summaryrefslogtreecommitdiffstats
path: root/usb/ncr-dispenser.lua
blob: c6dbfd04adcb863161c92616d926db276766bcbf (plain)
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
-- 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.up_addr", "Upload Addr", base.HEX)
size_F   = ProtoField.uint32("dispenser.up_size", "Upload Size", base.HEX)
data_F   = ProtoField.bytes("dispenser.up_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)