... | @@ -4,7 +4,7 @@ |
... | @@ -4,7 +4,7 @@ |
|
|
|
|
|
## A dissector tutorial script
|
|
## A dissector tutorial script
|
|
|
|
|
|
Download this [dissector.lua](uploads/\__moin_import_\_/attachments/Lua/Examples/dissector.lua) file for an example Lua script for a protocol dissector. The script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
Download this [dissector.lua](uploads/__moin_import__/attachments/Lua/Examples/dissector.lua) file for an example Lua script for a protocol dissector. The script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
|
|
|
|
The purpose of this script is two-fold:
|
|
The purpose of this script is two-fold:
|
|
|
|
|
... | @@ -15,17 +15,17 @@ If you wonder why some functions are called some way, or differently than previo |
... | @@ -15,17 +15,17 @@ If you wonder why some functions are called some way, or differently than previo |
|
|
|
|
|
This script creates an elementary dissector for DNS. It's neither comprehensive nor error-free with regards to the DNS protocol. That's OK. The goal isn't to fully dissect DNS properly - Wireshark already has a good DNS dissector built-in. We don't need another one. We also have other example Lua scripts, but the nice thing about this one is getting capture files to run it against is trivial.
|
|
This script creates an elementary dissector for DNS. It's neither comprehensive nor error-free with regards to the DNS protocol. That's OK. The goal isn't to fully dissect DNS properly - Wireshark already has a good DNS dissector built-in. We don't need another one. We also have other example Lua scripts, but the nice thing about this one is getting capture files to run it against is trivial.
|
|
|
|
|
|
**How to use this script:** Once the script is loaded, it creates a new protocol named "MyDNS" (or "MYDNS" in some places). If you have a capture file with DNS packets in it, simply select one in the Packet List pane, right-click on it, and select "Decode As ...", and then in the dialog box that shows up scroll down the list of protocols to one called "MYDNS", select that and click the "ok" or "apply" button. Voila\`, you're now decoding DNS packets using the simplistic dissector in this script. Another way is to download the [dns_port.pcap](uploads/\__moin_import_\_/attachments/SampleCaptures/dns_port.pcap "dns_port.pcap") capture file made for this script, and open that - since the DNS packets in it use UDP port 65333 (instead of the default 53), and since the MyDNS protocol in this script has been set to automatically decode UDP port 65333, it will automagically do it without doing "Decode As ...".
|
|
**How to use this script:** Once the script is loaded, it creates a new protocol named "MyDNS" (or "MYDNS" in some places). If you have a capture file with DNS packets in it, simply select one in the Packet List pane, right-click on it, and select "Decode As ...", and then in the dialog box that shows up scroll down the list of protocols to one called "MYDNS", select that and click the "ok" or "apply" button. Voila\`, you're now decoding DNS packets using the simplistic dissector in this script. Another way is to download the [dns_port.pcap](uploads/__moin_import__/attachments/SampleCaptures/dns_port.pcap "dns_port.pcap") capture file made for this script, and open that - since the DNS packets in it use UDP port 65333 (instead of the default 53), and since the MyDNS protocol in this script has been set to automatically decode UDP port 65333, it will automagically do it without doing "Decode As ...".
|
|
|
|
|
|
## A dissector tutorial with TCP-reassembly
|
|
## A dissector tutorial with TCP-reassembly
|
|
|
|
|
|
Download this [fpm.lua](uploads/\__moin_import_\_/attachments/Lua/Examples/fpm.lua) file for an example Lua script for a TCP-based protocol dissector. The script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
Download this [fpm.lua](uploads/__moin_import__/attachments/Lua/Examples/fpm.lua) file for an example Lua script for a TCP-based protocol dissector. The script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
|
|
|
|
**How to use this script:** Once the script is loaded, it creates a new protocol named "FPM". To see it in action, download the [segmented_fpm.pcap](uploads/\__moin_import_\_/attachments/SampleCaptures/segmented_fpm.pcap "segmented_fpm.pcap") capture file made for this script, and open that.
|
|
**How to use this script:** Once the script is loaded, it creates a new protocol named "FPM". To see it in action, download the [segmented_fpm.pcap](uploads/__moin_import__/attachments/SampleCaptures/segmented_fpm.pcap "segmented_fpm.pcap") capture file made for this script, and open that.
|
|
|
|
|
|
## A custom file reader & writer tutorial script
|
|
## A custom file reader & writer tutorial script
|
|
|
|
|
|
Download this [pcap_file.lua](uploads/\__moin_import_\_/attachments/Lua/Examples/pcap_file.lua) file for an example Lua script for a custom file format reader and writer.
|
|
Download this [pcap_file.lua](uploads/__moin_import__/attachments/Lua/Examples/pcap_file.lua) file for an example Lua script for a custom file format reader and writer.
|
|
|
|
|
|
Like the dissector tutorial script above, this script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
Like the dissector tutorial script above, this script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
|
|
|
... | @@ -43,7 +43,7 @@ The last method is the one recommended for this file reader, so that you don't i |
... | @@ -43,7 +43,7 @@ The last method is the one recommended for this file reader, so that you don't i |
|
|
|
|
|
## A pcap FileShark script
|
|
## A pcap FileShark script
|
|
|
|
|
|
Download both this [fileshark_pcap.lua](uploads/\__moin_import_\_/attachments/Lua/Examples/fileshark_pcap.lua) file and this [linktype.lua](uploads/\__moin_import_\_/attachments/Lua/Examples/linktype.lua) file for an example Lua script for a pcap-format [FileShark](/FileShark) script. What does that mean? It means it reads a pcap file and displays the contents of the file _format_ itself, showing the file header, record headers, etc., and their fields. To do this it creates a "pcapfile" protocol dissector, with associated protocol fields of what pcap file formats have. This implements both a Lua-based dissector and custom file format reader.
|
|
Download both this [fileshark_pcap.lua](uploads/__moin_import__/attachments/Lua/Examples/fileshark_pcap.lua) file and this [linktype.lua](uploads/__moin_import__/attachments/Lua/Examples/linktype.lua) file for an example Lua script for a pcap-format [FileShark](/FileShark) script. What does that mean? It means it reads a pcap file and displays the contents of the file _format_ itself, showing the file header, record headers, etc., and their fields. To do this it creates a "pcapfile" protocol dissector, with associated protocol fields of what pcap file formats have. This implements both a Lua-based dissector and custom file format reader.
|
|
|
|
|
|
Like the tutorial scripts above, this script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
Like the tutorial scripts above, this script is too long to embed in this page, and it's much better to view it in a text editor that supports Lua syntax highlighting, because there are a lot of comments in the script explaining things.
|
|
|
|
|
... | @@ -101,29 +101,29 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -101,29 +101,29 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
4 -- this will print out an error if the directory already exists, but that's fine
|
|
4 -- this will print out an error if the directory already exists, but that's fine
|
|
5 os.execute("mkdir " .. dirname)
|
|
5 os.execute("mkdir " .. dirname)
|
|
6 end
|
|
6 end
|
|
7
|
|
7
|
|
8 local dir = "by_ip"
|
|
8 local dir = "by_ip"
|
|
9 createDir(dir)
|
|
9 createDir(dir)
|
|
10
|
|
10
|
|
11 -- create a table to hold the dumper objects/file handles
|
|
11 -- create a table to hold the dumper objects/file handles
|
|
12 local dumpers = {}
|
|
12 local dumpers = {}
|
|
13
|
|
13
|
|
14 -- create a listener tap. By default it creates one for "frame", but we're tapping IP layer.
|
|
14 -- create a listener tap. By default it creates one for "frame", but we're tapping IP layer.
|
|
15 -- Valid values can be any protocol with tapping support, but to get something useful in the
|
|
15 -- Valid values can be any protocol with tapping support, but to get something useful in the
|
|
16 -- "extractor" argument of the tap's 'packet' function callback (the third argument passed by
|
|
16 -- "extractor" argument of the tap's 'packet' function callback (the third argument passed by
|
|
17 -- wireshark into it), it has to be one of the following currently:
|
|
17 -- wireshark into it), it has to be one of the following currently:
|
|
18 -- "actrace", "ansi_a", "ansi_map", "bacapp", "eth", "h225", "http", "ip", "ldap",
|
|
18 -- "actrace", "ansi_a", "ansi_map", "bacapp", "eth", "h225", "http", "ip", "ldap",
|
|
19 -- "smb", "smb2", "tcp", "udp", "wlan", and "frame"
|
|
19 -- "smb", "smb2", "tcp", "udp", "wlan", and "frame"
|
|
20 local tap = Listener.new("ip")
|
|
20 local tap = Listener.new("ip")
|
|
21
|
|
21
|
|
22
|
|
22
|
|
23 -- we will be called once for every IP Header.
|
|
23 -- we will be called once for every IP Header.
|
|
24 -- If there's more than one IP header in a given packet we'll dump the packet once per every header
|
|
24 -- If there's more than one IP header in a given packet we'll dump the packet once per every header
|
|
25 function tap.packet(pinfo,tvb,ip)
|
|
25 function tap.packet(pinfo,tvb,ip)
|
|
26 --print("packet called")
|
|
26 --print("packet called")
|
|
27 local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst)
|
|
27 local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst)
|
|
28 local src_dmp, dst_dmp
|
|
28 local src_dmp, dst_dmp
|
|
29
|
|
29
|
|
30 -- get the dumper file handle for this ip addr
|
|
30 -- get the dumper file handle for this ip addr
|
|
31 src_dmp = dumpers[ip_src]
|
|
31 src_dmp = dumpers[ip_src]
|
|
32 if not src_dmp then
|
|
32 if not src_dmp then
|
... | @@ -131,23 +131,23 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -131,23 +131,23 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
34 src_dmp = Dumper.new_for_current( dir .. "/" .. ip_src .. ".pcap" )
|
|
34 src_dmp = Dumper.new_for_current( dir .. "/" .. ip_src .. ".pcap" )
|
|
35 dumpers[ip_src] = src_dmp
|
|
35 dumpers[ip_src] = src_dmp
|
|
36 end
|
|
36 end
|
|
37
|
|
37
|
|
38 -- dump the current packet as it is (same encap format and content)
|
|
38 -- dump the current packet as it is (same encap format and content)
|
|
39 src_dmp:dump_current()
|
|
39 src_dmp:dump_current()
|
|
40 src_dmp:flush()
|
|
40 src_dmp:flush()
|
|
41
|
|
41
|
|
42 -- now do the same for dest addr
|
|
42 -- now do the same for dest addr
|
|
43 dst_dmp = dumpers[ip_dst]
|
|
43 dst_dmp = dumpers[ip_dst]
|
|
44 if not dst_dmp then
|
|
44 if not dst_dmp then
|
|
45 dst_dmp = Dumper.new_for_current( dir .. "/" .. ip_dst .. ".pcap" )
|
|
45 dst_dmp = Dumper.new_for_current( dir .. "/" .. ip_dst .. ".pcap" )
|
|
46 dumpers[ip_dst] = dst_dmp
|
|
46 dumpers[ip_dst] = dst_dmp
|
|
47 end
|
|
47 end
|
|
48
|
|
48
|
|
49 dst_dmp:dump_current()
|
|
49 dst_dmp:dump_current()
|
|
50 dst_dmp:flush()
|
|
50 dst_dmp:flush()
|
|
51
|
|
51
|
|
52 end
|
|
52 end
|
|
53
|
|
53
|
|
54 -- a listener tap's draw function is called every few seconds in the GUI
|
|
54 -- a listener tap's draw function is called every few seconds in the GUI
|
|
55 -- and at end of file (once) in tshark
|
|
55 -- and at end of file (once) in tshark
|
|
56 function tap.draw()
|
|
56 function tap.draw()
|
... | @@ -156,7 +156,7 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -156,7 +156,7 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
59 dumper:flush()
|
|
59 dumper:flush()
|
|
60 end
|
|
60 end
|
|
61 end
|
|
61 end
|
|
62
|
|
62
|
|
63 -- a listener tap's reset function is called at the end of a live capture run,
|
|
63 -- a listener tap's reset function is called at the end of a live capture run,
|
|
64 -- when a file is opened, or closed. Tshark never appears to call it.
|
|
64 -- when a file is opened, or closed. Tshark never appears to call it.
|
|
65 function tap.reset()
|
|
65 function tap.reset()
|
... | @@ -181,10 +181,10 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -181,10 +181,10 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
1 -- Append "<dst> -> <src>" to the Info column with a post-dissector.
|
|
1 -- Append "<dst> -> <src>" to the Info column with a post-dissector.
|
|
2 -- (Taps are not guaranteed to be run at a point when they can set the
|
|
2 -- (Taps are not guaranteed to be run at a point when they can set the
|
|
3 -- column text, so they can't be used for this.)
|
|
3 -- column text, so they can't be used for this.)
|
|
4
|
|
4
|
|
5 -- create a new protocol so we can register a post-dissector
|
|
5 -- create a new protocol so we can register a post-dissector
|
|
6 local myproto = Proto("swapper","Dummy proto to edit info column")
|
|
6 local myproto = Proto("swapper","Dummy proto to edit info column")
|
|
7
|
|
7
|
|
8 -- the dissector function callback
|
|
8 -- the dissector function callback
|
|
9 function myproto.dissector(tvb,pinfo,tree)
|
|
9 function myproto.dissector(tvb,pinfo,tree)
|
|
10 pinfo.cols.info:append(" " .. tostring(pinfo.dst).." -> "..tostring(pinfo.src))
|
|
10 pinfo.cols.info:append(" " .. tostring(pinfo.dst).." -> "..tostring(pinfo.src))
|
... | @@ -203,10 +203,10 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -203,10 +203,10 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
<div>
|
|
<div>
|
|
|
|
|
|
```
|
|
```
|
|
1 -- This Example will add a menu "Lua Dialog Test" under the Tools menu,
|
|
1 -- This Example will add a menu "Lua Dialog Test" under the Tools menu,
|
|
2 -- which when selected will pop a dialog prompting the user for input
|
|
2 -- which when selected will pop a dialog prompting the user for input
|
|
3 -- that when accepted will pop a window with a result.
|
|
3 -- that when accepted will pop a window with a result.
|
|
4
|
|
4
|
|
5 if gui_enabled() then
|
|
5 if gui_enabled() then
|
|
6 local splash = TextWindow.new("Hello!");
|
|
6 local splash = TextWindow.new("Hello!");
|
|
7 splash:set("This time wireshark has been enhanced with a useless feature.\n")
|
|
7 splash:set("This time wireshark has been enhanced with a useless feature.\n")
|
... | @@ -219,23 +219,23 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -219,23 +219,23 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
14 win:append(" with " .. eyes .." eyes and")
|
|
14 win:append(" with " .. eyes .." eyes and")
|
|
15 win:append(" " .. hair .. " hair.");
|
|
15 win:append(" " .. hair .. " hair.");
|
|
16 end
|
|
16 end
|
|
17
|
|
17
|
|
18 new_dialog("Dialog Test",dialog_func,"A Person","Eyes","Hair")
|
|
18 new_dialog("Dialog Test",dialog_func,"A Person","Eyes","Hair")
|
|
19 end
|
|
19 end
|
|
20
|
|
20
|
|
21 -- optional 3rd parameter to register_menu.
|
|
21 -- optional 3rd parameter to register_menu.
|
|
22 -- See http://www.wireshark.org/docs/wsug_html_chunked/wsluarm_modules.html
|
|
22 -- See http://www.wireshark.org/docs/wsug_html_chunked/wsluarm_modules.html
|
|
23 -- If omitted, defaults to MENU_STAT_GENERIC. Other options include:
|
|
23 -- If omitted, defaults to MENU_STAT_GENERIC. Other options include:
|
|
24 -- MENU_STAT_UNSORTED (Statistics),
|
|
24 -- MENU_STAT_UNSORTED (Statistics),
|
|
25 -- MENU_STAT_GENERIC (Statistics, first section),
|
|
25 -- MENU_STAT_GENERIC (Statistics, first section),
|
|
26 -- MENU_STAT_CONVERSATION (Statistics/Conversation List),
|
|
26 -- MENU_STAT_CONVERSATION (Statistics/Conversation List),
|
|
27 -- MENU_STAT_ENDPOINT (Statistics/Endpoint List),
|
|
27 -- MENU_STAT_ENDPOINT (Statistics/Endpoint List),
|
|
28 -- MENU_STAT_RESPONSE (Statistics/Service Response Time),
|
|
28 -- MENU_STAT_RESPONSE (Statistics/Service Response Time),
|
|
29 -- MENU_STAT_TELEPHONY (Telephony),
|
|
29 -- MENU_STAT_TELEPHONY (Telephony),
|
|
30 -- MENU_ANALYZE_UNSORTED (Analyze),
|
|
30 -- MENU_ANALYZE_UNSORTED (Analyze),
|
|
31 -- MENU_ANALYZE_CONVERSATION (Analyze/Conversation Filter),
|
|
31 -- MENU_ANALYZE_CONVERSATION (Analyze/Conversation Filter),
|
|
32 -- MENU_TOOLS_UNSORTED (Tools)
|
|
32 -- MENU_TOOLS_UNSORTED (Tools)
|
|
33
|
|
33
|
|
34 register_menu("Lua Dialog Test",dialog_menu,MENU_TOOLS_UNSORTED)
|
|
34 register_menu("Lua Dialog Test",dialog_menu,MENU_TOOLS_UNSORTED)
|
|
```
|
|
```
|
|
|
|
|
... | @@ -281,29 +281,29 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -281,29 +281,29 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
2 -- It shows the current tree for the selected packet, but this does not mean it always shows the full tree,
|
|
2 -- It shows the current tree for the selected packet, but this does not mean it always shows the full tree,
|
|
3 -- because wireshark performs multiple dissection passes of a packet, with the initial pass only being high-level and not
|
|
3 -- because wireshark performs multiple dissection passes of a packet, with the initial pass only being high-level and not
|
|
4 -- dissecting fully (for performance reasons). You can see this behavior better by changing line 30 of this example
|
|
4 -- dissecting fully (for performance reasons). You can see this behavior better by changing line 30 of this example
|
|
5 -- to this, so it concatenates output instead of clearing it every time:
|
|
5 -- to this, so it concatenates output instead of clearing it every time:
|
|
6 -- output = output .. "\nTree fields for packet #".. pinfo.number .. ":\n"
|
|
6 -- output = output .. "\nTree fields for packet #".. pinfo.number .. ":\n"
|
|
7
|
|
7
|
|
8 -- this only works in wireshark
|
|
8 -- this only works in wireshark
|
|
9 if not gui_enabled() then return end
|
|
9 if not gui_enabled() then return end
|
|
10
|
|
10
|
|
11 local output = "" -- for the output we'll show in the text window
|
|
11 local output = "" -- for the output we'll show in the text window
|
|
12 local tw = nil -- the text window
|
|
12 local tw = nil -- the text window
|
|
13 -- function to refresh the text window
|
|
13 -- function to refresh the text window
|
|
14 local function updateWindow()
|
|
14 local function updateWindow()
|
|
15 if tw then tw:set(output) end
|
|
15 if tw then tw:set(output) end
|
|
16 end
|
|
16 end
|
|
17
|
|
17
|
|
18 -- calling tostring() on random FieldInfo's can cause an error, so this func handles it
|
|
18 -- calling tostring() on random FieldInfo's can cause an error, so this func handles it
|
|
19 local function getstring(finfo)
|
|
19 local function getstring(finfo)
|
|
20 local ok, val = pcall(tostring, finfo)
|
|
20 local ok, val = pcall(tostring, finfo)
|
|
21 if not ok then val = "(unknown)" end
|
|
21 if not ok then val = "(unknown)" end
|
|
22 return val
|
|
22 return val
|
|
23 end
|
|
23 end
|
|
24
|
|
24
|
|
25 -- create a new protocol so we can register a post-dissector
|
|
25 -- create a new protocol so we can register a post-dissector
|
|
26 local myproto = Proto("tree_view","Dummy proto to view tree")
|
|
26 local myproto = Proto("tree_view","Dummy proto to view tree")
|
|
27
|
|
27
|
|
28 -- the dissector function callback
|
|
28 -- the dissector function callback
|
|
29 function myproto.dissector(tvb,pinfo,tree)
|
|
29 function myproto.dissector(tvb,pinfo,tree)
|
|
30 output = output.. "\nTree fields for packet #".. pinfo.number .. ":\n"
|
|
30 output = output.. "\nTree fields for packet #".. pinfo.number .. ":\n"
|
... | @@ -316,15 +316,15 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -316,15 +316,15 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
37 end
|
|
37 end
|
|
38 -- register our new dummy protocol for post-dissection
|
|
38 -- register our new dummy protocol for post-dissection
|
|
39 register_postdissector(myproto)
|
|
39 register_postdissector(myproto)
|
|
40
|
|
40
|
|
41
|
|
41
|
|
42 -- now we create the menu function for this, which creates a text window to display this stuff
|
|
42 -- now we create the menu function for this, which creates a text window to display this stuff
|
|
43 local function menu_view_tree()
|
|
43 local function menu_view_tree()
|
|
44 tw = TextWindow.new("Tree View")
|
|
44 tw = TextWindow.new("Tree View")
|
|
45 tw:set_atclose(function() tw = nil end)
|
|
45 tw:set_atclose(function() tw = nil end)
|
|
46 updateWindow()
|
|
46 updateWindow()
|
|
47 end
|
|
47 end
|
|
48
|
|
48
|
|
49 -- add this to the Tools->Lua submenu
|
|
49 -- add this to the Tools->Lua submenu
|
|
50 register_menu("Lua/Tree View", menu_view_tree, MENU_TOOLS_UNSORTED)
|
|
50 register_menu("Lua/Tree View", menu_view_tree, MENU_TOOLS_UNSORTED)
|
|
```
|
|
```
|
... | @@ -352,14 +352,14 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -352,14 +352,14 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
11 -- The following:
|
|
11 -- The following:
|
|
12 -- wireshark -r myfile -X lua_script:extract.lua -X lua_script1:data-text-lines
|
|
12 -- wireshark -r myfile -X lua_script:extract.lua -X lua_script1:data-text-lines
|
|
13 -- will do something similar in the GUI, showing the extracted values in the tree.
|
|
13 -- will do something similar in the GUI, showing the extracted values in the tree.
|
|
14
|
|
14
|
|
15 local args = { ... }
|
|
15 local args = { ... }
|
|
16
|
|
16
|
|
17 -- exit if no arguments were passed in
|
|
17 -- exit if no arguments were passed in
|
|
18 if #args == 0 then
|
|
18 if #args == 0 then
|
|
19 return
|
|
19 return
|
|
20 end
|
|
20 end
|
|
21
|
|
21
|
|
22 -- verify tshark/wireshark version is new enough - needs to be 1.12+
|
|
22 -- verify tshark/wireshark version is new enough - needs to be 1.12+
|
|
23 local major, minor, micro = 0, 0, 0
|
|
23 local major, minor, micro = 0, 0, 0
|
|
24 if get_version then
|
|
24 if get_version then
|
... | @@ -372,38 +372,38 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -372,38 +372,38 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
31 error("Sorry, but your Wireshark/Tshark version is too old for this script!\n"..
|
|
31 error("Sorry, but your Wireshark/Tshark version is too old for this script!\n"..
|
|
32 "This script needs Wireshark/Tshark version 1.12 or higher.\n" )
|
|
32 "This script needs Wireshark/Tshark version 1.12 or higher.\n" )
|
|
33 end
|
|
33 end
|
|
34
|
|
34
|
|
35 -- a table to hold field extractors
|
|
35 -- a table to hold field extractors
|
|
36 local fields = {}
|
|
36 local fields = {}
|
|
37
|
|
37
|
|
38 -- create field extractor(s) for the passed-in argument(s)
|
|
38 -- create field extractor(s) for the passed-in argument(s)
|
|
39 for i, arg in ipairs(args) do
|
|
39 for i, arg in ipairs(args) do
|
|
40 fields[i] = Field.new(arg)
|
|
40 fields[i] = Field.new(arg)
|
|
41 end
|
|
41 end
|
|
42
|
|
42
|
|
43 -- our fake protocol
|
|
43 -- our fake protocol
|
|
44 local exproto = Proto.new("extract", "Data Extractor")
|
|
44 local exproto = Proto.new("extract", "Data Extractor")
|
|
45
|
|
45
|
|
46 -- the new fields that contain the extracted data (one in string form, one in hex)
|
|
46 -- the new fields that contain the extracted data (one in string form, one in hex)
|
|
47 local exfield_string = ProtoField.new("Extracted String Value", "extract.string", ftypes.STRING)
|
|
47 local exfield_string = ProtoField.new("Extracted String Value", "extract.string", ftypes.STRING)
|
|
48 local exfield_hex = ProtoField.new("Extracted Hex Value", "extract.hex", ftypes.STRING)
|
|
48 local exfield_hex = ProtoField.new("Extracted Hex Value", "extract.hex", ftypes.STRING)
|
|
49
|
|
49
|
|
50 -- register the new fields into our fake protocol
|
|
50 -- register the new fields into our fake protocol
|
|
51 exproto.fields = { exfield_string, exfield_hex }
|
|
51 exproto.fields = { exfield_string, exfield_hex }
|
|
52
|
|
52
|
|
53 function exproto.dissector(tvbuf,pktinfo,root)
|
|
53 function exproto.dissector(tvbuf,pktinfo,root)
|
|
54 local tree = nil
|
|
54 local tree = nil
|
|
55
|
|
55
|
|
56 for i, field in ipairs(fields) do
|
|
56 for i, field in ipairs(fields) do
|
|
57 -- extract the field into a table of FieldInfos
|
|
57 -- extract the field into a table of FieldInfos
|
|
58 finfos = { field() }
|
|
58 finfos = { field() }
|
|
59
|
|
59
|
|
60 if #finfos > 0 then
|
|
60 if #finfos > 0 then
|
|
61 -- add our proto if we haven't already
|
|
61 -- add our proto if we haven't already
|
|
62 if not tree then
|
|
62 if not tree then
|
|
63 tree = root:add(exproto)
|
|
63 tree = root:add(exproto)
|
|
64 end
|
|
64 end
|
|
65
|
|
65
|
|
66 for _, finfo in ipairs(finfos) do
|
|
66 for _, finfo in ipairs(finfos) do
|
|
67 -- get a TvbRange of the FieldInfo (fieldinfo.range in WSDG)
|
|
67 -- get a TvbRange of the FieldInfo (fieldinfo.range in WSDG)
|
|
68 local ftvbr = finfo.tvb
|
|
68 local ftvbr = finfo.tvb
|
... | @@ -412,9 +412,9 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -412,9 +412,9 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
71 end
|
|
71 end
|
|
72 end
|
|
72 end
|
|
73 end
|
|
73 end
|
|
74
|
|
74
|
|
75 end
|
|
75 end
|
|
76
|
|
76
|
|
77 -- register it as a postdissector, and force all fields to be generated
|
|
77 -- register it as a postdissector, and force all fields to be generated
|
|
78 register_postdissector(exproto, true)
|
|
78 register_postdissector(exproto, true)
|
|
```
|
|
```
|
... | @@ -431,18 +431,18 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -431,18 +431,18 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
```
|
|
```
|
|
1 -- voip.lua
|
|
1 -- voip.lua
|
|
2 -- Written by: Jason Garland <jgarland@jasongarland.com>
|
|
2 -- Written by: Jason Garland <jgarland@jasongarland.com>
|
|
3
|
|
3
|
|
4 print("Starting voip.lua script.")
|
|
4 print("Starting voip.lua script.")
|
|
5
|
|
5
|
|
6
|
|
6
|
|
7 rex = require "rex_pcre"
|
|
7 rex = require "rex_pcre"
|
|
8
|
|
8
|
|
9 --MySQL database connection
|
|
9 --MySQL database connection
|
|
10 require "luasql.mysql"
|
|
10 require "luasql.mysql"
|
|
11 env = assert (luasql.mysql())
|
|
11 env = assert (luasql.mysql())
|
|
12 con = assert (env:connect("voiper","voiper","password"))
|
|
12 con = assert (env:connect("voiper","voiper","password"))
|
|
13
|
|
13
|
|
14
|
|
14
|
|
15 do
|
|
15 do
|
|
16 local voiperdir = os.getenv("voiperdir")
|
|
16 local voiperdir = os.getenv("voiperdir")
|
|
17 local capturesdir = os.getenv("voiperdir") .. "/captures"
|
|
17 local capturesdir = os.getenv("voiperdir") .. "/captures"
|
... | @@ -469,11 +469,11 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -469,11 +469,11 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
38 local sip_callid_f = Field.new("sip.Call-ID")
|
|
38 local sip_callid_f = Field.new("sip.Call-ID")
|
|
39 local sip_cseq_method_f = Field.new("sip.CSeq.method")
|
|
39 local sip_cseq_method_f = Field.new("sip.CSeq.method")
|
|
40 local sip_status_code_f = Field.new("sip.Status-Code")
|
|
40 local sip_status_code_f = Field.new("sip.Status-Code")
|
|
41
|
|
41
|
|
42 local sip_contact_addr_f = Field.new("sip.contact.addr")
|
|
42 local sip_contact_addr_f = Field.new("sip.contact.addr")
|
|
43 local sip_request_line_f = Field.new("sip.Request-Line")
|
|
43 local sip_request_line_f = Field.new("sip.Request-Line")
|
|
44 local sip_from_addr_f = Field.new("sip.from.addr")
|
|
44 local sip_from_addr_f = Field.new("sip.from.addr")
|
|
45
|
|
45
|
|
46 local sdp_connection_info_address_f = Field.new("sdp.connection_info.address")
|
|
46 local sdp_connection_info_address_f = Field.new("sdp.connection_info.address")
|
|
47 local raw_sip_line_f = Field.new("raw_sip.line")
|
|
47 local raw_sip_line_f = Field.new("raw_sip.line")
|
|
48 local function init_listener()
|
|
48 local function init_listener()
|
... | @@ -486,28 +486,28 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -486,28 +486,28 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
55 local rtp_setup_frame,rtp_ssrc = rtp_setup_frame_f(), rtp_ssrc_f()
|
|
55 local rtp_setup_frame,rtp_ssrc = rtp_setup_frame_f(), rtp_ssrc_f()
|
|
56 local t38_setup_frame = t38_setup_frame_f()
|
|
56 local t38_setup_frame = t38_setup_frame_f()
|
|
57 local sip_cseq_method, sip_status_code, sip_callid, sdp_connection_info_address, raw_sip_line = sip_cseq_method_f(), sip_status_code_f(), sip_callid_f(), sdp_connection_info_address_f(), raw_sip_line_f()
|
|
57 local sip_cseq_method, sip_status_code, sip_callid, sdp_connection_info_address, raw_sip_line = sip_cseq_method_f(), sip_status_code_f(), sip_callid_f(), sdp_connection_info_address_f(), raw_sip_line_f()
|
|
58 local sip_contact_addr, sip_request_line, sip_from_addr = sip_contact_addr_f(), sip_request_line_f(), sip_from_addr_f()
|
|
58 local sip_contact_addr, sip_request_line, sip_from_addr = sip_contact_addr_f(), sip_request_line_f(), sip_from_addr_f()
|
|
59 local rtcp_setup_frame, rtcp_ssrc_jitter, rtcp_ssrc_fraction, rtcp_ssrc_identifier = rtcp_setup_frame_f(), rtcp_ssrc_jitter_f(), rtcp_ssrc_fraction_f(), rtcp_ssrc_identifier_f()
|
|
59 local rtcp_setup_frame, rtcp_ssrc_jitter, rtcp_ssrc_fraction, rtcp_ssrc_identifier = rtcp_setup_frame_f(), rtcp_ssrc_jitter_f(), rtcp_ssrc_fraction_f(), rtcp_ssrc_identifier_f()
|
|
60 local frame = tostring(pinfo.number)
|
|
60 local frame = tostring(pinfo.number)
|
|
61 local src_dmp, dst_dmp, rtp_dmp, sip_dmp
|
|
61 local src_dmp, dst_dmp, rtp_dmp, sip_dmp
|
|
62
|
|
62
|
|
63 if sdp_connection_info_address then
|
|
63 if sdp_connection_info_address then
|
|
64 --print("Frame: " .. frame .. " = " .. tostring(sip_callid))
|
|
64 --print("Frame: " .. frame .. " = " .. tostring(sip_callid))
|
|
65 frames[frame] = tostring(sip_callid)
|
|
65 frames[frame] = tostring(sip_callid)
|
|
66 end
|
|
66 end
|
|
67
|
|
67
|
|
68 if rtcp_setup_frame then
|
|
68 if rtcp_setup_frame then
|
|
69 if not (frames[tostring(rtcp_setup_frame)] == nil) then
|
|
69 if not (frames[tostring(rtcp_setup_frame)] == nil) then
|
|
70 sip_callid = frames[tostring(rtcp_setup_frame)]
|
|
70 sip_callid = frames[tostring(rtcp_setup_frame)]
|
|
71 end
|
|
71 end
|
|
72 end
|
|
72 end
|
|
73
|
|
73
|
|
74 if t38_setup_frame then
|
|
74 if t38_setup_frame then
|
|
75 if not (frames[tostring(t38_setup_frame)] == nil) then
|
|
75 if not (frames[tostring(t38_setup_frame)] == nil) then
|
|
76 sip_callid = frames[tostring(t38_setup_frame)]
|
|
76 sip_callid = frames[tostring(t38_setup_frame)]
|
|
77 end
|
|
77 end
|
|
78 end
|
|
78 end
|
|
79
|
|
79
|
|
80 --if rtp_setup_frame then
|
|
80 --if rtp_setup_frame then
|
|
81 if not (frames[tostring(rtp_setup_frame)] == nil) then
|
|
81 if not (frames[tostring(rtp_setup_frame)] == nil) then
|
|
82 sip_callid = frames[tostring(rtp_setup_frame)]
|
|
82 sip_callid = frames[tostring(rtp_setup_frame)]
|
... | @@ -522,14 +522,14 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -522,14 +522,14 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
91 -- rtp_dmp:flush()
|
|
91 -- rtp_dmp:flush()
|
|
92 end
|
|
92 end
|
|
93 --end
|
|
93 --end
|
|
94
|
|
94
|
|
95 if (sip_callid == nil) then
|
|
95 if (sip_callid == nil) then
|
|
96 if (rtp_ssrc) then
|
|
96 if (rtp_ssrc) then
|
|
97 sip_callid = rtp[tostring(rtp_ssrc)]
|
|
97 sip_callid = rtp[tostring(rtp_ssrc)]
|
|
98 --if not (sip_callid == nil) then print("SSRC: " .. tostring(rtp_ssrc) .. " = " .. sip_callid) end
|
|
98 --if not (sip_callid == nil) then print("SSRC: " .. tostring(rtp_ssrc) .. " = " .. sip_callid) end
|
|
99 end
|
|
99 end
|
|
100 end
|
|
100 end
|
|
101
|
|
101
|
|
102 if sip_callid then
|
|
102 if sip_callid then
|
|
103 if not ((closed[tostring(sip_callid)] == true)) then
|
|
103 if not ((closed[tostring(sip_callid)] == true)) then
|
|
104 --check_age()
|
|
104 --check_age()
|
... | @@ -544,9 +544,9 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -544,9 +544,9 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
113 VALUES ('%s', '%s', '%s', '%s')
|
|
113 VALUES ('%s', '%s', '%s', '%s')
|
|
114 ]], files_path[tostring(sip_callid)], files[tostring(sip_callid)], tostring(sip_callid), "open")
|
|
114 ]], files_path[tostring(sip_callid)], files[tostring(sip_callid)], tostring(sip_callid), "open")
|
|
115 ))
|
|
115 ))
|
|
116
|
|
116
|
|
117 end
|
|
117 end
|
|
118
|
|
118
|
|
119 -- print(tostring(sip_callid))
|
|
119 -- print(tostring(sip_callid))
|
|
120 sip_dmp = dumpers[tostring(sip_callid)]
|
|
120 sip_dmp = dumpers[tostring(sip_callid)]
|
|
121 if not sip_dmp then
|
|
121 if not sip_dmp then
|
... | @@ -571,8 +571,8 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -571,8 +571,8 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
140 print("Ignoring packet after " .. tostring(sip_callid) .. " was closed.")
|
|
140 print("Ignoring packet after " .. tostring(sip_callid) .. " was closed.")
|
|
141 end
|
|
141 end
|
|
142 end
|
|
142 end
|
|
143
|
|
143
|
|
144
|
|
144
|
|
145 if raw_sip_line_f() then
|
|
145 if raw_sip_line_f() then
|
|
146 local line = {raw_sip_line_f()}
|
|
146 local line = {raw_sip_line_f()}
|
|
147 for i=1,#line do
|
|
147 for i=1,#line do
|
... | @@ -592,8 +592,8 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -592,8 +592,8 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
161 end
|
|
161 end
|
|
162 end
|
|
162 end
|
|
163 end
|
|
163 end
|
|
164
|
|
164
|
|
165
|
|
165
|
|
166 function check_age()
|
|
166 function check_age()
|
|
167 for item in pairs(last_packet) do
|
|
167 for item in pairs(last_packet) do
|
|
168 local age = os.difftime(os.clock(), last_packet[tostring(item)])
|
|
168 local age = os.difftime(os.clock(), last_packet[tostring(item)])
|
... | @@ -606,13 +606,13 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -606,13 +606,13 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
175 --dumper:flush()
|
|
175 --dumper:flush()
|
|
176 --dumper:close()
|
|
176 --dumper:close()
|
|
177 --dumpers[tostring(item)] = nil
|
|
177 --dumpers[tostring(item)] = nil
|
|
178
|
|
178
|
|
179 --dumpers[tostring(item)]:close()
|
|
179 --dumpers[tostring(item)]:close()
|
|
180 --dumpers[tostring(item)] = nil
|
|
180 --dumpers[tostring(item)] = nil
|
|
181 end
|
|
181 end
|
|
182 end
|
|
182 end
|
|
183 end
|
|
183 end
|
|
184
|
|
184
|
|
185 function mark_closed(sip_callid)
|
|
185 function mark_closed(sip_callid)
|
|
186 print("Closing: " .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)])
|
|
186 print("Closing: " .. files_path[tostring(sip_callid)] .. files[tostring(sip_callid)])
|
|
187 res = assert (con:execute(string.format([[
|
|
187 res = assert (con:execute(string.format([[
|
... | @@ -625,25 +625,25 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
... | @@ -625,25 +625,25 @@ Notice that the last "`read_format:Fileshark Pcap`" argument is encased in sing |
|
194 files[tostring(sip_callid)] = nil
|
|
194 files[tostring(sip_callid)] = nil
|
|
195 files_path[tostring(sip_callid)] = nil
|
|
195 files_path[tostring(sip_callid)] = nil
|
|
196 end
|
|
196 end
|
|
197
|
|
197
|
|
198 function tap.draw()
|
|
198 function tap.draw()
|
|
199 -- The show is over. Close the database connection and flush the buffers.
|
|
199 -- The show is over. Close the database connection and flush the buffers.
|
|
200 for item in pairs(closed) do
|
|
200 for item in pairs(closed) do
|
|
201 print("cleaning up: " .. item)
|
|
201 print("cleaning up: " .. item)
|
|
202 dumpers[tostring(item)] = nil
|
|
202 dumpers[tostring(item)] = nil
|
|
203 end
|
|
203 end
|
|
204
|
|
204
|
|
205 for item,dumper in pairs(dumpers) do
|
|
205 for item,dumper in pairs(dumpers) do
|
|
206 print("Flushing: " .. files_path[tostring(item)] .. files[tostring(item)])
|
|
206 print("Flushing: " .. files_path[tostring(item)] .. files[tostring(item)])
|
|
207 dumper:flush()
|
|
207 dumper:flush()
|
|
208 mark_closed(item)
|
|
208 mark_closed(item)
|
|
209 end
|
|
209 end
|
|
210
|
|
210
|
|
211 -- Close the database connection
|
|
211 -- Close the database connection
|
|
212 con:close()
|
|
212 con:close()
|
|
213 env:close()
|
|
213 env:close()
|
|
214 end
|
|
214 end
|
|
215
|
|
215
|
|
216 function tap.reset()
|
|
216 function tap.reset()
|
|
217 for item,dumper in pairs(dumpers) do
|
|
217 for item,dumper in pairs(dumpers) do
|
|
218 mark_closed(item)
|
|
218 mark_closed(item)
|
... | | ... | |