/src/wireshark/epan/dissectors/packet-kdp.c
Line | Count | Source |
1 | | /* packet-kdp.c |
2 | | * Routines for KDP (Kontiki Delivery Protocol) packet disassembly |
3 | | * |
4 | | * Copyright (c) 2008 by Kontiki Inc. |
5 | | * Wade Hennessey <wade@kontiki.com> |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1999 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | void proto_register_kdp(void); |
18 | | void proto_reg_handoff_kdp(void); |
19 | | |
20 | | static dissector_handle_t kdp_handle; |
21 | | |
22 | 14 | #define KDP_PORT 19948 /* Not IANA registered */ |
23 | | #define BUFFER_SIZE 80 |
24 | | static int proto_kdp; |
25 | | static int ett_kdp; |
26 | | static int ett_kdp_flags; |
27 | | |
28 | | static int hf_kdp_version; |
29 | | static int hf_kdp_headerlen; |
30 | | static int hf_kdp_flags; |
31 | | static int hf_kdp_errors; |
32 | | static int hf_kdp_destflowid; |
33 | | static int hf_kdp_srcflowid; |
34 | | static int hf_kdp_sequence; |
35 | | static int hf_kdp_ack; |
36 | | static int hf_kdp_maxsegmentsize; |
37 | | static int hf_kdp_optionnumber; |
38 | | static int hf_kdp_optionlen; |
39 | | static int hf_kdp_option1; |
40 | | static int hf_kdp_option2; |
41 | | static int hf_kdp_option3; |
42 | | static int hf_kdp_option4; |
43 | | static int hf_kdp_option5; |
44 | | static int hf_kdp_option6; |
45 | | static int hf_kdp_option7; |
46 | | static int hf_kdp_option8; |
47 | | static int hf_kdp_option9; |
48 | | static int hf_kdp_option_unknown; |
49 | | static int hf_kdp_fragment; |
50 | | static int hf_kdp_fragtotal; |
51 | | static int hf_kdp_body; |
52 | | static int hf_kdp_xml_body; |
53 | | |
54 | 19 | #define KDP_DROP_FLAG (1 << 0) |
55 | 58 | #define KDP_SYN_FLAG (1 << 1) |
56 | 53 | #define KDP_ACK_FLAG (1 << 2) |
57 | 19 | #define KDP_RST_FLAG (1 << 3) |
58 | 41 | #define KDP_BCST_FLAG (1 << 4) |
59 | 19 | #define KDP_DUP_FLAG (1 << 5) |
60 | | |
61 | | static int hf_kdp_drop_flag; |
62 | | static int hf_kdp_syn_flag; |
63 | | static int hf_kdp_ack_flag; |
64 | | static int hf_kdp_rst_flag; |
65 | | static int hf_kdp_bcst_flag; |
66 | | static int hf_kdp_dup_flag; |
67 | | |
68 | | static int dissect_kdp(tvbuff_t *tvb, |
69 | | packet_info *pinfo, |
70 | 18 | proto_tree *tree, void* data _U_) { |
71 | 18 | proto_item *ti; |
72 | 18 | proto_tree *kdp_tree; |
73 | 18 | unsigned body_len; |
74 | 18 | uint8_t version; |
75 | 18 | uint8_t header_len = 0; |
76 | 18 | uint8_t packet_flags = 0; |
77 | 18 | uint8_t packet_errors = 0; |
78 | 18 | uint32_t sequence_number = UINT32_MAX; |
79 | 18 | uint32_t ack_number = UINT32_MAX; |
80 | 18 | uint32_t src_flowid = UINT32_MAX; |
81 | | |
82 | 18 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "KDP"); |
83 | 18 | col_clear(pinfo->cinfo, COL_INFO); |
84 | | |
85 | 18 | ti = proto_tree_add_item(tree, proto_kdp, tvb, 0, -1, ENC_NA); |
86 | 18 | kdp_tree = proto_item_add_subtree(ti, ett_kdp); |
87 | | |
88 | 18 | version = tvb_get_uint8(tvb, 0); |
89 | 18 | if (version != 2) { |
90 | | /* Version other than 2 is really SDDP in UDP */ |
91 | 1 | proto_tree_add_item(kdp_tree, hf_kdp_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
92 | 1 | proto_tree_add_item(kdp_tree, hf_kdp_xml_body, tvb, 0, -1, ENC_ASCII); |
93 | 17 | } else { |
94 | 17 | proto_tree *flags_tree; |
95 | 17 | header_len = tvb_get_uint8(tvb, 1) * 4; |
96 | 17 | body_len = tvb_reported_length(tvb); |
97 | 17 | if (header_len > body_len) { |
98 | 11 | body_len = 0; /* malformed packet */ |
99 | 11 | } else { |
100 | 6 | body_len = body_len - header_len; |
101 | 6 | } |
102 | 17 | packet_flags = tvb_get_uint8(tvb, 2); |
103 | 17 | packet_errors = tvb_get_uint8(tvb, 3); |
104 | 17 | proto_tree_add_item(kdp_tree, hf_kdp_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
105 | 17 | proto_tree_add_item(kdp_tree, hf_kdp_headerlen, tvb, 1, 1, ENC_BIG_ENDIAN); |
106 | 17 | ti = proto_tree_add_item(kdp_tree, hf_kdp_flags, tvb, 2, 1, ENC_BIG_ENDIAN); |
107 | 17 | flags_tree = proto_item_add_subtree(ti, ett_kdp_flags); |
108 | | |
109 | 17 | proto_tree_add_item(flags_tree, hf_kdp_drop_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
110 | 17 | proto_tree_add_item(flags_tree, hf_kdp_syn_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
111 | 17 | proto_tree_add_item(flags_tree, hf_kdp_ack_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
112 | 17 | proto_tree_add_item(flags_tree, hf_kdp_rst_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
113 | 17 | proto_tree_add_item(flags_tree, hf_kdp_bcst_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
114 | 17 | proto_tree_add_item(flags_tree, hf_kdp_dup_flag, tvb, 2, 1, ENC_BIG_ENDIAN); |
115 | | |
116 | 17 | proto_tree_add_item(kdp_tree, hf_kdp_errors, tvb, 3, 1, ENC_BIG_ENDIAN); |
117 | | |
118 | 17 | if (header_len > 4) { |
119 | 17 | int offset; |
120 | 17 | offset = 4; |
121 | 17 | if (packet_flags & KDP_ACK_FLAG) { |
122 | 12 | proto_tree_add_item(kdp_tree, hf_kdp_destflowid, tvb, offset, 4, ENC_BIG_ENDIAN); |
123 | 12 | offset = offset + 4; |
124 | 12 | } |
125 | | |
126 | 17 | if (packet_flags & (KDP_SYN_FLAG | KDP_BCST_FLAG)) { |
127 | 15 | proto_tree_add_item(kdp_tree, hf_kdp_srcflowid, tvb, offset, 4, ENC_BIG_ENDIAN); |
128 | 15 | src_flowid = tvb_get_ntohl(tvb, offset); |
129 | 15 | offset = offset + 4; |
130 | 15 | } |
131 | | |
132 | 17 | proto_tree_add_item(kdp_tree, hf_kdp_sequence, tvb, offset, 4, ENC_BIG_ENDIAN); |
133 | 17 | sequence_number = tvb_get_ntohl(tvb, offset); |
134 | 17 | offset = offset + 4; |
135 | | |
136 | 17 | if (packet_flags & KDP_ACK_FLAG) { |
137 | 12 | proto_tree_add_item(kdp_tree, hf_kdp_ack, tvb, offset, 4, ENC_BIG_ENDIAN); |
138 | 12 | ack_number = tvb_get_ntohl(tvb, offset); |
139 | 12 | offset = offset + 4; |
140 | 12 | } |
141 | 17 | if (packet_flags & KDP_SYN_FLAG) { |
142 | 11 | proto_tree_add_item(kdp_tree, hf_kdp_maxsegmentsize, tvb, offset, 4, ENC_BIG_ENDIAN); |
143 | 11 | offset = offset + 4; |
144 | 11 | } |
145 | | |
146 | 402 | while (offset < ((body_len > 0) ? header_len - 4 : header_len)) { |
147 | 397 | uint8_t option_number; |
148 | 397 | uint8_t option_len = 0; |
149 | | |
150 | 397 | option_number = tvb_get_uint8(tvb, offset); |
151 | | |
152 | 397 | proto_tree_add_item(kdp_tree, hf_kdp_optionnumber, tvb, offset, 1, ENC_BIG_ENDIAN); |
153 | 397 | offset = offset + 1; |
154 | 397 | if (option_number > 0) { |
155 | 97 | option_len = tvb_get_uint8(tvb, offset); |
156 | 97 | proto_tree_add_item(kdp_tree, hf_kdp_optionlen, tvb, offset, 1, ENC_BIG_ENDIAN); |
157 | 97 | offset = offset + 1; |
158 | 97 | } |
159 | | |
160 | 397 | switch (option_number) { |
161 | 298 | case 0: |
162 | 298 | break; |
163 | 21 | case 1: |
164 | 21 | proto_tree_add_item(kdp_tree, hf_kdp_option1, tvb, offset, 2, ENC_BIG_ENDIAN); |
165 | 21 | offset = offset + 2; |
166 | 21 | break; |
167 | 3 | case 2: |
168 | 3 | proto_tree_add_item(kdp_tree, hf_kdp_option2, tvb, offset, 2, ENC_BIG_ENDIAN); |
169 | 3 | offset = offset + 2; |
170 | 3 | break; |
171 | 10 | case 3: |
172 | 10 | proto_tree_add_item(kdp_tree, hf_kdp_option3, tvb, offset, 2, ENC_BIG_ENDIAN); |
173 | 10 | offset = offset + 2; |
174 | 10 | break; |
175 | 0 | case 4: |
176 | 0 | proto_tree_add_item(kdp_tree, hf_kdp_option4, tvb, offset, 0, ENC_NA); |
177 | 0 | break; |
178 | 0 | case 5: |
179 | 0 | proto_tree_add_item(kdp_tree, hf_kdp_option5, tvb, offset, 0, ENC_NA); |
180 | 0 | break; |
181 | 9 | case 6: |
182 | 9 | proto_tree_add_item(kdp_tree, hf_kdp_option6, tvb, offset, option_len - 2, ENC_NA); |
183 | 9 | offset = offset + option_len - 2; |
184 | 9 | break; |
185 | 9 | case 7: |
186 | 9 | proto_tree_add_item(kdp_tree, hf_kdp_option7, tvb, offset, 2, ENC_BIG_ENDIAN); |
187 | 9 | offset = offset + 2; |
188 | 9 | break; |
189 | 2 | case 8: |
190 | 2 | proto_tree_add_item(kdp_tree, hf_kdp_option8, tvb, offset, 2, ENC_BIG_ENDIAN); |
191 | 2 | offset = offset + 2; |
192 | 2 | break; |
193 | 3 | case 9: |
194 | 3 | proto_tree_add_item(kdp_tree, hf_kdp_option9, tvb, offset, 2, ENC_BIG_ENDIAN); |
195 | 3 | offset = offset + 2; |
196 | 3 | break; |
197 | 40 | default: |
198 | 40 | proto_tree_add_item(kdp_tree, hf_kdp_option_unknown, tvb, offset, option_len - 2, ENC_NA); |
199 | 40 | offset = offset + option_len - 2; |
200 | 40 | break; |
201 | 397 | } |
202 | 397 | } |
203 | | |
204 | 5 | if (body_len > 0) { |
205 | 5 | proto_tree_add_item(kdp_tree, hf_kdp_fragment, tvb, offset, 2, ENC_BIG_ENDIAN); |
206 | 5 | offset = offset + 2; |
207 | | |
208 | 5 | proto_tree_add_item(kdp_tree, hf_kdp_fragtotal, tvb, offset, 2, ENC_BIG_ENDIAN); |
209 | 5 | offset = offset + 2; |
210 | | |
211 | 5 | proto_tree_add_item(kdp_tree, hf_kdp_body, tvb, offset, -1, ENC_NA); |
212 | 5 | } |
213 | 5 | } |
214 | 17 | } |
215 | | /* Now that we know sequence number and optional ack number, we can |
216 | | print more detailed summary info */ |
217 | 6 | if (version != 2) { |
218 | 1 | col_set_str(pinfo->cinfo, COL_INFO, "SDDP message"); |
219 | 5 | } else { |
220 | 5 | char ack_string[BUFFER_SIZE]; |
221 | 5 | char seq_num_string[BUFFER_SIZE]; |
222 | 5 | char src_flowid_string[BUFFER_SIZE]; |
223 | | |
224 | 5 | if (packet_flags & KDP_ACK_FLAG) { |
225 | 3 | snprintf(ack_string, sizeof(ack_string), "ACK=%x ", ack_number); |
226 | 3 | } else { |
227 | 2 | ack_string[0] = '\0'; |
228 | 2 | } |
229 | 5 | if (header_len > 4) { |
230 | 5 | snprintf(seq_num_string, sizeof(seq_num_string), "SEQ=%x ", sequence_number); |
231 | 5 | } else { |
232 | 0 | seq_num_string[0] = '\0'; |
233 | 0 | } |
234 | 5 | if (packet_flags & (KDP_SYN_FLAG | KDP_BCST_FLAG)) { |
235 | 5 | snprintf(src_flowid_string, sizeof(src_flowid_string), "SRC_FLOWID=%x ", src_flowid); |
236 | 5 | } else { |
237 | 0 | src_flowid_string[0] = '\0'; |
238 | 0 | } |
239 | 5 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s%s%s%serrors=%d", |
240 | 5 | ((packet_flags & KDP_DROP_FLAG) ? "DROP " : ""), |
241 | 5 | ((packet_flags & KDP_SYN_FLAG) ? "SYN " : ""), |
242 | 5 | ((packet_flags & KDP_RST_FLAG) ? "RST " : ""), |
243 | 5 | ((packet_flags & KDP_BCST_FLAG) ? "BCST " : ""), |
244 | 5 | ((packet_flags & KDP_DUP_FLAG) ? "DUP " : ""), |
245 | 5 | ack_string, |
246 | 5 | seq_num_string, |
247 | 5 | src_flowid_string, |
248 | 5 | packet_errors); |
249 | 5 | } |
250 | | |
251 | 6 | return tvb_captured_length(tvb); |
252 | 18 | } |
253 | | |
254 | 14 | void proto_register_kdp(void) { |
255 | | |
256 | 14 | static hf_register_info hf[] = { |
257 | 14 | { &hf_kdp_version, |
258 | 14 | {"KDP version", "kdp.version", |
259 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} |
260 | 14 | }, |
261 | 14 | { &hf_kdp_headerlen, |
262 | 14 | {"KDP header len", "kdp.headerlen", |
263 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} |
264 | 14 | }, |
265 | 14 | { &hf_kdp_flags, |
266 | 14 | {"KDP flags", "kdp.flags", |
267 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} |
268 | 14 | }, |
269 | 14 | { &hf_kdp_drop_flag, |
270 | 14 | {"KDP DROP Flag", "kdp.flags.drop", |
271 | 14 | FT_BOOLEAN, 8, NULL, KDP_DROP_FLAG, NULL, HFILL} |
272 | 14 | }, |
273 | 14 | { &hf_kdp_syn_flag, |
274 | 14 | {"KDP SYN Flag", "kdp.flags.syn", |
275 | 14 | FT_BOOLEAN, 8, NULL, KDP_SYN_FLAG, NULL, HFILL} |
276 | 14 | }, |
277 | 14 | { &hf_kdp_ack_flag, |
278 | 14 | {"KDP ACK Flag", "kdp.flags.ack", |
279 | 14 | FT_BOOLEAN, 8, NULL, KDP_ACK_FLAG, NULL, HFILL} |
280 | 14 | }, |
281 | 14 | { &hf_kdp_rst_flag, |
282 | 14 | {"KDP RST Flag", "kdp.flags.rst", |
283 | 14 | FT_BOOLEAN, 8, NULL, KDP_RST_FLAG, NULL, HFILL} |
284 | 14 | }, |
285 | 14 | { &hf_kdp_bcst_flag, |
286 | 14 | {"KDP BCST Flag", "kdp.flags.bcst", |
287 | 14 | FT_BOOLEAN, 8, NULL, KDP_BCST_FLAG, NULL, HFILL} |
288 | 14 | }, |
289 | 14 | { &hf_kdp_dup_flag, |
290 | 14 | {"KDP DUP Flag", "kdp.flags.dup", |
291 | 14 | FT_BOOLEAN, 8, NULL, KDP_DUP_FLAG, NULL, HFILL} |
292 | 14 | }, |
293 | 14 | { &hf_kdp_errors, |
294 | 14 | {"KDP errors", "kdp.errors", |
295 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} |
296 | 14 | }, |
297 | 14 | { &hf_kdp_destflowid, |
298 | 14 | { "DestFlowID", "kdp.destflowid", |
299 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} |
300 | 14 | }, |
301 | 14 | { &hf_kdp_srcflowid, |
302 | 14 | { "SrcFlowID", "kdp.srcflowid", |
303 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} |
304 | 14 | }, |
305 | 14 | { &hf_kdp_sequence, |
306 | 14 | { "Sequence", "kdp.sequence", |
307 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} |
308 | 14 | }, |
309 | 14 | { &hf_kdp_ack, |
310 | 14 | { "Ack", "kdp.ack", |
311 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} |
312 | 14 | }, |
313 | 14 | { &hf_kdp_maxsegmentsize, |
314 | 14 | { "MaxSegmentSize", "kdp.maxsegmentsize", |
315 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} |
316 | 14 | }, |
317 | 14 | { &hf_kdp_optionnumber, |
318 | 14 | { "Option Number", "kdp.optionnumber", |
319 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} |
320 | 14 | }, |
321 | 14 | { &hf_kdp_optionlen, |
322 | 14 | { "Option Len", "kdp.option", |
323 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} |
324 | 14 | }, |
325 | 14 | { &hf_kdp_option1, |
326 | 14 | { "Option1 - Max Window", "kdp.option1", |
327 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
328 | 14 | }, |
329 | 14 | { &hf_kdp_option2, |
330 | 14 | { "Option2 - TCP Fraction", "kdp.option2", |
331 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
332 | 14 | }, |
333 | 14 | { &hf_kdp_option3, |
334 | 14 | { "Option3 - KDP Version", "kdp.option3", |
335 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
336 | 14 | }, |
337 | 14 | { &hf_kdp_option4, |
338 | 14 | { "Option4 - Enable Reliable", "kdp.option4", |
339 | 14 | FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL} |
340 | 14 | }, |
341 | 14 | { &hf_kdp_option5, |
342 | 14 | { "Option5 - Disable Reliable", "kdp.option5", |
343 | 14 | FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL} |
344 | 14 | }, |
345 | 14 | { &hf_kdp_option6, |
346 | 14 | { "Option6 - SACK", "kdp.option6", |
347 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} |
348 | 14 | }, |
349 | 14 | { &hf_kdp_option7, |
350 | 14 | { "Option7 - COS", "kdp.option7", |
351 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
352 | 14 | }, |
353 | 14 | { &hf_kdp_option8, |
354 | 14 | { "Option8 - BWMIN", "kdp.option8", |
355 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
356 | 14 | }, |
357 | 14 | { &hf_kdp_option9, |
358 | 14 | { "Option9 - INT", "kdp.option9", |
359 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
360 | 14 | }, |
361 | 14 | { &hf_kdp_option_unknown, |
362 | 14 | { "Unknown option", "kdp.option_unknown", |
363 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} |
364 | 14 | }, |
365 | 14 | { &hf_kdp_fragment, |
366 | 14 | { "Fragment", "kdp.fragment", |
367 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
368 | 14 | }, |
369 | 14 | { &hf_kdp_fragtotal, |
370 | 14 | { "FragTotal", "kdp.fragtotal", |
371 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} |
372 | 14 | }, |
373 | 14 | { &hf_kdp_body, |
374 | 14 | { "Encrypted Body", "kdp.body", |
375 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} |
376 | 14 | }, |
377 | 14 | { &hf_kdp_xml_body, |
378 | 14 | { "XML Body", "kdp.xml_body", |
379 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} |
380 | 14 | } |
381 | 14 | }; |
382 | | |
383 | | /* Setup protocol subtree array */ |
384 | 14 | static int *ett[] = { |
385 | 14 | &ett_kdp, &ett_kdp_flags |
386 | 14 | }; |
387 | | |
388 | 14 | proto_kdp = proto_register_protocol("Kontiki Delivery Protocol", "KDP", "kdp"); /* name, short name, abbreviation */ |
389 | 14 | proto_register_field_array(proto_kdp, hf, array_length(hf)); |
390 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
391 | | |
392 | 14 | kdp_handle = register_dissector("kdp", dissect_kdp, proto_kdp); |
393 | 14 | } |
394 | | |
395 | | void |
396 | 14 | proto_reg_handoff_kdp(void) { |
397 | 14 | dissector_add_uint_with_preference("udp.port", KDP_PORT, kdp_handle); |
398 | 14 | } |
399 | | |
400 | | /* |
401 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
402 | | * |
403 | | * Local Variables: |
404 | | * c-basic-offset: 2 |
405 | | * tab-width: 8 |
406 | | * indent-tabs-mode: nil |
407 | | * End: |
408 | | * |
409 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
410 | | * :indentSize=2:tabSize=8:noTabs=true: |
411 | | */ |