-- This is a test script for tshark. -- This script runs inside tshark. -- FIRST run tshark with the "dns_dissector.lua" plugin, with the dns_port.pcap file, -- and with full tree output (-V switch). Pipe that to a file named testin.txt. -- This verify script then reads in that testin.txt. The filename can be specified -- using the "verify_file" argument. -- -- tshark -r bogus.cap -X lua_script:/lua/verify_dns_dissector.lua local function testing(...) print("---- Testing "..tostring(...).." ----") end local lines = { { "MyDNS Protocol", "Transaction ID: 42", "Flags: 0x0100", "0... .... .... .... = Response: this is a query", "[Expert Info (Chat/Request): DNS query message]", "[DNS query message]", "[Severity level: Chat]", "[Group: Request]", ".000 0... .... .... = Opcode: 0", ".... ..0. .... .... = Truncated: False", ".... ...1 .... .... = Recursion desired: yes", ".... .... .0.. .... = World War Z - Reserved for future use: 0x0", ".... .... ...0 .... = Checking disabled: False", "Number of Questions: 1", "Number of Answer RRs: 0", "Number of Authority RRs: 0", "Number of Additional RRs: 0", "Queries", "us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1)", "Name: us.pool.ntp.org", "[Name Length: 17]", "[Label Count: 4]", "Type: A (IPv4 host address) (1)", "Class: IN (Internet) (1)", }, { "MyDNS Protocol", "Transaction ID: 42", "Flags: 0x8180", "1... .... .... .... = Response: this is a response", "[Expert Info (Chat/Response): It's a response!]", "[It's a response!]", "[Severity level: Chat]", "[Group: Response]", ".000 0... .... .... = Opcode: 0", ".... .0.. .... .... = Authoritative: False", ".... ..0. .... .... = Truncated: False", ".... .... 1... .... = Recursion available: True", ".... .... .0.. .... = World War Z - Reserved for future use: 0x0", ".... .... ..0. .... = Authenticated: no", ".... .... .... 0000 = Response code: No Error (0)", ".... .... ...0 .... = Checking disabled: False", "DNS answer to life, the universe, and everything", "[Expert Info (Note/Comment): DNS answer to life, the universe, and everything]", "[DNS answer to life, the universe, and everything]", "[Severity level: Note]", "[Group: Comment]", "Number of Questions: 1", "Number of Answer RRs: 15", "Number of Authority RRs: 6", "Number of Additional RRs: 2", "Queries", "us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1)", "Name: us.pool.ntp.org", "[Name Length: 17]", "[Label Count: 4]", "Type: A (IPv4 host address) (1)", "Class: IN (Internet) (1)", }, { "MyDNS Protocol", "Transaction ID: 43", "Flags: 0x0100", "0... .... .... .... = Response: this is a query", "[Expert Info (Chat/Request): DNS query message]", "[DNS query message]", "[Severity level: Chat]", "[Group: Request]", ".000 0... .... .... = Opcode: 0", ".... ..0. .... .... = Truncated: False", ".... ...1 .... .... = Recursion desired: yes", ".... .... .0.. .... = World War Z - Reserved for future use: 0x0", ".... .... ...0 .... = Checking disabled: False", "Number of Questions: 1", "Number of Answer RRs: 0", "Number of Authority RRs: 0", "Number of Additional RRs: 0", "Queries", "us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1)", "Name: us.pool.ntp.org", "[Name Length: 17]", "[Label Count: 4]", "Type: A (IPv4 host address) (1)", "Class: IN (Internet) (1)", }, { "MyDNS Protocol", "Transaction ID: 43", "Flags: 0x8180", "1... .... .... .... = Response: this is a response", "[Expert Info (Chat/Response): It's a response!]", "[It's a response!]", "[Severity level: Chat]", "[Group: Response]", ".000 0... .... .... = Opcode: 0", ".... .0.. .... .... = Authoritative: False", ".... ..0. .... .... = Truncated: False", ".... .... 1... .... = Recursion available: True", ".... .... .0.. .... = World War Z - Reserved for future use: 0x0", ".... .... ..0. .... = Authenticated: no", ".... .... .... 0000 = Response code: No Error (0)", ".... .... ...0 .... = Checking disabled: False", "Number of Questions: 1", "Number of Answer RRs: 15", "Number of Authority RRs: 6", "Number of Additional RRs: 2", "Queries", "us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1)", "Name: us.pool.ntp.org", "[Name Length: 17]", "[Label Count: 4]", "Type: A (IPv4 host address) (1)", "Class: IN (Internet) (1)", }, } -- we're going to see those two sets of output twice: both by the normal -- dissector, then the first one by the heuristic, then the second one by -- a conversation match local numtests = 1 + #lines[1] + #lines[2] + #lines[3] + #lines[4] local hasHeuristic = true local verify_file = "testin.txt" -- grab passed-in arguments local args = { ... } if #args > 0 then for _, arg in ipairs(args) do local name, value = arg:match("(.+)=(.+)") if arg == "no_heur" then numtests = numtests - 1 elseif name == "verify_file" and value then verify_file = value end end end print("going to run "..numtests.." tests") -- for an example of what we're reading through to verify, look at end of this file print("opening file "..verify_file) local file = io.open(verify_file, "r") local line = file:read() local pktidx = 1 local total = 0 local found = false while line do -- eat beginning whitespace line = line:gsub("^%s+","",1) if line:find("^Frame %d+:") then pktidx = line:match("^Frame (%d+):") testing("Frame "..pktidx) pktidx = tonumber(pktidx) if pktidx > 4 then pktidx = pktidx - 4 end line = file:read() elseif line:find("%[Heuristic dissector used%]") then -- start again, because it now repeats -- but we should not see this [Heuristic dissector used] line again -- or it's an error in setting the conversation if found then error("Heuristic dissector ran twice - conversation setting not working?") return end found = true total = total + 1 line = file:read() elseif line == lines[pktidx][1] then -- we've matched the first line of our section -- now verify the rest is sequential for i, v in ipairs(lines[pktidx]) do io.stdout:write("testing Frame "..pktidx..", line "..i.."...") if not line then -- ended too soon io.stdout:write("failed!\n") error("Ran out of file lines!") return end -- eat beginning whitespace line = line:gsub("^%s+","",1) if line ~= v then io.stdout:write("failed!\n") print("Got this:'"..line.."', expected this:'"..v.."'") error("mismatched lines!") return end io.stdout:write("passed\n") total = total + 1 line = file:read() end else line = file:read() end end print(total.." of "..numtests.." tests run and passed") if total ~= numtests then error("Did not find all our lines to test!") return end print("\n-----------------------------\n") -- must print out the following for success (the test shell sciprt looks for this) print("All tests passed!\n\n") ---------------------------------------------------------- -- We should see something like this: --[[ Frame 1: 75 bytes on wire (600 bits), 75 bytes captured (600 bits) Encapsulation type: Ethernet (1) Arrival Time: Sep 26, 2004 23:18:04.938672000 EDT [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1096255084.938672000 seconds [Time delta from previous captured frame: 0.000000000 seconds] [Time delta from previous displayed frame: 0.000000000 seconds] [Time since reference or first frame: 0.000000000 seconds] Frame Number: 1 Frame Length: 75 bytes (600 bits) Capture Length: 75 bytes (600 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ethertype:ip:udp:mydns] Ethernet II, Src: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e), Dst: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53) Destination: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53) Address: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e) Address: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IP (0x0800) Internet Protocol Version 4, Src: 192.168.50.50 (192.168.50.50), Dst: 192.168.0.1 (192.168.0.1) Version: 4 Header Length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport)) 0000 00.. = Differentiated Services Codepoint: Default (0x00) .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00) Total Length: 61 Identification: 0x0a41 (2625) Flags: 0x00 0... .... = Reserved bit: Not set .0.. .... = Don't fragment: Not set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 128 Protocol: UDP (17) Header checksum: 0x7ceb [correct] [Good: True] [Bad: False] Source: 192.168.50.50 (192.168.50.50) Destination: 192.168.0.1 (192.168.0.1) User Datagram Protocol, Src Port: 65282 (65282), Dst Port: 65333 (65333) Source Port: 65282 (65282) Destination Port: 65333 (65333) Length: 41 Checksum: 0x07a9 [validation disabled] [Good Checksum: False] [Bad Checksum: False] [Stream index: 0] MyDNS Protocol Transaction ID: 43 Flags: 0x0100 0... .... .... .... = Response: this is a query .000 0... .... .... = Opcode: 0 .... ..0. .... .... = Truncated: False .... ...1 .... .... = Recursion desired: yes .... .... .0.. .... = World War Z - Reserved for future use: 0x0 .... .... ...0 .... = Checking disabled: False Number of Questions: 1 Number of Answer RRs: 0 Number of Authority RRs: 0 Number of Additional RRs: 0 Queries us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1) Name: us.pool.ntp.org [Name Length: 17] [Label Count: 4] Type: A (IPv4 host address) (1) Class: IN (Internet) (1) Frame 2: 540 bytes on wire (4320 bits), 540 bytes captured (4320 bits) Encapsulation type: Ethernet (1) Arrival Time: Sep 26, 2004 23:18:04.945618000 EDT [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1096255084.945618000 seconds [Time delta from previous captured frame: 0.006946000 seconds] [Time delta from previous displayed frame: 0.006946000 seconds] [Time since reference or first frame: 0.006946000 seconds] Frame Number: 2 Frame Length: 540 bytes (4320 bits) Capture Length: 540 bytes (4320 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ethertype:ip:udp:mydns] Ethernet II, Src: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53), Dst: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e) Destination: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e) Address: AmbitMic_6c:40:4e (00:d0:59:6c:40:4e) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53) Address: Cisco-Li_82:b2:53 (00:0c:41:82:b2:53) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IP (0x0800) Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.50.50 (192.168.50.50) Version: 4 Header Length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport)) 0000 00.. = Differentiated Services Codepoint: Default (0x00) .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00) Total Length: 526 Identification: 0x2153 (8531) Flags: 0x00 0... .... = Reserved bit: Not set .0.. .... = Don't fragment: Not set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 63 Protocol: UDP (17) Header checksum: 0xa508 [correct] [Good: True] [Bad: False] Source: 192.168.0.1 (192.168.0.1) Destination: 192.168.50.50 (192.168.50.50) User Datagram Protocol, Src Port: 65333 (65333), Dst Port: 65282 (65282) Source Port: 65333 (65333) Destination Port: 65282 (65282) Length: 506 Checksum: 0xf9d5 [validation disabled] [Good Checksum: False] [Bad Checksum: False] [Stream index: 0] MyDNS Protocol Transaction ID: 43 Flags: 0x8180 1... .... .... .... = Response: this is a response .000 0... .... .... = Opcode: 0 .... .0.. .... .... = Authoritative: False .... ..0. .... .... = Truncated: False .... .... 1... .... = Recursion available: True .... .... .0.. .... = World War Z - Reserved for future use: 0x0 .... .... ..0. .... = Authenticated: no .... .... .... 0000 = Response code: No Error (0) .... .... ...0 .... = Checking disabled: False Number of Questions: 1 Number of Answer RRs: 15 Number of Authority RRs: 6 Number of Additional RRs: 2 Queries us.pool.ntp.org: type A (IPv4 host address) (1), class IN (Internet) (1) Name: us.pool.ntp.org [Name Length: 17] [Label Count: 4] Type: A (IPv4 host address) (1) Class: IN (Internet) (1) ]]