epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-rpl.c
blobe76d601f596a3942dacfba2319a39d5a01b9ece6
1 /* packet-rpl.c
2 * Routines for RPL
3 * Jochen Friedrich <jochen@scram.de>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
16 #include <epan/llcsaps.h>
17 #include "packet-llc.h"
19 void proto_register_rpl(void);
20 void proto_reg_handoff_rpl(void);
22 static int proto_rpl;
24 static int hf_rpl_type;
25 static int hf_rpl_len;
26 static int hf_rpl_corrval;
27 static int hf_rpl_respval;
28 static int hf_rpl_maxframe;
29 static int hf_rpl_connclass;
30 static int hf_rpl_lmac;
31 static int hf_rpl_smac;
32 static int hf_rpl_sap;
33 static int hf_rpl_equipment;
34 static int hf_rpl_memsize;
35 static int hf_rpl_bsmversion;
36 static int hf_rpl_adapterid;
37 static int hf_rpl_shortname;
38 static int hf_rpl_laddress;
39 static int hf_rpl_xaddress;
40 static int hf_rpl_sequence;
41 static int hf_rpl_config;
42 static int hf_rpl_flags;
43 static int hf_rpl_data;
44 static int hf_rpl_ec;
46 static int ett_rpl;
47 static int ett_rpl_0004;
48 static int ett_rpl_0008;
49 static int ett_rpl_4003;
50 static int ett_rpl_4006;
51 static int ett_rpl_4007;
52 static int ett_rpl_4009;
53 static int ett_rpl_400a;
54 static int ett_rpl_400b;
55 static int ett_rpl_400c;
56 static int ett_rpl_4011;
57 static int ett_rpl_4018;
58 static int ett_rpl_c005;
59 static int ett_rpl_c014;
60 static int ett_rpl_unkn;
62 static dissector_handle_t rpl_handle;
64 static const value_string rpl_type_vals[] = {
65 { 1, "FIND Command" },
66 { 2, "FOUND Frame" },
67 { 4, "Search Vector" },
68 { 8, "Connect Info Vector" },
69 { 0x10, "Send File Request" },
70 { 0x20, "File Data Response" },
71 { 0x4003, "Correlator Vector" },
72 { 0x4006, "Loader Address Vector" },
73 { 0x4007, "Loader SAP Vector" },
74 { 0x4009, "Frame Size Sub-Vector" },
75 { 0x400a, "Connect Class Sub-Vector" },
76 { 0x400b, "Response Correlator" },
77 { 0x400c, "Set Address Vector" },
78 { 0x4011, "Sequence Header" },
79 { 0x4018, "File Data Vector" },
80 { 0xc005, "Loader Info Sub-Vector" },
81 { 0xc014, "Loader Header" },
82 { 0x0, NULL }
85 static void
86 // NOLINTNEXTLINE(misc-no-recursion)
87 dissect_rpl_container(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
89 uint16_t len, type, sublen, subtyp;
90 proto_tree *rpl_container_tree;
91 uint16_t offset;
92 int ett_type;
93 int length, reported_length;
95 len = tvb_get_ntohs(tvb, 0);
96 proto_tree_add_item(tree, hf_rpl_len, tvb, 0, 2, ENC_BIG_ENDIAN);
98 type = tvb_get_ntohs(tvb, 2);
99 proto_tree_add_item(tree, hf_rpl_type, tvb, 2, 2, ENC_BIG_ENDIAN);
100 offset = 4;
102 switch (type) {
103 case 1:
104 case 2:
105 case 4:
106 case 8:
107 case 0x10:
108 case 0x20:
109 while (len >= offset+4) {
110 sublen = tvb_get_ntohs(tvb, offset);
111 subtyp = tvb_get_ntohs(tvb, offset+2);
112 ett_type = ett_rpl_unkn;
113 if(subtyp == 0x0004) ett_type = ett_rpl_0004;
114 if(subtyp == 0x0008) ett_type = ett_rpl_0008;
115 if(subtyp == 0x4003) ett_type = ett_rpl_4003;
116 if(subtyp == 0x4006) ett_type = ett_rpl_4006;
117 if(subtyp == 0x4007) ett_type = ett_rpl_4007;
118 if(subtyp == 0x4009) ett_type = ett_rpl_4009;
119 if(subtyp == 0x400a) ett_type = ett_rpl_400a;
120 if(subtyp == 0x400b) ett_type = ett_rpl_400b;
121 if(subtyp == 0x400c) ett_type = ett_rpl_400c;
122 if(subtyp == 0x4011) ett_type = ett_rpl_4011;
123 if(subtyp == 0x4018) ett_type = ett_rpl_4018;
124 if(subtyp == 0xc005) ett_type = ett_rpl_c005;
125 if(subtyp == 0xc014) ett_type = ett_rpl_c014;
126 rpl_container_tree = proto_tree_add_subtree(tree, tvb,
127 offset, sublen, ett_type, NULL,
128 val_to_str_const(subtyp,
129 rpl_type_vals,
130 "Unknown Type"));
131 length = tvb_captured_length_remaining(tvb, offset);
132 if (length > sublen)
133 length = sublen;
134 reported_length = tvb_reported_length_remaining(tvb, offset);
135 if (reported_length > sublen)
136 reported_length = sublen;
137 if ( length > 0) {
138 dissect_rpl_container(tvb_new_subset_length_caplen(tvb,
139 offset, length, reported_length),
140 pinfo, rpl_container_tree);
141 offset += reported_length;
142 } else {
143 /* no more data, exit the loop */
144 offset += reported_length;
145 break;
148 break;
150 case 0x4003:
151 proto_tree_add_item(tree, hf_rpl_corrval,
152 tvb, offset, 4, ENC_BIG_ENDIAN);
153 offset += 4;
154 break;
156 case 0x4006:
157 proto_tree_add_item(tree, hf_rpl_lmac,
158 tvb, offset, 6, ENC_NA);
159 offset += 6;
160 break;
162 case 0x4007:
163 proto_tree_add_item(tree, hf_rpl_sap,
164 tvb, offset, 1, ENC_BIG_ENDIAN);
165 offset ++;
166 break;
168 case 0x4009:
169 proto_tree_add_item(tree, hf_rpl_maxframe,
170 tvb, offset, 2, ENC_BIG_ENDIAN);
171 offset += 2;
172 break;
174 case 0x400a:
175 proto_tree_add_item(tree, hf_rpl_connclass,
176 tvb, offset, 2, ENC_BIG_ENDIAN);
177 offset += 2;
178 break;
180 case 0x400b:
181 proto_tree_add_item(tree, hf_rpl_respval,
182 tvb, offset, 1, ENC_BIG_ENDIAN);
183 offset ++;
184 break;
186 case 0x400c:
187 proto_tree_add_item(tree, hf_rpl_smac,
188 tvb, offset, 6, ENC_NA);
189 offset += 6;
190 break;
192 case 0x4011:
193 proto_tree_add_item(tree, hf_rpl_sequence,
194 tvb, offset, 4, ENC_BIG_ENDIAN);
195 offset += 4;
196 break;
198 case 0x4018:
199 proto_tree_add_item(tree, hf_rpl_data,
200 tvb, offset, len-4, ENC_NA);
201 offset += len - 4;
202 break;
204 case 0xc005:
205 proto_tree_add_item(tree, hf_rpl_config,
206 tvb, offset, 8, ENC_NA);
207 offset += 8;
208 proto_tree_add_item(tree, hf_rpl_equipment,
209 tvb, offset, 2, ENC_BIG_ENDIAN);
210 offset += 2;
211 proto_tree_add_item(tree, hf_rpl_memsize,
212 tvb, offset, 2, ENC_BIG_ENDIAN);
213 offset += 2;
214 proto_tree_add_item(tree, hf_rpl_bsmversion,
215 tvb, offset, 2, ENC_BIG_ENDIAN);
216 offset += 2;
217 proto_tree_add_item(tree, hf_rpl_ec,
218 tvb, offset, 6, ENC_NA);
219 offset += 6;
220 proto_tree_add_item(tree, hf_rpl_adapterid,
221 tvb, offset, 2, ENC_BIG_ENDIAN);
222 offset += 2;
223 proto_tree_add_item(tree, hf_rpl_shortname,
224 tvb, offset, 10, ENC_NA);
225 offset += 10;
226 break;
228 case 0xc014:
229 proto_tree_add_item(tree, hf_rpl_laddress,
230 tvb, offset, 4, ENC_BIG_ENDIAN);
231 offset += 4;
232 proto_tree_add_item(tree, hf_rpl_xaddress,
233 tvb, offset, 4, ENC_BIG_ENDIAN);
234 offset += 4;
235 proto_tree_add_item(tree, hf_rpl_flags,
236 tvb, offset, 1, ENC_BIG_ENDIAN);
237 offset ++;
238 break;
240 default:
241 call_data_dissector(tvb_new_subset_remaining(tvb, 4), pinfo,
242 tree);
243 break;
245 if (tvb_reported_length(tvb) > offset)
246 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
249 static int
250 dissect_rpl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
252 uint16_t rpl_len, rpl_type;
253 proto_item *ti;
254 proto_tree *rpl_tree;
255 tvbuff_t *next_tvb;
257 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPL");
259 rpl_len = tvb_get_ntohs(tvb, 0);
260 rpl_type = tvb_get_ntohs(tvb, 2);
262 col_set_str(pinfo->cinfo, COL_INFO,
263 val_to_str_const(rpl_type, rpl_type_vals, "Unknown Type"));
265 ti = proto_tree_add_item(tree, proto_rpl, tvb, 0,
266 rpl_len, ENC_NA);
267 rpl_tree = proto_item_add_subtree(ti, ett_rpl);
268 next_tvb = tvb_new_subset_remaining(tvb, 0);
269 set_actual_length(next_tvb, rpl_len);
270 dissect_rpl_container(next_tvb, pinfo, rpl_tree);
272 if (tvb_reported_length(tvb) > rpl_len)
273 call_data_dissector(tvb_new_subset_remaining(tvb, rpl_len), pinfo,
274 tree);
276 return tvb_captured_length(tvb);
279 void
280 proto_register_rpl(void)
282 static hf_register_info hf[] = {
283 { &hf_rpl_type,
284 { "Type", "rpl.type",
285 FT_UINT16, BASE_DEC, VALS(rpl_type_vals), 0x0,
286 "RPL Packet Type", HFILL }},
287 { &hf_rpl_len,
288 { "Length", "rpl.len",
289 FT_UINT16, BASE_DEC, NULL, 0x0,
290 "RPL Packet Length", HFILL }},
291 { &hf_rpl_corrval,
292 { "Correlator Value", "rpl.corrval",
293 FT_UINT32, BASE_HEX, NULL, 0x0,
294 "RPL Correlator Value", HFILL }},
295 { &hf_rpl_respval,
296 { "Response Code", "rpl.respval",
297 FT_UINT8, BASE_DEC, NULL, 0x0,
298 "RPL Response Code", HFILL }},
299 { &hf_rpl_maxframe,
300 { "Maximum Frame Size", "rpl.maxframe",
301 FT_UINT16, BASE_DEC, NULL, 0x0,
302 "RPL Maximum Frame Size", HFILL }},
303 { &hf_rpl_connclass,
304 { "Connection Class", "rpl.connclass",
305 FT_UINT16, BASE_HEX, NULL, 0x0,
306 "RPL Connection Class", HFILL }},
307 { &hf_rpl_lmac,
308 { "Loader MAC Address", "rpl.lmac",
309 FT_ETHER, BASE_NONE, NULL, 0x0,
310 "RPL Loader MAC Address", HFILL }},
311 { &hf_rpl_smac,
312 { "Set MAC Address", "rpl.smac",
313 FT_ETHER, BASE_NONE, NULL, 0x0,
314 "RPL Set MAC Address", HFILL }},
315 { &hf_rpl_sap,
316 { "SAP", "rpl.sap",
317 FT_UINT8, BASE_HEX, VALS(sap_vals), 0x0,
318 "RPL SAP", HFILL }},
319 { &hf_rpl_equipment,
320 { "Equipment", "rpl.equipment",
321 FT_UINT16, BASE_HEX, NULL, 0x0,
322 "RPL Equipment - AX from INT 11h", HFILL }},
323 { &hf_rpl_memsize,
324 { "Memory Size", "rpl.memsize",
325 FT_UINT16, BASE_DEC, NULL, 0x0,
326 "RPL Memory Size - AX from INT 12h MINUS 32k MINUS the Boot ROM Size", HFILL }},
327 { &hf_rpl_bsmversion,
328 { "BSM Version", "rpl.bsmversion",
329 FT_UINT16, BASE_HEX, NULL, 0x0,
330 "RPL Version of BSM.obj", HFILL }},
331 { &hf_rpl_adapterid,
332 { "Adapter ID", "rpl.adapterid",
333 FT_UINT16, BASE_HEX, NULL, 0x0,
334 "RPL Adapter ID", HFILL }},
335 { &hf_rpl_shortname,
336 { "Short Name", "rpl.shortname",
337 FT_BYTES, BASE_NONE, NULL, 0x0,
338 "RPL BSM Short Name", HFILL }},
339 { &hf_rpl_laddress,
340 { "Locate Address", "rpl.laddress",
341 FT_UINT32, BASE_HEX, NULL, 0x0,
342 "RPL Locate Address", HFILL }},
343 { &hf_rpl_xaddress,
344 { "XFER Address", "rpl.xaddress",
345 FT_UINT32, BASE_HEX, NULL, 0x0,
346 "RPL Transfer Control Address", HFILL }},
347 { &hf_rpl_sequence,
348 { "Sequence Number", "rpl.sequence",
349 FT_UINT32, BASE_HEX, NULL, 0x0,
350 "RPL Sequence Number", HFILL }},
351 { &hf_rpl_config,
352 { "Configuration", "rpl.config",
353 FT_BYTES, BASE_NONE, NULL, 0x0,
354 "RPL Configuration", HFILL }},
355 { &hf_rpl_flags,
356 { "Flags", "rpl.flags",
357 FT_UINT8, BASE_HEX, NULL, 0x0,
358 "RPL Bit Significant Option Flags", HFILL }},
359 { &hf_rpl_data,
360 { "Data", "rpl.data",
361 FT_BYTES, BASE_NONE, NULL, 0x0,
362 "RPL Binary File Data", HFILL }},
363 { &hf_rpl_ec,
364 { "EC", "rpl.ec",
365 FT_BYTES, BASE_NONE, NULL, 0x0,
366 "RPL EC", HFILL }},
369 static int *ett[] = {
370 &ett_rpl,
371 &ett_rpl_0004,
372 &ett_rpl_0008,
373 &ett_rpl_4003,
374 &ett_rpl_4006,
375 &ett_rpl_4007,
376 &ett_rpl_4009,
377 &ett_rpl_400a,
378 &ett_rpl_400b,
379 &ett_rpl_400c,
380 &ett_rpl_4011,
381 &ett_rpl_4018,
382 &ett_rpl_c005,
383 &ett_rpl_c014,
384 &ett_rpl_unkn
387 proto_rpl = proto_register_protocol("Remote Program Load", "RPL", "rpl");
388 proto_register_field_array(proto_rpl, hf, array_length(hf));
389 proto_register_subtree_array(ett, array_length(ett));
390 rpl_handle = register_dissector("rpl", dissect_rpl, proto_rpl);
393 void
394 proto_reg_handoff_rpl(void)
396 dissector_add_uint("llc.dsap", SAP_RPL, rpl_handle);
400 * Editor modelines - https://www.wireshark.org/tools/modelines.html
402 * Local variables:
403 * c-basic-offset: 8
404 * tab-width: 8
405 * indent-tabs-mode: t
406 * End:
408 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
409 * :indentSize=8:tabSize=8:noTabs=false: