-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcr3.lua
273 lines (225 loc) · 7.21 KB
/
cr3.lua
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
--
-- thoughtleader@internetofallthethings.com
--
cr3_proto = Proto("cr3","Crimson v3")
-- define the field names, widths, descriptions, and number base
-- looks like lua structs is what I should use here
local pf_payload_length = ProtoField.uint16("cr3.len", "Length", base.HEX)
local pf_reg = ProtoField.uint16("cr3.reg", "Register number", base.HEX)
local pf_payload = ProtoField.bytes("cr3.payload", "Payload")
local ptype = ProtoField.uint16("cr3.payload.type", "Type", base.HEX)
local pzero = ProtoField.uint16("cr3.payload.zero", "Zero", base.HEX)
local pdata = ProtoField.bytes("cr3.payload.data", "Data")
local pstring = ProtoField.string("cr3.payload.string", "String")
-- 0x1300
local p_1300_seq = ProtoField.uint16("cr3.payload.sequence", "Sequence", base.HEX)
local p_1300_subtype = ProtoField.uint16("cr3.payload.subtype", "Subtype", base.HEX)
local p_1300_value = ProtoField.uint32("cr3.payload.value", "Value", base.HEX)
local p_1700_value = p_1300_value
-- 0x1500
-- start 32bit
-- length
local p_1500_chunkstart = ProtoField.uint32("cr3.payload.chunkstart", "Chunk start", base.HEX)
local p_1500_chunklength = ProtoField.uint16("cr3.payload.chunklength", "Chunk Length", base.HEX)
local p_1500_chunkdata = ProtoField.bytes("cr3.payload.chunkdata", "Chunk Data")
-- 0x1b00
-- 32bit zero
-- 16bit readoffset
-- 16bit readlength
local p_1b00_zero = ProtoField.uint32("cr3.payload.zero", "Zero", base.HEX)
local p_1b00_readoffset = ProtoField.uint16("cr3.payload.readoffset", "Read offset", base.HEX)
local p_1b00_readlength = ProtoField.uint16("cr3.payload.readlength", "Read length", base.HEX)
-- example I followed said not to do the fields like this, risk of missing some
cr3_proto.fields = {
pf_payload_length,
pf_reg,
pf_payload,
ptype,
pstring,
pdata,
p_1300_seq,
p_1300_subtype,
p_1300_value,
p_1500_chunkstart,
p_1500_chunklength,
p_1500_chunkdata,
p_1b00_zero,
p_1b00_readoffset,
p_1b00_readlength
}
-- trying out a global variable for processing any cr3 segments
local processing_segment = false
-- local reassembled_length = 0
-- local segment_cur = 0
-- local segment_data = nil
function cr3_proto.dissector(tvbuf,pinfo,tree)
-- length of the received packet
local pktlen = tvbuf:reported_length_remaining()
if not processing_segment then
-- pf_payload_length
local cr3len = tvbuf(0,2):uint()
if pktlen == cr3len + 2 then
dissect_cr3(tvbuf, pinfo, tree, cr3len)
return
elseif cr3len > pktlen then
processing_segment = true
pinfo.desegment_len = cr3len - pktlen + 2
return
else
-- checking if this ever hits
print "SHOULD NOT HIT THIS"
return
end
else
-- preumption is that setting desegment_len
-- means we won't get called until we recv that much
dissect_cr3(tvbuf, pinfo, tree, cr3len)
processing_segment = false
return
end
end
function dissect_cr3(tvbuf,pinfo,tree,cr3len)
-- set the protocol column based on the Proto object
pinfo.cols.protocol = cr3_proto.description
-- length of the entire CR3 payload
local pktlen = tvbuf:reported_length_remaining()
-- define this entire length as the object of dissection
local subtree = tree:add(cr3_proto, tvbuf:range(0, pktlen))
-- setup fields in the proper order and width
local offset = 0
local cr3len = tvbuf(offset,2):uint()
subtree:add(pf_payload_length,tvbuf(offset,2))
offset = offset + 2
local reg = tvbuf(offset,2):uint()
subtree:add(pf_reg, reg)
offset = offset + 2
-- payload gets broken out
local payloadtree = subtree:add(pf_payload, tvbuf:range(offset, pktlen - offset))
payloadtree:append_text(string.format(" (0x%02x bytes)", tvbuf:reported_length_remaining() - 4))
payloadtree:add(ptype, tvbuf(offset, 2))
local packettype = tvbuf:range(offset, 2):uint()
offset = offset + 2
-- setting CR3 summary data into the info column in the UI
pinfo.cols.info = string.format("Register: 0x%04x, Type: 0x%04x, Bytes: 0x%04x", reg, packettype, cr3len + 2)
print(string.format("packettype 0x%04x",packettype))
-- type-specific handling here
-- packettype 0x0100
if packettype == 0x0100 then
-- no data
return
elseif packettype == 0x0200 then
-- no data
return
elseif packettype == 0x0300 then
if (reg == 0x012a or reg == 0x012b) then
string = tvbuf:range(offset):stringz()
payloadtree:add(pstring, string)
else
local data = tvbuf:range(offset)
payloadtree:add(pdata,data)
end
return
elseif packettype == 0x1000 or packettype == 0x1600 then
-- 16 byte read
if not crlen == 0x14 then
print "subtype 0x1000, length violates assumption"
return
end
local data = tvbuf:range(offset)
payloadtree:add(pdata,data)
return
elseif packettype == 0x1100 then
if not(cr3len > 4) then
print(string.format("subtype 0x%04x, length violates assumption", packettype))
return
end
local data = tvbuf:range(offset)
payloadtree:add(pdata, data)
return
elseif packettype == 0x1300 or packettype == 0x1400 then
-- sequence
-- type
-- value
if not (cr3len == 0x0c) then
print(string.format("subtype 0x%04x, length violates assumption", packettype))
return
end
local seq = tvbuf(offset,2):uint()
offset = offset + 2
local subtype = tvbuf(offset,2):uint()
offset = offset + 2
local value = tvbuf(offset,4):uint()
offset = offset + 4
payloadtree:add(p_1300_seq,seq)
payloadtree:add(p_1300_subtype,subtype)
payloadtree:add(p_1300_value,value)
return
elseif packettype == 0x1200 or packettype == 0x1202 or packettype == 0x1500 then
if not(cr3len > 4) then
print(string.format("subtype 0x%04x, length violates assumption", packettype))
return
end
-- start
-- length
local chunkstart = tvbuf(offset,4):uint()
offset = offset + 4
local chunklength = tvbuf(offset,2):uint()
offset = offset + 2
local chunkdata = tvbuf(offset)
payloadtree:add(p_1500_chunkstart, chunkstart)
payloadtree:add(p_1500_chunklength, chunklength)
payloadtree:add(p_1500_chunkdata, chunkdata)
return
elseif packettype == 0x1700 then
-- seems to always read 0x7530 (30000)
local value = tvbuf(offset,4):uint()
payloadtree:add(p_1700_value, value)
return
elseif packettype == 0x1800 then
-- no read
return
elseif packettype == 0x1a00 then
if cr3len > 4 then
local data = tvbuf:range(offset)
payloadtree:add(pdata, data)
end
return
elseif packettype == 0x1b00 then
if cr3len < 0x0c then
print(string.format("subtype 0x%04x, length violates assumption", packettype))
return
end
local zero = tvbuf(offset,4):uint()
offset = offset + 4
local readoffset = tvbuf(offset,2):uint()
offset = offset + 2
local readlength = tvbuf(offset,2):uint()
offset = offset + 2
payloadtree:add(p_1b00_zero, zero)
payloadtree:add(p_1b00_readoffset, readoffset)
payloadtree:add(p_1b00_readlength, readlength)
return
elseif packettype == 0x1c00 then
-- no read
return
elseif packettype == 0x1e00 then
-- one byte
local data = tvbuf:range(offset)
payloadtree:add(pdata, data)
return
elseif packettype == 0x1f00 then
-- no read
return
elseif packettype == 0x2e00 then
-- no read
return
else
print(string.format("Unknown packettype 0x%04x", packettype))
return
end
return
end
-- load the tcp.port table
tcp_table = DissectorTable.get("tcp.port")
-- register our protocol tcp:789
tcp_table:add(789,cr3_proto)