aboutsummaryrefslogtreecommitdiff
path: root/wireshark/ieee.lua
diff options
context:
space:
mode:
Diffstat (limited to 'wireshark/ieee.lua')
-rw-r--r--wireshark/ieee.lua96
1 files changed, 96 insertions, 0 deletions
diff --git a/wireshark/ieee.lua b/wireshark/ieee.lua
new file mode 100644
index 0000000..bbdc397
--- /dev/null
+++ b/wireshark/ieee.lua
@@ -0,0 +1,96 @@
+require "util"
+local bit = require "bit"
+
+local p = Proto("ieee", "IEEE802.11 frame header")
+
+-- based off <https://www.problemkaputt.de/gbatek.htm#dswifiieee80211frames>
+
+p.fields.ctl = ProtoField.new("Frame control", "ieee.ctl", ftypes.BYTES)
+p.fields.ctl_ver = ProtoField.uint16("ieee.ctl.ver", "Protocol version", base.DEC, {
+ [0] = "Current",
+ [1] = "Reserved",
+ [2] = "Reserved",
+ [3] = "Reserved",
+}, bits(0, 2))
+p.fields.ctl_type = ProtoField.uint16("ieee.ctl.type", "Type", base.DEC, {
+ [0] = "Management",
+ [1] = "Control",
+ [2] = "Data",
+ [3] = "Reserved",
+}, bits(2, 2))
+p.fields.ctl_subtype = ProtoField.uint16("ieee.ctl.subtype", "Subtype", base.DEC, nil, bits(4, 4))
+p.fields.ctl_to_ds = ProtoField.bool("ieee.ctl.tods", "To DS", base.DEC, nil, bits(8))
+p.fields.ctl_from_ds = ProtoField.bool("ieee.ctl.fromds", "From DS", base.DEC, nil, bits(9))
+p.fields.ctl_fragment = ProtoField.bool("ieee.ctl.fragment", "More fragments", base.DEC, nil, bits(10))
+p.fields.ctl_retry = ProtoField.bool("ieee.ctl.retry", "Retry", base.DEC, nil, bits(11))
+p.fields.ctl_power = ProtoField.bool("ieee.ctl.power", "Power management", base.DEC, nil, bits(12))
+p.fields.ctl_data = ProtoField.bool("ieee.ctl.data", "More data", base.DEC, nil, bits(13))
+p.fields.ctl_wep = ProtoField.bool("ieee.ctl.wep", "WEP encrypt", base.DEC, nil, bits(14))
+p.fields.ctl_order = ProtoField.bool("ieee.ctl.order", "Order", base.DEC, nil, bits(15))
+
+p.fields.duration = ProtoField.uint16("ieee.duration", "Duration / ID")
+p.fields.addr1 = ProtoField.ether("ieee.addr1", "Address 1")
+p.fields.addr2 = ProtoField.ether("ieee.addr2", "Address 2")
+p.fields.addr3 = ProtoField.ether("ieee.addr3", "Address 3")
+p.fields.seq = ProtoField.uint16("ieee.seq", "Sequence control")
+p.fields.seq_frag = ProtoField.uint16("ieee.seq.frag", "Fragment", base.DEC, nil, bits(0, 4))
+p.fields.seq_num = ProtoField.uint16("ieee.seq.num", "Sequence number", base.DEC, nil, bits(4, 12))
+
+p.fields.body = ProtoField.bytes("ieee.body", "Body")
+
+local pc_dissector = Dissector.get("pictochat")
+
+function p.dissector(buffer, pinfo, tree)
+ local buffer_len = buffer:len()
+ -- invalid
+ if buffer_len < 10 then return 0 end
+
+ -- pretty wireshark shit
+ pinfo.cols.protocol = p.name
+
+ -- MAC header is (usually) 0x18 bytes, but also sometimes contains values in
+ -- the trailer. The 0x18 here is so wireshark only highlights the MAC header
+ -- when clicking this item in the dissection tree.
+ local subtree = tree:add(p, buffer(0x00, 0x18), p.description)
+ local trailer_size = 0
+
+ local ctl_tree = subtree:add_le(p.fields.ctl, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_ver, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_type, buffer(0x00, 2))
+ local ctl_type = bit.rshift(bit.band(buffer(0x00, 2):le_uint(), bits(2, 2)), 2)
+ ctl_tree:add_le(p.fields.ctl_subtype, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_to_ds, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_from_ds, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_fragment, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_retry, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_power, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_data, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_wep, buffer(0x00, 2))
+ ctl_tree:add_le(p.fields.ctl_order, buffer(0x00, 2))
+
+ subtree:add_le(p.fields.duration, buffer(0x02, 2))
+ subtree:add(p.fields.addr1, buffer(0x04, 6))
+ subtree:add(p.fields.addr2, buffer(0x0a, 6))
+ subtree:add(p.fields.addr3, buffer(0x10, 6))
+ local seq_tree = subtree:add_le(p.fields.seq, buffer(0x16, 2))
+ seq_tree:add_le(p.fields.seq_frag, buffer(0x16, 2))
+ seq_tree:add_le(p.fields.seq_num, buffer(0x16, 2))
+
+ if ctl_type ~= 0 then
+ trailer_size = 4 -- Frame Check Sequence (FCS) (hardware-generated CRC32)
+ end
+
+ buffer = buffer(0x18) -- seek forward
+
+ local body_size = buffer:len() - trailer_size
+ subtree:add(p.fields.body, buffer(0, body_size))
+ pc_dissector:call(buffer(0, body_size):tvb(), pinfo, tree)
+
+ if trailer_size == 0 then
+ return buffer_len
+ end
+
+ buffer = buffer(body_size)
+
+ return buffer_len
+end