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
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);
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
;
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" },
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" },
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
;
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
);
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
,
131 length
= tvb_captured_length_remaining(tvb
, offset
);
134 reported_length
= tvb_reported_length_remaining(tvb
, offset
);
135 if (reported_length
> sublen
)
136 reported_length
= sublen
;
138 dissect_rpl_container(tvb_new_subset_length_caplen(tvb
,
139 offset
, length
, reported_length
),
140 pinfo
, rpl_container_tree
);
141 offset
+= reported_length
;
143 /* no more data, exit the loop */
144 offset
+= reported_length
;
151 proto_tree_add_item(tree
, hf_rpl_corrval
,
152 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
157 proto_tree_add_item(tree
, hf_rpl_lmac
,
158 tvb
, offset
, 6, ENC_NA
);
163 proto_tree_add_item(tree
, hf_rpl_sap
,
164 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
169 proto_tree_add_item(tree
, hf_rpl_maxframe
,
170 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
175 proto_tree_add_item(tree
, hf_rpl_connclass
,
176 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
181 proto_tree_add_item(tree
, hf_rpl_respval
,
182 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
187 proto_tree_add_item(tree
, hf_rpl_smac
,
188 tvb
, offset
, 6, ENC_NA
);
193 proto_tree_add_item(tree
, hf_rpl_sequence
,
194 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
199 proto_tree_add_item(tree
, hf_rpl_data
,
200 tvb
, offset
, len
-4, ENC_NA
);
205 proto_tree_add_item(tree
, hf_rpl_config
,
206 tvb
, offset
, 8, ENC_NA
);
208 proto_tree_add_item(tree
, hf_rpl_equipment
,
209 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
211 proto_tree_add_item(tree
, hf_rpl_memsize
,
212 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
214 proto_tree_add_item(tree
, hf_rpl_bsmversion
,
215 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
217 proto_tree_add_item(tree
, hf_rpl_ec
,
218 tvb
, offset
, 6, ENC_NA
);
220 proto_tree_add_item(tree
, hf_rpl_adapterid
,
221 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
223 proto_tree_add_item(tree
, hf_rpl_shortname
,
224 tvb
, offset
, 10, ENC_NA
);
229 proto_tree_add_item(tree
, hf_rpl_laddress
,
230 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
232 proto_tree_add_item(tree
, hf_rpl_xaddress
,
233 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
235 proto_tree_add_item(tree
, hf_rpl_flags
,
236 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
241 call_data_dissector(tvb_new_subset_remaining(tvb
, 4), pinfo
,
245 if (tvb_reported_length(tvb
) > offset
)
246 call_data_dissector(tvb_new_subset_remaining(tvb
, offset
), pinfo
, tree
);
250 dissect_rpl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
252 uint16_t rpl_len
, rpl_type
;
254 proto_tree
*rpl_tree
;
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,
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
,
276 return tvb_captured_length(tvb
);
280 proto_register_rpl(void)
282 static hf_register_info hf
[] = {
284 { "Type", "rpl.type",
285 FT_UINT16
, BASE_DEC
, VALS(rpl_type_vals
), 0x0,
286 "RPL Packet Type", HFILL
}},
288 { "Length", "rpl.len",
289 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
290 "RPL Packet Length", HFILL
}},
292 { "Correlator Value", "rpl.corrval",
293 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
294 "RPL Correlator Value", HFILL
}},
296 { "Response Code", "rpl.respval",
297 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
298 "RPL Response Code", HFILL
}},
300 { "Maximum Frame Size", "rpl.maxframe",
301 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
302 "RPL Maximum Frame Size", HFILL
}},
304 { "Connection Class", "rpl.connclass",
305 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
306 "RPL Connection Class", HFILL
}},
308 { "Loader MAC Address", "rpl.lmac",
309 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
310 "RPL Loader MAC Address", HFILL
}},
312 { "Set MAC Address", "rpl.smac",
313 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
314 "RPL Set MAC Address", HFILL
}},
317 FT_UINT8
, BASE_HEX
, VALS(sap_vals
), 0x0,
320 { "Equipment", "rpl.equipment",
321 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
322 "RPL Equipment - AX from INT 11h", HFILL
}},
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
}},
332 { "Adapter ID", "rpl.adapterid",
333 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
334 "RPL Adapter ID", HFILL
}},
336 { "Short Name", "rpl.shortname",
337 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
338 "RPL BSM Short Name", HFILL
}},
340 { "Locate Address", "rpl.laddress",
341 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
342 "RPL Locate Address", HFILL
}},
344 { "XFER Address", "rpl.xaddress",
345 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
346 "RPL Transfer Control Address", HFILL
}},
348 { "Sequence Number", "rpl.sequence",
349 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
350 "RPL Sequence Number", HFILL
}},
352 { "Configuration", "rpl.config",
353 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
354 "RPL Configuration", HFILL
}},
356 { "Flags", "rpl.flags",
357 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
358 "RPL Bit Significant Option Flags", HFILL
}},
360 { "Data", "rpl.data",
361 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
362 "RPL Binary File Data", HFILL
}},
365 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
369 static int *ett
[] = {
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
);
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
405 * indent-tabs-mode: t
408 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
409 * :indentSize=8:tabSize=8:noTabs=false: