-- declare some Fields to be read usb_hl_f = Field.new("usb.usbpcap_header_len") usb_tt_f = Field.new("usb.transfer_type") usb_dl_f = Field.new("usb.data_len") usb_di_f = Field.new("usb.endpoint_number.direction") -- declare our (pseudo) protocol dispenser_proto = Proto("dispenser","NCR S1 Dispenser") direction_vals = { [ 0 ] = "OUT", [ 1 ] = "IN", } mode_vals = { [ 1 ] = "Command", [ 2 ] = "Upload", } -- create the fields for our "protocol" dir_F = ProtoField.uint8("dispenser.direction", "Direction", base.DEC, direction_vals) b00_F = ProtoField.uint8("dispenser.mode", "Mode (?)", base.HEX, mode_vals) b01_F = ProtoField.uint8("dispenser.b01", "Unknown 01", base.HEX) w02_F = ProtoField.uint16("dispenser.w02", "Unknown 02", base.HEX) w04_F = ProtoField.uint16("dispenser.w04", "Const 04 (?)", base.HEX) w06_F = ProtoField.uint16("dispenser.seq", "Sequence Nr (?)", base.HEX) w08_F = ProtoField.uint16("dispenser.magic", "Magic Cookie", base.HEX) w0a_F = ProtoField.uint16("dispenser.w0a", "Unknown 0a", base.HEX) w0c_F = ProtoField.uint16("dispenser.d0c", "Unknown 0c", base.HEX) w0e_F = ProtoField.uint16("dispenser.d0e", "Unknown 0e", base.HEX) d10_F = ProtoField.uint32("dispenser.d10", "Unknown 10", base.HEX) d14_F = ProtoField.uint32("dispenser.d14", "Unknown 14", base.HEX) d18_F = ProtoField.uint32("dispenser.d18", "Unknown 18", base.HEX) d1c_F = ProtoField.uint32("dispenser.d1c", "Unknown 1c", base.HEX) d20_F = ProtoField.uint32("dispenser.d20", "Unknown 20", base.HEX) d24_F = ProtoField.uint32("dispenser.d24", "Unknown 24", base.HEX) d28_F = ProtoField.uint32("dispenser.d28", "Unknown 28", base.HEX) d2c_F = ProtoField.uint32("dispenser.d2c", "Unknown 2c", base.HEX) d30_F = ProtoField.uint32("dispenser.d30", "Unknown 30", base.HEX) d34_F = ProtoField.uint32("dispenser.d34", "Unknown 34", base.HEX) d38_F = ProtoField.uint32("dispenser.d38", "Unknown 38", base.HEX) d3c_F = ProtoField.uint32("dispenser.d3c", "Unknown 3c", base.HEX) addr_F = ProtoField.uint32("dispenser.addr", "Upload Address", base.HEX) size_F = ProtoField.uint32("dispenser.size", "Upload Size", base.HEX) data_F = ProtoField.bytes("dispenser.data", "Upload Data") -- add the field to the protocol dispenser_proto.fields = { dir_F, b00_F, b01_F, w02_F, w04_F, w06_F, w08_F, w0a_F, w0c_F, w0e_F, d10_F, d14_F, d18_F, d1c_F, d20_F, d24_F, d28_F, d2c_F, d30_F, d34_F, d38_F, d3c_F, addr_F, size_F, data_F, } -- create a function to "postdissect" each frame function dispenser_proto.dissector(buffer,pinfo,tree) -- obtain the current values the protocol fields local usb_hl = usb_hl_f() local usb_tt = usb_tt_f() local usb_dl = usb_dl_f() local usb_di = usb_di_f() if usb_tt.value == 0x01 and usb_dl.value >= 63 then local off = 64 -- linux (usbmon) if usb_hl then off = usb_hl.value -- windows (https://desowin.org/usbpcap/) end local mode = buffer(off + 0x00, 1) local size = buffer(off + 0x18, 4) local magic = buffer(off + 0x08, 2) if magic:le_uint() == 0xbeef then local subtree = tree:add(dispenser_proto, "NCR S1 Dispenser") subtree:add(dir_F, usb_di.value) subtree:add(b00_F, mode) subtree:add(b01_F, buffer(off + 0x01, 1)) subtree:add_le(w02_F, buffer(off + 0x02, 2)) subtree:add_le(w04_F, buffer(off + 0x04, 2)) subtree:add_le(w06_F, buffer(off + 0x06, 2)) subtree:add_le(w08_F, magic) local w0a = buffer(off + 0x0a, 2) if w0a:le_uint() > 0 then subtree:add_le(w0a_F, w0a) end local w0c = buffer(off + 0x0c, 2) if w0c:le_uint() > 0 then subtree:add_le(w0c_F, w0c) end local w0e = buffer(off + 0x0e, 2) if w0e:le_uint() > 0 then subtree:add_le(w0e_F, w0e) end local d10 = buffer(off + 0x10, 4) if d10:le_uint() > 0 then subtree:add_le(d10_F, d10) end if mode:uint() == 2 then subtree:add_le(addr_F, buffer(off + 0x14, 4)) subtree:add_le(size_F, size) subtree:add_le(data_F, buffer(off + 0x1c, size:le_uint())) else local d14 = buffer(off + 0x14, 4) if d14:le_uint() > 0 then subtree:add_le(d14_F, d14) end local d18 = buffer(off + 0x18, 4) if d18:le_uint() > 0 then subtree:add_le(d18_F, d18) end local d1c = buffer(off + 0x1c, 4) if d1c:le_uint() > 0 then subtree:add_le(d1c_F, d1c) end local d20 = buffer(off + 0x20, 4) if d20:le_uint() > 0 then subtree:add_le(d20_F, d20) end local d24 = buffer(off + 0x24, 4) if d24:le_uint() > 0 then subtree:add_le(d24_F, d24) end local d28 = buffer(off + 0x28, 4) if d28:le_uint() > 0 then subtree:add_le(d28_F, d28) end local d2c = buffer(off + 0x2c, 4) if d2c:le_uint() > 0 then subtree:add_le(d2c_F, d2c) end local d30 = buffer(off + 0x30, 4) if d30:le_uint() > 0 then subtree:add_le(d30_F, d30) end local d34 = buffer(off + 0x34, 4) if d34:le_uint() > 0 then subtree:add_le(d34_F, d34) end local d38 = buffer(off + 0x38, 4) if d38:le_uint() > 0 then subtree:add_le(d38_F, d38) end end end end end -- register our protocol as a postdissector register_postdissector(dispenser_proto)