2 * Routines for parsing packetbb rfc 5444
3 * Parser created by Henning Rogge <henning.rogge@fkie.fraunhofer.de> of Fraunhover
4 * TLV values decoding by Francois Schneider <francois.schneider_@_airbus.com>
6 * https://tools.ietf.org/html/rfc5444
7 * https://tools.ietf.org/html/rfc5498
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include <epan/to_str.h>
21 #include <wsutil/array.h>
23 void proto_reg_handoff_packetbb(void);
24 void proto_register_packetbb(void);
26 static dissector_handle_t packetbb_handle
;
28 #define PACKET_HEADER_HASSEQNR 0x08
29 #define PACKET_HEADER_HASTLV 0x04
31 #define MSG_HEADER_HASORIG 0x80
32 #define MSG_HEADER_HASHOPLIMIT 0x40
33 #define MSG_HEADER_HASHOPCOUNT 0x20
34 #define MSG_HEADER_HASSEQNR 0x10
36 #define ADDR_HASHEAD 0x80
37 #define ADDR_HASFULLTAIL 0x40
38 #define ADDR_HASZEROTAIL 0x20
39 #define ADDR_HASSINGLEPRELEN 0x10
40 #define ADDR_HASMULTIPRELEN 0x08
42 #define TLV_HAS_TYPEEXT 0x80
43 #define TLV_HAS_SINGLEINDEX 0x40
44 #define TLV_HAS_MULTIINDEX 0x20
45 #define TLV_HAS_VALUE 0x10
46 #define TLV_HAS_EXTLEN 0x08
47 #define TLV_HAS_MULTIVALUE 0x04
49 #define MAX_ADDR_SIZE 16
51 #define PACKETBB_MSG_TLV_LENGTH (UINT8_MAX + 1)
53 #define TLV_CAT_PACKET 0
54 #define TLV_CAT_MESSAGE 1
55 #define TLV_CAT_ADDRESS 2
57 /* Generic address TLV defined by IANA in RFC5497 (timetlv) */
58 enum rfc5497_tlv_iana
{
59 RFC5497_TLV_INTERVAL_TIME
= 0,
60 RFC5497_TLV_VALIDITY_TIME
= 1
63 /* Generic address TLV defined by IANA in RFC6130 (NHDP) */
64 enum rfc6130_addrtlv_iana
{
65 RFC6130_ADDRTLV_LOCAL_IF
= 2,
66 RFC6130_ADDRTLV_LINK_STATUS
= 3,
67 RFC6130_ADDRTLV_OTHER_NEIGH
= 4
70 /* Generic address TLVs defined by IANA in RFC7182 (rfc5444-sec) */
71 enum rfc7182_tlv_iana
{
73 RFC7182_TLV_TIMESTAMP
= 6
76 /* Generic address TLV defined by IANA in RFC7181 (OLSRv2) */
77 enum rfc7181_addrtlv_iana
{
78 RFC7181_ADDRTLV_LINK_METRIC
= 7,
79 RFC7181_ADDRTLV_MPR
= 8,
80 RFC7181_ADDRTLV_NBR_ADDR_TYPE
= 9,
81 RFC7181_ADDRTLV_GATEWAY
= 10
84 /* Generic message TLV defined by IANA in RFC7181 (OLSRv2) */
85 enum rfc7181_msgtlvs_iana
{
86 RFC7181_MSGTLV_MPR_WILLING
= 7,
87 RFC7181_MSGTLV_CONT_SEQ_NUM
= 8
90 /* Bit-flags for LINK_METRIC address TLV */
91 enum rfc7181_linkmetric_flags
{
92 RFC7181_LINKMETRIC_INCOMING_LINK
= 1<<15,
93 RFC7181_LINKMETRIC_OUTGOING_LINK
= 1<<14,
94 RFC7181_LINKMETRIC_INCOMING_NEIGH
= 1<<13,
95 RFC7181_LINKMETRIC_OUTGOING_NEIGH
= 1<<12
98 /* Bit-flags for MPR address TLV */
99 enum rfc7181_mpr_bitmask
{
100 RFC7181_MPR_FLOODING
= 1,
101 RFC7181_MPR_ROUTING
= 2,
102 RFC7181_MPR_FLOOD_ROUTE
= 3
105 /* Message types defined by IANA in RFC5444 */
106 static const value_string msgheader_type_vals
[] = {
107 { 0, "HELLO (NHDP)" },
108 { 1, "TC (OLSRv2)" },
111 /* Packet TLV types defined by IANA in RFC7182 */
112 static const value_string pkttlv_type_vals
[] = {
113 { RFC7182_TLV_ICV
, "Integrity Check Value" },
114 { RFC7182_TLV_TIMESTAMP
, "Timestamp" },
117 /* Message TLV types defined by IANA in RFC5497,7181,7182 */
118 static const value_string msgtlv_type_vals
[] = {
119 { RFC5497_TLV_INTERVAL_TIME
, "Signaling message interval" },
120 { RFC5497_TLV_VALIDITY_TIME
, "Message validity time" },
121 { RFC7182_TLV_ICV
, "Integrity Check Value" },
122 { RFC7182_TLV_TIMESTAMP
, "Timestamp" },
123 { RFC7181_MSGTLV_MPR_WILLING
, "MPR willingness" },
124 { RFC7181_MSGTLV_CONT_SEQ_NUM
, "Content sequence number" },
127 /* Address TLV types defined by IANA in RFC5497,6130,7181,7182 */
128 static const value_string addrtlv_type_vals
[] = {
129 { RFC5497_TLV_INTERVAL_TIME
, "Signaling message interval" },
130 { RFC5497_TLV_VALIDITY_TIME
, "Message validity time" },
131 { RFC6130_ADDRTLV_LOCAL_IF
, "Local interface status" },
132 { RFC6130_ADDRTLV_LINK_STATUS
, "Link status" },
133 { RFC6130_ADDRTLV_OTHER_NEIGH
, "Other neighbor status" },
134 { RFC7182_TLV_ICV
, "Integrity Check Value" },
135 { RFC7182_TLV_TIMESTAMP
, "Timestamp" },
136 { RFC7181_ADDRTLV_LINK_METRIC
, "Link metric" },
137 { RFC7181_ADDRTLV_MPR
, "Multipoint Relay" },
138 { RFC7181_ADDRTLV_NBR_ADDR_TYPE
, "Neighbor address type" },
139 { RFC7181_ADDRTLV_GATEWAY
, "Gateway" },
142 /* Values of LOCALIF TLV of RFC6130 */
143 static const value_string localif_vals
[] = {
148 /* Values of LINKSTATUS TLV of RFC6130 */
149 static const value_string linkstatus_vals
[] = {
155 /* Values of OTHERNEIGH TLV of RFC6130 */
156 static const value_string otherneigh_vals
[] = {
161 /* Values of MPR TLV of RFC7181 */
162 static const value_string mpr_vals
[] = {
165 { 3, "FLOOD_ROUTE" },
168 /* Values of NBRADDRTYPE TLV of RFC7181 */
169 static const value_string nbraddrtype_vals
[] = {
172 { 3, "ROUTABLE_ORIG" },
175 static int proto_packetbb
;
177 #define PACKETBB_PORT 269 /* Not IANA registered */
179 static int hf_packetbb_header
;
180 static int hf_packetbb_version
;
181 static int hf_packetbb_header_flags
;
182 static int hf_packetbb_header_flags_phasseqnum
;
183 static int hf_packetbb_header_flags_phastlv
;
184 static int hf_packetbb_seqnr
;
185 static int hf_packetbb_msg
;
186 static int hf_packetbb_msgheader
;
187 static int hf_packetbb_msgheader_type
;
188 static int hf_packetbb_msgheader_flags
;
189 static int hf_packetbb_msgheader_flags_mhasorig
;
190 static int hf_packetbb_msgheader_flags_mhashoplimit
;
191 static int hf_packetbb_msgheader_flags_mhashopcount
;
192 static int hf_packetbb_msgheader_flags_mhasseqnr
;
193 static int hf_packetbb_msgheader_addresssize
;
194 static int hf_packetbb_msgheader_size
;
195 static int hf_packetbb_msgheader_origaddripv4
;
196 static int hf_packetbb_msgheader_origaddripv6
;
197 static int hf_packetbb_msgheader_origaddrmac
;
198 static int hf_packetbb_msgheader_origaddrcustom
;
199 static int hf_packetbb_msgheader_hoplimit
;
200 static int hf_packetbb_msgheader_hopcount
;
201 static int hf_packetbb_msgheader_seqnr
;
202 static int hf_packetbb_addr
;
203 static int hf_packetbb_addr_num
;
204 static int hf_packetbb_addr_flags
;
205 static int hf_packetbb_addr_flags_hashead
;
206 static int hf_packetbb_addr_flags_hasfulltail
;
207 static int hf_packetbb_addr_flags_haszerotail
;
208 static int hf_packetbb_addr_flags_hassingleprelen
;
209 static int hf_packetbb_addr_flags_hasmultiprelen
;
210 static int hf_packetbb_addr_head
;
211 static int hf_packetbb_addr_tail
;
212 static int hf_packetbb_addr_value
[4];
213 static int hf_packetbb_addr_value_mid
;
214 static int hf_packetbb_addr_value_prefix
;
215 static int hf_packetbb_tlvblock
;
216 static int hf_packetbb_tlvblock_length
;
217 static int hf_packetbb_tlv
;
218 static int hf_packetbb_pkttlv_type
;
219 static int hf_packetbb_msgtlv_type
;
220 static int hf_packetbb_addrtlv_type
;
221 static int hf_packetbb_tlv_flags
;
222 static int hf_packetbb_tlv_flags_hastypext
;
223 static int hf_packetbb_tlv_flags_hassingleindex
;
224 static int hf_packetbb_tlv_flags_hasmultiindex
;
225 static int hf_packetbb_tlv_flags_hasvalue
;
226 static int hf_packetbb_tlv_flags_hasextlen
;
227 static int hf_packetbb_tlv_flags_hasmultivalue
;
228 static int hf_packetbb_tlv_typeext
;
229 static int hf_packetbb_tlv_indexstart
;
230 static int hf_packetbb_tlv_indexend
;
231 static int hf_packetbb_tlv_length
;
232 static int hf_packetbb_tlv_value
;
233 static int hf_packetbb_tlv_multivalue
;
234 static int hf_packetbb_tlv_intervaltime
;
235 static int hf_packetbb_tlv_validitytime
;
236 static int hf_packetbb_tlv_localifs
;
237 static int hf_packetbb_tlv_linkstatus
;
238 static int hf_packetbb_tlv_otherneigh
;
239 static int hf_packetbb_tlv_icv
;
240 static int hf_packetbb_tlv_timestamp
;
241 static int hf_packetbb_tlv_linkmetric_flags_linkin
;
242 static int hf_packetbb_tlv_linkmetric_flags_linkout
;
243 static int hf_packetbb_tlv_linkmetric_flags_neighin
;
244 static int hf_packetbb_tlv_linkmetric_flags_neighout
;
245 static int hf_packetbb_tlv_linkmetric_value
;
246 static int hf_packetbb_tlv_mpr
;
247 static int hf_packetbb_tlv_nbraddrtype
;
248 static int hf_packetbb_tlv_gateway
;
249 static int hf_packetbb_tlv_mprwillingness
;
250 static int hf_packetbb_tlv_mprwillingness_flooding
;
251 static int hf_packetbb_tlv_mprwillingness_routing
;
252 static int hf_packetbb_tlv_contseqnum
;
254 static int ett_packetbb
;
255 static int ett_packetbb_header
;
256 static int ett_packetbb_header_flags
;
257 static int ett_packetbb_msg
[PACKETBB_MSG_TLV_LENGTH
];
258 static int ett_packetbb_msgheader
;
259 static int ett_packetbb_msgheader_flags
;
260 static int ett_packetbb_addr
;
261 static int ett_packetbb_addr_flags
;
262 static int ett_packetbb_addr_value
;
263 static int ett_packetbb_tlvblock
;
264 static int ett_packetbb_tlv
[PACKETBB_MSG_TLV_LENGTH
];
265 static int ett_packetbb_tlv_flags
;
266 static int ett_packetbb_tlv_value
;
267 static int ett_packetbb_tlv_mprwillingness
;
268 static int ett_packetbb_tlv_linkmetric
;
270 static expert_field ei_packetbb_error
;
272 /* Link metric of RFC7181 */
273 static uint32_t uncompress_metric(uint16_t val16
) {
274 uint8_t exp
= (val16
>> 8) & 0xf;
275 return (uint32_t)((((uint16_t)257U + (val16
& 0xff)) << exp
) - 256);
278 /* Time metric of RFC5497 */
279 static uint32_t uncompress_time(uint8_t val8
) {
280 uint8_t exp
= val8
>> 3;
281 float mant
= (float)(val8
& 0x07);
282 return (uint32_t)((1.00 + mant
/ 8) * (1U << exp
));
285 static proto_item
* dissect_pbb_tlvvalue(tvbuff_t
*tvb
, proto_tree
*tlvTree
, unsigned offset
, unsigned len
, unsigned tlvCat
, unsigned tlvType
) {
286 proto_tree
*tlv_decoded_value_tree
= NULL
;
287 proto_tree
*tlv_decoded_value_item
= NULL
;
289 static int * const mprwillingness_values
[] = {
290 &hf_packetbb_tlv_mprwillingness_flooding
,
291 &hf_packetbb_tlv_mprwillingness_routing
,
296 case TLV_CAT_MESSAGE
:
298 if (tlvType
== RFC7181_MSGTLV_MPR_WILLING
) {
299 tlv_decoded_value_item
= proto_tree_add_bitmask(tlvTree
, tvb
, offset
, hf_packetbb_tlv_mprwillingness
, ett_packetbb_tlv_mprwillingness
, mprwillingness_values
, ENC_BIG_ENDIAN
);
302 else if (tlvType
== RFC7181_MSGTLV_CONT_SEQ_NUM
) {
303 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_contseqnum
, tvb
, offset
, len
, ENC_NA
);
307 /* other tlvTypes are common with categories PACKET and ADDRESS,
312 case TLV_CAT_ADDRESS
:
315 case RFC5497_TLV_INTERVAL_TIME
:
316 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_intervaltime
, tvb
, offset
, len
, ENC_NA
);
317 proto_item_append_text(tlv_decoded_value_item
, " (%d)", uncompress_time(tvb_get_uint8(tvb
, offset
)));
319 case RFC5497_TLV_VALIDITY_TIME
:
320 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_validitytime
, tvb
, offset
, len
, ENC_NA
);
321 proto_item_append_text(tlv_decoded_value_item
, " (%d)", uncompress_time(tvb_get_uint8(tvb
, offset
)));
323 case RFC6130_ADDRTLV_LOCAL_IF
:
324 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_localifs
, tvb
, offset
, 1, ENC_NA
);
326 case RFC6130_ADDRTLV_LINK_STATUS
:
327 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_linkstatus
, tvb
, offset
, 1, ENC_NA
);
329 case RFC6130_ADDRTLV_OTHER_NEIGH
:
330 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_otherneigh
, tvb
, offset
, 1, ENC_NA
);
332 case RFC7182_TLV_ICV
:
333 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_icv
, tvb
, offset
, len
, ENC_NA
);
335 case RFC7182_TLV_TIMESTAMP
:
336 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_timestamp
, tvb
, offset
, len
, ENC_NA
);
338 case RFC7181_ADDRTLV_LINK_METRIC
:
339 tlv_decoded_value_tree
= proto_tree_add_subtree(tlvTree
, tvb
, offset
, len
, ett_packetbb_tlv_linkmetric
, NULL
, "Link metric");
340 proto_tree_add_item(tlv_decoded_value_tree
, hf_packetbb_tlv_linkmetric_flags_linkin
, tvb
, offset
, 2, ENC_NA
);
341 proto_tree_add_item(tlv_decoded_value_tree
, hf_packetbb_tlv_linkmetric_flags_linkout
, tvb
, offset
, 2, ENC_NA
);
342 proto_tree_add_item(tlv_decoded_value_tree
, hf_packetbb_tlv_linkmetric_flags_neighin
, tvb
, offset
, 2, ENC_NA
);
343 proto_tree_add_item(tlv_decoded_value_tree
, hf_packetbb_tlv_linkmetric_flags_neighout
, tvb
, offset
, 2, ENC_NA
);
344 tlv_decoded_value_item
= proto_tree_add_item(tlv_decoded_value_tree
, hf_packetbb_tlv_linkmetric_value
, tvb
, offset
, 2, ENC_NA
);
345 proto_item_append_text(tlv_decoded_value_item
, " (%d)", uncompress_metric(tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
)));
347 case RFC7181_ADDRTLV_MPR
:
348 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_mpr
, tvb
, offset
, len
, ENC_NA
);
350 case RFC7181_ADDRTLV_NBR_ADDR_TYPE
:
351 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_nbraddrtype
, tvb
, offset
, len
, ENC_NA
);
353 case RFC7181_ADDRTLV_GATEWAY
:
354 tlv_decoded_value_item
= proto_tree_add_item(tlvTree
, hf_packetbb_tlv_gateway
, tvb
, offset
, len
, ENC_NA
);
358 return tlv_decoded_value_item
;
361 static int dissect_pbb_tlvblock(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
, unsigned maxoffset
, int8_t addrCount
, unsigned tlvCat
) {
362 uint16_t tlvblockLength
;
363 unsigned tlvblockEnd
;
365 proto_tree
*tlvblock_tree
, *tlv_tree
, *tlvValue_tree
;
366 proto_item
*tlvBlock_item
, *tlv_item
, *tlvValue_item
;
370 static int * const flags
[] = {
371 &hf_packetbb_tlv_flags_hastypext
,
372 &hf_packetbb_tlv_flags_hassingleindex
,
373 &hf_packetbb_tlv_flags_hasmultiindex
,
374 &hf_packetbb_tlv_flags_hasvalue
,
375 &hf_packetbb_tlv_flags_hasextlen
,
376 &hf_packetbb_tlv_flags_hasmultivalue
,
380 if (maxoffset
< offset
+ 2) {
381 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
382 "Not enough octets for minimal tlvblock");
386 tlvblockLength
= tvb_get_ntohs(tvb
, offset
);
388 tlvblockEnd
= offset
+ 2 + tlvblockLength
;
389 if (maxoffset
< tlvblockEnd
) {
390 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
391 "Not enough octets for tlvblock");
395 tlvBlock_item
= proto_tree_add_item(tree
, hf_packetbb_tlvblock
, tvb
, offset
, tlvblockEnd
- offset
, ENC_NA
);
396 tlvblock_tree
= proto_item_add_subtree(tlvBlock_item
, ett_packetbb_tlvblock
);
398 proto_tree_add_item(tlvblock_tree
, hf_packetbb_tlvblock_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
401 while (offset
< tlvblockEnd
) {
402 unsigned tlvStart
, tlvLength
;
403 uint8_t tlvType
, tlvFlags
, /*tlvExtType, */indexStart
, indexEnd
;
405 int hf_packetbb_tlv_type
= 0;
406 const value_string
*tlv_type_vals
;
409 tlvType
= tvb_get_uint8(tvb
, offset
++);
410 tlvFlags
= tvb_get_uint8(tvb
, offset
++);
412 if ((tlvFlags
& TLV_HAS_TYPEEXT
) != 0) {
413 /* skip over ext-type */
418 indexEnd
= addrCount
? (addrCount
- 1) : 0;
420 if ((tlvFlags
& TLV_HAS_SINGLEINDEX
) != 0) {
421 indexStart
= indexEnd
= tvb_get_uint8(tvb
, offset
++);
423 else if ((tlvFlags
& TLV_HAS_MULTIINDEX
) != 0) {
424 indexStart
= tvb_get_uint8(tvb
, offset
++);
425 indexEnd
= tvb_get_uint8(tvb
, offset
++);
428 if ((tlvFlags
& TLV_HAS_VALUE
) != 0) {
429 if ((tlvFlags
& TLV_HAS_EXTLEN
) != 0) {
430 length
= tvb_get_ntohs(tvb
, offset
);
434 length
= tvb_get_uint8(tvb
, offset
++);
438 tlvLength
= offset
- tlvStart
+ length
;
441 tlv_item
= proto_tree_add_item(tlvBlock_item
, hf_packetbb_tlv
, tvb
, tlvStart
, tlvLength
, ENC_NA
);
442 tlv_tree
= proto_item_add_subtree(tlv_item
, ett_packetbb_tlv
[tlvType
]);
444 /* select possible strings for tlvType */
445 if (tlvCat
== TLV_CAT_PACKET
) {
446 hf_packetbb_tlv_type
= hf_packetbb_pkttlv_type
;
447 tlv_type_vals
= pkttlv_type_vals
;
449 else if (tlvCat
== TLV_CAT_MESSAGE
) {
450 hf_packetbb_tlv_type
= hf_packetbb_msgtlv_type
;
451 tlv_type_vals
= msgtlv_type_vals
;
454 /* assume TLV_CAT_ADDRESS */
455 hf_packetbb_tlv_type
= hf_packetbb_addrtlv_type
;
456 tlv_type_vals
= addrtlv_type_vals
;
460 proto_tree_add_item(tlv_tree
, hf_packetbb_tlv_type
, tvb
, offset
++, 1, ENC_BIG_ENDIAN
);
463 proto_tree_add_bitmask(tlv_tree
, tvb
, offset
, hf_packetbb_tlv_flags
, ett_packetbb_tlv_flags
, flags
, ENC_BIG_ENDIAN
);
466 if ((tlvFlags
& TLV_HAS_TYPEEXT
) != 0) {
468 proto_tree_add_item(tlv_tree
, hf_packetbb_tlv_typeext
, tvb
, offset
++, 1, ENC_BIG_ENDIAN
);
472 /* add index values */
473 if ((tlvFlags
& TLV_HAS_SINGLEINDEX
) != 0) {
474 proto_tree_add_uint(tlv_tree
, hf_packetbb_tlv_indexstart
, tvb
, offset
++, 1, indexStart
);
476 proto_tree_add_uint_format_value(tlv_tree
, hf_packetbb_tlv_indexend
, tvb
, offset
, 0, indexEnd
, "%d (implicit)", indexEnd
);
478 else if ((tlvFlags
& TLV_HAS_MULTIINDEX
) != 0) {
479 proto_tree_add_uint(tlv_tree
, hf_packetbb_tlv_indexstart
, tvb
, offset
++, 1, indexStart
);
480 proto_tree_add_uint(tlv_tree
, hf_packetbb_tlv_indexend
, tvb
, offset
++, 1, indexEnd
);
483 proto_tree_add_uint_format_value(tlv_tree
, hf_packetbb_tlv_indexstart
, tvb
, offset
, 0, indexStart
, "%d (implicit)", indexStart
);
484 proto_tree_add_uint_format_value(tlv_tree
, hf_packetbb_tlv_indexend
, tvb
, offset
, 0, indexEnd
, "%d (implicit)", indexEnd
);
489 if ((tlvFlags
& TLV_HAS_VALUE
) != 0) {
490 if ((tlvFlags
& TLV_HAS_EXTLEN
) != 0) {
491 proto_tree_add_uint(tlv_tree
, hf_packetbb_tlv_length
, tvb
, offset
, 2, length
);
495 proto_tree_add_uint(tlv_tree
, hf_packetbb_tlv_length
, tvb
, offset
++, 1, length
);
499 proto_tree_add_uint_format_value(tlv_tree
, hf_packetbb_tlv_length
, tvb
, offset
, 0, 0, "0 (implicit)");
504 tlvValue_item
= proto_tree_add_item(tlv_tree
, hf_packetbb_tlv_value
, tvb
, offset
, length
, ENC_NA
);
505 if ((tlvFlags
& TLV_HAS_MULTIVALUE
) == 0) {
507 dissect_pbb_tlvvalue(tvb
, tlv_tree
, offset
, length
, tlvCat
, tlvType
);
511 /* multiple values */
513 unsigned c
= indexEnd
- indexStart
+ 1;
515 tlvValue_tree
= proto_item_add_subtree(tlvValue_item
, ett_packetbb_tlv_value
);
517 for (i
=indexStart
; i
<=indexEnd
; i
++) {
518 proto_tree_add_item(tlvValue_tree
, hf_packetbb_tlv_multivalue
, tvb
, offset
, length
/c
, ENC_NA
);
519 offset
+= (length
/c
);
526 proto_item_append_text(tlv_item
, " (t=%d,l=%d): %s", tlvType
, length
, val_to_str(tlvType
, tlv_type_vals
, "Unknown Type (%d)") );
531 proto_item_append_text(tlvBlock_item
, " (%d TLVs)", tlvCount
);
536 static int dissect_pbb_addressblock(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
, unsigned maxoffset
,
537 uint8_t addressType
, uint8_t addressSize
) {
538 uint8_t addr
[MAX_ADDR_SIZE
];
541 uint8_t address_flags
;
542 uint8_t head_length
= 0, tail_length
= 0;
543 unsigned block_length
= 0, midSize
= 0;
544 unsigned block_index
= 0, head_index
= 0, tail_index
= 0, mid_index
= 0, prefix_index
= 0;
546 proto_tree
*addr_tree
= NULL
;
547 proto_tree
*addrValue_tree
= NULL
;
549 proto_item
*addr_item
= NULL
;
550 proto_item
*addrValue_item
= NULL
;
554 static int * const flags
[] = {
555 &hf_packetbb_addr_flags_hashead
,
556 &hf_packetbb_addr_flags_hasfulltail
,
557 &hf_packetbb_addr_flags_haszerotail
,
558 &hf_packetbb_addr_flags_hassingleprelen
,
559 &hf_packetbb_addr_flags_hasmultiprelen
,
563 if (maxoffset
- offset
< 2) {
564 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
565 "Not enough octets for minimal addressblock header");
566 return tvb_reported_length(tvb
);
569 DISSECTOR_ASSERT(addressSize
<= MAX_ADDR_SIZE
);
571 memset(addr
, 0, addressSize
);
574 block_index
= offset
;
575 midSize
= addressSize
;
577 numAddr
= tvb_get_uint8(tvb
, offset
++);
578 address_flags
= tvb_get_uint8(tvb
, offset
++);
580 if ((address_flags
& ADDR_HASHEAD
) != 0) {
583 if (maxoffset
- offset
<= 0) {
584 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
585 "Not enough octets for addressblock head");
586 return tvb_reported_length(tvb
);
588 head_length
= tvb_get_uint8(tvb
, offset
++);
590 if (head_length
> addressSize
-1) {
591 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
592 "address head length is too long");
593 return tvb_reported_length(tvb
);
595 if (maxoffset
- offset
< head_length
) {
596 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
597 "Not enough octets for addressblock head");
598 return tvb_reported_length(tvb
);
600 tvb_memcpy(tvb
, addr
, offset
, head_length
);
602 midSize
-= head_length
;
603 block_length
+= (head_length
+1);
604 offset
+= head_length
;
606 if ((address_flags
& ADDR_HASZEROTAIL
) != 0) {
609 if (maxoffset
- offset
<= 0) {
610 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
611 "Not enough octets for addressblock tail");
612 return tvb_reported_length(tvb
);
614 tail_length
= tvb_get_uint8(tvb
, offset
++);
615 if (tail_length
> addressSize
-1-head_length
) {
616 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
617 "address tail length is too long");
618 return tvb_reported_length(tvb
);
620 midSize
-= tail_length
;
623 else if ((address_flags
& ADDR_HASFULLTAIL
) != 0) {
626 if (maxoffset
- offset
<= 0) {
627 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
628 "Not enough octets for addressblock tail");
629 return tvb_reported_length(tvb
);
631 tail_length
= tvb_get_uint8(tvb
, offset
++);
632 if (tail_length
> addressSize
-1-head_length
) {
633 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
634 "address tail length is too long");
635 return tvb_reported_length(tvb
);
638 if (maxoffset
- offset
< tail_length
) {
639 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
640 "Not enough octets for addressblock tail");
641 return tvb_reported_length(tvb
);
643 tvb_memcpy(tvb
, &addr
[addressSize
- tail_length
], offset
, tail_length
);
645 midSize
-= tail_length
;
646 block_length
+= (tail_length
+1);
647 offset
+= tail_length
;
651 block_length
+= numAddr
* midSize
;
652 offset
+= numAddr
* midSize
;
654 if ((address_flags
& ADDR_HASSINGLEPRELEN
) != 0) {
655 prefix_index
= offset
;
658 else if ((address_flags
& ADDR_HASMULTIPRELEN
) != 0) {
659 prefix_index
= offset
;
660 block_length
+= numAddr
;
663 if (maxoffset
< block_index
+ block_length
) {
664 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, maxoffset
- offset
,
665 "Not enough octets for address block");
669 /* add address tree */
670 addr_item
= proto_tree_add_item(tree
, hf_packetbb_addr
, tvb
, block_index
, block_length
, ENC_NA
);
671 addr_tree
= proto_item_add_subtree(addr_item
, ett_packetbb_addr
);
672 proto_item_append_text(addr_item
, " (%d addresses)", numAddr
);
675 proto_tree_add_item(addr_tree
, hf_packetbb_addr_num
, tvb
, block_index
, 1, ENC_BIG_ENDIAN
);
678 proto_tree_add_bitmask(addr_tree
, tvb
, block_index
+1, hf_packetbb_addr_flags
, ett_packetbb_addr_flags
, flags
, ENC_BIG_ENDIAN
);
680 if ((address_flags
& ADDR_HASHEAD
) != 0) {
682 proto_tree_add_item(addr_tree
, hf_packetbb_addr_head
, tvb
, head_index
, head_length
+1, ENC_NA
);
685 if ((address_flags
& ADDR_HASFULLTAIL
) != 0) {
687 proto_tree_add_item(addr_tree
, hf_packetbb_addr_tail
, tvb
, tail_index
, tail_length
+1, ENC_NA
);
689 else if ((address_flags
& ADDR_HASZEROTAIL
) != 0) {
691 proto_tree_add_item(addr_tree
, hf_packetbb_addr_tail
, tvb
, tail_index
, 1, ENC_NA
);
693 for (i
=0; i
<numAddr
; i
++) {
695 uint8_t prefix
= addressSize
* 8;
697 tvb_memcpy(tvb
, &addr
[head_length
], mid_index
+ midSize
*i
, midSize
);
698 ipv4
= (addr
[3] << 24) + (addr
[2] << 16) + (addr
[1] << 8) + addr
[0];
700 switch (addressType
) {
702 addrValue_item
= proto_tree_add_ipv4(addr_tree
, hf_packetbb_addr_value
[addressType
],
703 tvb
, mid_index
, block_index
+ block_length
- mid_index
, ipv4
);
706 addrValue_item
= proto_tree_add_ipv6(addr_tree
, hf_packetbb_addr_value
[addressType
],
707 tvb
, mid_index
, block_index
+ block_length
- mid_index
, (ws_in6_addr
*)addr
);
710 addrValue_item
= proto_tree_add_ether(addr_tree
, hf_packetbb_addr_value
[addressType
],
711 tvb
, mid_index
, block_index
+ block_length
- mid_index
, addr
);
714 addrValue_item
= proto_tree_add_bytes_format_value(addr_tree
, hf_packetbb_addr_value
[addressType
],
715 tvb
, mid_index
, block_index
+ block_length
- mid_index
, NULL
,
716 "%s", bytes_to_str(pinfo
->pool
, addr
, head_length
+ midSize
));
721 addrValue_tree
= proto_item_add_subtree(addrValue_item
, ett_packetbb_addr_value
);
723 proto_tree_add_item(addrValue_tree
, hf_packetbb_addr_value_mid
, tvb
,
724 mid_index
+ midSize
*i
, midSize
, ENC_NA
);
726 if ((address_flags
& ADDR_HASSINGLEPRELEN
) != 0) {
727 prefix
= tvb_get_uint8(tvb
, prefix_index
);
728 proto_tree_add_item(addrValue_tree
, hf_packetbb_addr_value_prefix
, tvb
, prefix_index
, 1, ENC_BIG_ENDIAN
);
730 else if ((address_flags
& ADDR_HASMULTIPRELEN
) != 0) {
731 prefix
= tvb_get_uint8(tvb
, prefix_index
+ i
);
732 proto_tree_add_item(addrValue_tree
, hf_packetbb_addr_value_prefix
, tvb
, prefix_index
+ i
, 1, ENC_BIG_ENDIAN
);
734 proto_item_append_text(addrValue_item
, "/%d", prefix
);
737 offset
= dissect_pbb_tlvblock(tvb
, pinfo
, addr_tree
, block_index
+ block_length
, maxoffset
, numAddr
, TLV_CAT_ADDRESS
);
741 static int dissect_pbb_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
) {
742 proto_tree
*message_tree
;
743 proto_tree
*header_tree
= NULL
;
744 proto_tree
*headerFlags_tree
= NULL
;
746 proto_item
*message_item
;
747 proto_item
*header_item
= NULL
;
748 proto_item
*headerFlags_item
= NULL
;
751 uint8_t messageFlags
;
752 uint16_t messageLength
, headerLength
, messageEnd
;
753 uint8_t addressSize
, addressType
;
755 if (tvb_reported_length(tvb
) - offset
< 6) {
756 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, -1,
757 "Not enough octets for minimal message header");
758 return tvb_reported_length(tvb
);
761 messageType
= tvb_get_uint8(tvb
, offset
);
762 messageFlags
= tvb_get_uint8(tvb
, offset
+1);
763 messageLength
= tvb_get_ntohs(tvb
, offset
+2);
764 addressSize
= (messageFlags
& 0x0f) + 1;
766 switch (addressSize
) {
781 messageEnd
= offset
+ messageLength
;
785 /* calculate header size */
786 if ((messageFlags
& MSG_HEADER_HASORIG
) != 0) {
787 headerLength
+= addressSize
;
789 if ((messageFlags
& MSG_HEADER_HASHOPLIMIT
) != 0) {
792 if ((messageFlags
& MSG_HEADER_HASHOPCOUNT
) != 0) {
795 if ((messageFlags
& MSG_HEADER_HASSEQNR
) != 0) {
799 /* test length for message size */
800 if (tvb_reported_length(tvb
) - offset
< messageLength
) {
801 proto_tree_add_expert_format(tree
, pinfo
, &ei_packetbb_error
, tvb
, offset
, -1,
802 "Not enough octets for message");
803 return tvb_reported_length(tvb
);
806 message_item
= proto_tree_add_item(tree
, hf_packetbb_msg
, tvb
, offset
, messageLength
, ENC_NA
);
807 proto_item_append_text(message_item
, " (%s)",
808 val_to_str_const(messageType
, msgheader_type_vals
, "Unknown type"));
809 message_tree
= proto_item_add_subtree(message_item
, ett_packetbb_msg
[messageType
]);
811 header_item
= proto_tree_add_item(message_tree
, hf_packetbb_msgheader
, tvb
, offset
, headerLength
, ENC_NA
);
812 header_tree
= proto_item_add_subtree(header_item
, ett_packetbb_msgheader
);
815 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
818 headerFlags_item
= proto_tree_add_uint(header_tree
, hf_packetbb_msgheader_flags
,
819 tvb
, offset
+1, 1, messageFlags
& 0xf8);
821 headerFlags_tree
= proto_item_add_subtree(headerFlags_item
, ett_packetbb_msgheader_flags
);
822 proto_tree_add_boolean(headerFlags_tree
, hf_packetbb_msgheader_flags_mhasorig
,
823 tvb
, offset
+1, 1, messageFlags
);
824 proto_tree_add_boolean(headerFlags_tree
, hf_packetbb_msgheader_flags_mhashoplimit
,
825 tvb
, offset
+1, 1, messageFlags
);
826 proto_tree_add_boolean(headerFlags_tree
, hf_packetbb_msgheader_flags_mhashopcount
,
827 tvb
, offset
+1, 1, messageFlags
);
828 proto_tree_add_boolean(headerFlags_tree
, hf_packetbb_msgheader_flags_mhasseqnr
,
829 tvb
, offset
+1, 1, messageFlags
);
831 proto_tree_add_uint(header_tree
, hf_packetbb_msgheader_addresssize
,
832 tvb
, offset
+ 1, 1, (messageFlags
& 0x0f) + 1);
835 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_size
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
839 /* originator address */
840 if ((messageFlags
& MSG_HEADER_HASORIG
) != 0) {
841 switch (addressSize
) {
844 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_origaddripv4
,
845 tvb
, offset
, addressSize
, ENC_BIG_ENDIAN
);
849 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_origaddripv6
,
850 tvb
, offset
, addressSize
, ENC_NA
);
854 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_origaddrmac
,
855 tvb
, offset
, addressSize
, ENC_NA
);
859 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_origaddrcustom
,
860 tvb
, offset
, addressSize
, ENC_NA
);
863 offset
+= addressSize
;
867 if ((messageFlags
& MSG_HEADER_HASHOPLIMIT
) != 0) {
868 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_hoplimit
, tvb
, offset
++, 1, ENC_BIG_ENDIAN
);
872 if ((messageFlags
& MSG_HEADER_HASHOPCOUNT
) != 0) {
873 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_hopcount
, tvb
, offset
++, 1, ENC_BIG_ENDIAN
);
876 /* sequence number */
877 if ((messageFlags
& MSG_HEADER_HASSEQNR
) != 0) {
878 proto_tree_add_item(header_tree
, hf_packetbb_msgheader_seqnr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
882 if (offset
>= messageEnd
) {
883 /* this is an error, tlv block is mandatory */
884 return tvb_reported_length(tvb
);
886 offset
= dissect_pbb_tlvblock(tvb
, pinfo
, message_tree
, offset
, messageEnd
, 0, TLV_CAT_MESSAGE
);
887 while (offset
< messageEnd
) {
888 offset
= dissect_pbb_addressblock(tvb
, pinfo
, message_tree
, offset
, messageEnd
, addressType
, addressSize
);
893 static int dissect_pbb_header(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned headerLength
, unsigned tlvIndex
) {
894 proto_tree
*header_tree
;
895 proto_item
*header_item
;
897 uint8_t packet_flags
= tvb_get_uint8(tvb
, 0);
899 static int * const flags
[] = {
900 &hf_packetbb_header_flags_phasseqnum
,
901 &hf_packetbb_header_flags_phastlv
,
905 header_item
= proto_tree_add_item(tree
, hf_packetbb_header
, tvb
, 0, headerLength
, ENC_NA
);
906 header_tree
= proto_item_add_subtree(header_item
, ett_packetbb_header
);
909 proto_tree_add_item(header_tree
, hf_packetbb_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
912 proto_tree_add_bitmask(header_tree
, tvb
, 0, hf_packetbb_header_flags
, ett_packetbb_header_flags
, flags
, ENC_BIG_ENDIAN
);
914 /* sequence number */
915 if ((packet_flags
& PACKET_HEADER_HASSEQNR
) != 0) {
916 proto_tree_add_item(header_tree
, hf_packetbb_seqnr
, tvb
, 1, 2, ENC_BIG_ENDIAN
);
919 if ((packet_flags
& PACKET_HEADER_HASTLV
) != 0) {
920 return dissect_pbb_tlvblock(tvb
, pinfo
, tree
, tlvIndex
, tvb_reported_length(tvb
), 0, TLV_CAT_PACKET
);
925 static int dissect_packetbb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
928 proto_tree
*packetbb_tree
;
930 uint8_t packet_flags
;
931 unsigned headerLength
= 1;
932 unsigned tlvIndex
= 0;
934 /* Make sure it's a PacketBB packet */
936 /* calculate header length */
937 packet_flags
= tvb_get_uint8(tvb
, 0);
938 if ((packet_flags
& PACKET_HEADER_HASSEQNR
) != 0) {
941 if ((packet_flags
& PACKET_HEADER_HASTLV
) != 0) {
942 tlvIndex
= headerLength
;
946 if (tvb_reported_length(tvb
) < headerLength
) {
949 if ((packet_flags
& PACKET_HEADER_HASTLV
) != 0) {
950 headerLength
+= tvb_get_ntohs(tvb
, tlvIndex
);
952 if (tvb_reported_length(tvb
) < headerLength
) {
956 /* Reasonably certain it's a PacketBB packet */
957 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "packetbb");
958 col_clear(pinfo
->cinfo
, COL_INFO
);
960 ti
= proto_tree_add_item(tree
, proto_packetbb
, tvb
, 0, -1, ENC_NA
);
961 packetbb_tree
= proto_item_add_subtree(ti
, ett_packetbb
);
963 offset
= dissect_pbb_header(tvb
, pinfo
, packetbb_tree
, headerLength
, tlvIndex
);
964 while (offset
< tvb_reported_length(tvb
)) {
965 offset
= dissect_pbb_message(tvb
, pinfo
, packetbb_tree
, offset
);
968 return tvb_captured_length(tvb
);
971 void proto_reg_handoff_packetbb(void) {
972 dissector_add_uint_with_preference("udp.port", PACKETBB_PORT
, packetbb_handle
);
975 void proto_register_packetbb(void) {
976 /* Setup list of header fields See Section 1.6.1 for details*/
977 static hf_register_info hf
[] = {
978 { &hf_packetbb_header
,
979 { "Packet header", "packetbb.header",
980 FT_NONE
, BASE_NONE
, NULL
, 0,
983 { &hf_packetbb_version
,
984 { "Version", "packetbb.version",
985 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
988 { &hf_packetbb_header_flags
,
989 { "Flags", "packetbb.flags",
990 FT_UINT8
, BASE_HEX
, NULL
, 0x0F,
993 { &hf_packetbb_header_flags_phasseqnum
,
994 { "Has sequence number", "packetbb.flags.phasseqnum",
995 FT_BOOLEAN
, 8, NULL
, PACKET_HEADER_HASSEQNR
,
998 { &hf_packetbb_header_flags_phastlv
,
999 { "Has tlv block", "packetbb.flags.phastlv",
1000 FT_BOOLEAN
, 8, NULL
, PACKET_HEADER_HASTLV
,
1003 { &hf_packetbb_seqnr
,
1004 { "Sequence number", "packetbb.seqnr",
1005 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1009 { "Message", "packetbb.msg",
1010 FT_NONE
, BASE_NONE
, NULL
, 0,
1013 { &hf_packetbb_msgheader
,
1014 { "Message header", "packetbb.msg.header",
1015 FT_NONE
, BASE_NONE
, NULL
, 0,
1018 { &hf_packetbb_msgheader_type
,
1019 { "Type", "packetbb.msg.type",
1020 FT_UINT8
, BASE_DEC
, VALS(msgheader_type_vals
), 0,
1023 { &hf_packetbb_msgheader_flags
,
1024 { "Flags", "packetbb.msg.flags",
1025 FT_UINT8
, BASE_HEX
, NULL
, 0,
1028 { &hf_packetbb_msgheader_flags_mhasorig
,
1029 { "Has originator address", "packetbb.msg.flags.mhasorig",
1030 FT_BOOLEAN
, 8, NULL
, MSG_HEADER_HASORIG
,
1033 { &hf_packetbb_msgheader_flags_mhashoplimit
,
1034 { "Has hoplimit", "packetbb.msg.flags.mhashoplimit",
1035 FT_BOOLEAN
, 8, NULL
, MSG_HEADER_HASHOPLIMIT
,
1038 { &hf_packetbb_msgheader_flags_mhashopcount
,
1039 { "Has hopcount", "packetbb.msg.flags.mhashopcount",
1040 FT_BOOLEAN
, 8, NULL
, MSG_HEADER_HASHOPCOUNT
,
1043 { &hf_packetbb_msgheader_flags_mhasseqnr
,
1044 { "Has sequence number", "packetbb.msg.flags.mhasseqnum",
1045 FT_BOOLEAN
, 8, NULL
, MSG_HEADER_HASSEQNR
,
1048 { &hf_packetbb_msgheader_addresssize
,
1049 { "AddressSize", "packetbb.msg.addrsize",
1050 FT_UINT8
, BASE_DEC
, NULL
, 0,
1053 { &hf_packetbb_msgheader_size
,
1054 { "Size", "packetbb.msg.size",
1055 FT_UINT16
, BASE_DEC
, NULL
, 0,
1058 { &hf_packetbb_msgheader_origaddripv4
,
1059 { "Originator address", "packetbb.msg.origaddr4",
1060 FT_IPv4
, BASE_NONE
, NULL
, 0,
1063 { &hf_packetbb_msgheader_origaddripv6
,
1064 { "Originator address", "packetbb.msg.origaddr6",
1065 FT_IPv6
, BASE_NONE
, NULL
, 0,
1068 { &hf_packetbb_msgheader_origaddrmac
,
1069 { "Originator address", "packetbb.msg.origaddrmac",
1070 FT_ETHER
, BASE_NONE
, NULL
, 0,
1073 { &hf_packetbb_msgheader_origaddrcustom
,
1074 { "Originator address", "packetbb.msg.origaddrcustom",
1075 FT_BYTES
, BASE_NONE
, NULL
, 0,
1078 { &hf_packetbb_msgheader_hoplimit
,
1079 { "Hop limit", "packetbb.msg.hoplimit",
1080 FT_UINT8
, BASE_DEC
, NULL
, 0,
1083 { &hf_packetbb_msgheader_hopcount
,
1084 { "Hop count", "packetbb.msg.hopcount",
1085 FT_UINT8
, BASE_DEC
, NULL
, 0,
1088 { &hf_packetbb_msgheader_seqnr
,
1089 { "Sequence number", "packetbb.msg.seqnum",
1090 FT_UINT16
, BASE_DEC
, NULL
, 0,
1094 { &hf_packetbb_addr
,
1095 { "Address block", "packetbb.msg.addr",
1096 FT_NONE
, BASE_NONE
, NULL
, 0,
1099 { &hf_packetbb_addr_num
,
1100 { "Count", "packetbb.msg.addr.num",
1101 FT_UINT8
, BASE_DEC
, NULL
, 0,
1104 { &hf_packetbb_addr_flags
,
1105 { "Flags", "packetbb.msg.addr.flags",
1106 FT_UINT8
, BASE_HEX
, NULL
, 0,
1109 { &hf_packetbb_addr_flags_hashead
,
1110 { "Has head", "packetbb.msg.addr.hashead",
1111 FT_BOOLEAN
, 8, NULL
, ADDR_HASHEAD
,
1114 { &hf_packetbb_addr_flags_hasfulltail
,
1115 { "Has full tail", "packetbb.msg.addr.hasfulltail",
1116 FT_BOOLEAN
, 8, NULL
, ADDR_HASFULLTAIL
,
1119 { &hf_packetbb_addr_flags_haszerotail
,
1120 { "Has zero tail", "packetbb.msg.addr.haszerotail",
1121 FT_BOOLEAN
, 8, NULL
, ADDR_HASZEROTAIL
,
1124 { &hf_packetbb_addr_flags_hassingleprelen
,
1125 { "Has single prelen", "packetbb.msg.addr.hassingleprelen",
1126 FT_BOOLEAN
, 8, NULL
, ADDR_HASSINGLEPRELEN
,
1129 { &hf_packetbb_addr_flags_hasmultiprelen
,
1130 { "Has multiple prelen", "packetbb.msg.addr.hasmultiprelen",
1131 FT_BOOLEAN
, 8, NULL
, ADDR_HASMULTIPRELEN
,
1134 { &hf_packetbb_addr_head
,
1135 { "Head", "packetbb.msg.addr.head",
1136 FT_BYTES
, BASE_NONE
, NULL
, 0,
1139 { &hf_packetbb_addr_tail
,
1140 { "Tail", "packetbb.msg.addr.tail",
1141 FT_BYTES
, BASE_NONE
, NULL
, 0,
1144 { &hf_packetbb_addr_value
[0],
1145 { "Address", "packetbb.msg.addr.value4",
1146 FT_IPv4
, BASE_NONE
, NULL
, 0,
1149 { &hf_packetbb_addr_value
[1],
1150 { "Address", "packetbb.msg.addr.value6",
1151 FT_IPv6
, BASE_NONE
, NULL
, 0,
1154 { &hf_packetbb_addr_value
[2],
1155 { "Address", "packetbb.msg.addr.valuemac",
1156 FT_ETHER
, BASE_NONE
, NULL
, 0,
1159 { &hf_packetbb_addr_value
[3],
1160 { "Address", "packetbb.msg.addr.valuecustom",
1161 FT_BYTES
, BASE_NONE
, NULL
, 0,
1164 { &hf_packetbb_addr_value_mid
,
1165 { "Mid", "packetbb.msg.addr.value.mid",
1166 FT_BYTES
, BASE_NONE
, NULL
, 0,
1169 { &hf_packetbb_addr_value_prefix
,
1170 { "Prefix", "packetbb.msg.addr.value.prefix",
1171 FT_UINT8
, BASE_DEC
, NULL
, 0,
1174 { &hf_packetbb_tlvblock
,
1175 { "TLV block", "packetbb.tlvblock",
1176 FT_NONE
, BASE_NONE
, NULL
, 0,
1179 { &hf_packetbb_tlvblock_length
,
1180 { "Length", "packetbb.tlvblock.length",
1181 FT_UINT16
, BASE_DEC
, NULL
, 0,
1185 { "TLV", "packetbb.tlv",
1186 FT_NONE
, BASE_NONE
, NULL
, 0,
1189 { &hf_packetbb_pkttlv_type
,
1190 { "Type", "packetbb.pkttlv.type",
1191 FT_UINT8
, BASE_DEC
, VALS(pkttlv_type_vals
), 0,
1194 { &hf_packetbb_msgtlv_type
,
1195 { "Type", "packetbb.msgtlv.type",
1196 FT_UINT8
, BASE_DEC
, VALS(msgtlv_type_vals
), 0,
1199 { &hf_packetbb_addrtlv_type
,
1200 { "Type", "packetbb.addrtlv.type",
1201 FT_UINT8
, BASE_DEC
, VALS(addrtlv_type_vals
), 0,
1204 { &hf_packetbb_tlv_flags
,
1205 { "Flags", "packetbb.tlv.flags",
1206 FT_UINT8
, BASE_HEX
, NULL
, 0,
1209 { &hf_packetbb_tlv_typeext
,
1210 { "Extended Type", "packetbb.tlv.typeext",
1211 FT_UINT8
, BASE_DEC
, NULL
, 0,
1214 { &hf_packetbb_tlv_flags_hastypext
,
1215 { "Has type-ext", "packetbb.tlv.hastypeext",
1216 FT_BOOLEAN
, 8, NULL
, TLV_HAS_TYPEEXT
,
1219 { &hf_packetbb_tlv_flags_hassingleindex
,
1220 { "Has single index", "packetbb.tlv.hassingleindex",
1221 FT_BOOLEAN
, 8, NULL
, TLV_HAS_SINGLEINDEX
,
1224 { &hf_packetbb_tlv_flags_hasmultiindex
,
1225 { "Has multiple indices", "packetbb.tlv.hasmultiindex",
1226 FT_BOOLEAN
, 8, NULL
, TLV_HAS_MULTIINDEX
,
1229 { &hf_packetbb_tlv_flags_hasvalue
,
1230 { "Has value", "packetbb.tlv.hasvalue",
1231 FT_BOOLEAN
, 8, NULL
, TLV_HAS_VALUE
,
1234 { &hf_packetbb_tlv_flags_hasextlen
,
1235 { "Has extended length", "packetbb.tlv.hasextlen",
1236 FT_BOOLEAN
, 8, NULL
, TLV_HAS_EXTLEN
,
1239 { &hf_packetbb_tlv_flags_hasmultivalue
,
1240 { "Has multiple values", "packetbb.tlv.hasmultivalue",
1241 FT_BOOLEAN
, 8, NULL
, TLV_HAS_MULTIVALUE
,
1244 { &hf_packetbb_tlv_indexstart
,
1245 { "Index start", "packetbb.tlv.indexstart",
1246 FT_UINT8
, BASE_DEC
, NULL
, 0,
1249 { &hf_packetbb_tlv_indexend
,
1250 { "Index end", "packetbb.tlv.indexend",
1251 FT_UINT8
, BASE_DEC
, NULL
, 0,
1254 { &hf_packetbb_tlv_length
,
1255 { "Length", "packetbb.tlv.length",
1256 FT_UINT16
, BASE_DEC
, NULL
, 0,
1259 { &hf_packetbb_tlv_value
,
1260 { "Value", "packetbb.tlv.value",
1261 FT_BYTES
, BASE_NONE
, NULL
, 0,
1264 { &hf_packetbb_tlv_multivalue
,
1265 { "Multivalue", "packetbb.tlv.multivalue",
1266 FT_BYTES
, BASE_NONE
, NULL
, 0,
1269 { &hf_packetbb_tlv_intervaltime
,
1270 { "Signaling message interval", "packetbb.tlv.intervaltime",
1271 FT_UINT8
, BASE_HEX
, NULL
, 0,
1274 { &hf_packetbb_tlv_validitytime
,
1275 { "Message validity time", "packetbb.tlv.validitytime",
1276 FT_UINT8
, BASE_HEX
, NULL
, 0,
1279 { &hf_packetbb_tlv_localifs
,
1280 { "Local interface status", "packetbb.tlv.localifs",
1281 FT_UINT8
, BASE_DEC
, VALS(localif_vals
), 0,
1284 { &hf_packetbb_tlv_linkstatus
,
1285 { "Link status", "packetbb.tlv.linkstatus",
1286 FT_UINT8
, BASE_DEC
, VALS(linkstatus_vals
), 0,
1289 { &hf_packetbb_tlv_otherneigh
,
1290 { "Other neighbor status", "packetbb.tlv.otherneigh",
1291 FT_UINT8
, BASE_DEC
, VALS(otherneigh_vals
), 0,
1294 { &hf_packetbb_tlv_icv
,
1295 { "Integrity Check Value", "packetbb.tlv.icv",
1296 FT_BYTES
, BASE_NONE
, NULL
, 0,
1299 { &hf_packetbb_tlv_timestamp
,
1300 { "Timestamp", "packetbb.tlv.timestamp",
1301 FT_BYTES
, BASE_NONE
, NULL
, 0,
1304 { &hf_packetbb_tlv_mprwillingness
,
1305 { "MPR willingness", "packetbb.tlv.mprwillingness",
1306 FT_UINT8
, BASE_HEX
, NULL
, 0,
1309 { &hf_packetbb_tlv_mprwillingness_flooding
,
1310 { "Flooding", "packetbb.tlv.mprwillingnessflooding",
1311 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1314 { &hf_packetbb_tlv_mprwillingness_routing
,
1315 { "Routing", "packetbb.tlv.mprwillingnessrouting",
1316 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
1319 { &hf_packetbb_tlv_contseqnum
,
1320 { "Content sequence number", "packetbb.tlv.contseqnum",
1321 FT_UINT16
, BASE_HEX
, NULL
, 0,
1324 { &hf_packetbb_tlv_linkmetric_flags_linkin
,
1325 { "Incoming link", "packetbb.tlv.linkmetriclinkin",
1326 FT_BOOLEAN
, 16, NULL
, RFC7181_LINKMETRIC_INCOMING_LINK
,
1329 { &hf_packetbb_tlv_linkmetric_flags_linkout
,
1330 { "Outgoing link", "packetbb.tlv.linkmetriclinkout",
1331 FT_BOOLEAN
, 16, NULL
, RFC7181_LINKMETRIC_OUTGOING_LINK
,
1334 { &hf_packetbb_tlv_linkmetric_flags_neighin
,
1335 { "Incoming neighbor", "packetbb.tlv.linkmetricneighin",
1336 FT_BOOLEAN
, 16, NULL
, RFC7181_LINKMETRIC_INCOMING_NEIGH
,
1339 { &hf_packetbb_tlv_linkmetric_flags_neighout
,
1340 { "Outgoing neighbor", "packetbb.tlv.linkmetricneighout",
1341 FT_BOOLEAN
, 16, NULL
, RFC7181_LINKMETRIC_OUTGOING_NEIGH
,
1344 { &hf_packetbb_tlv_linkmetric_value
,
1345 { "Link metric", "packetbb.tlv.linkmetricvalue",
1346 FT_UINT16
, BASE_HEX
, NULL
, 0,
1349 { &hf_packetbb_tlv_mpr
,
1350 { "Multipoint Relay", "packetbb.tlv.mpr",
1351 FT_UINT8
, BASE_DEC
, VALS(mpr_vals
), 0,
1354 { &hf_packetbb_tlv_nbraddrtype
,
1355 { "Neighbor address type", "packetbb.tlv.nbraddrtype",
1356 FT_UINT8
, BASE_DEC
, VALS(nbraddrtype_vals
), 0,
1359 { &hf_packetbb_tlv_gateway
,
1360 { "Gateway", "packetbb.tlv.gateway",
1361 FT_UINT8
, BASE_DEC
, NULL
, 0,
1366 /* Setup protocol subtree array */
1369 &ett_packetbb_header
,
1370 &ett_packetbb_header_flags
,
1371 &ett_packetbb_msgheader
,
1372 &ett_packetbb_msgheader_flags
,
1374 &ett_packetbb_addr_flags
,
1375 &ett_packetbb_addr_value
,
1376 &ett_packetbb_tlvblock
,
1377 &ett_packetbb_tlv_flags
,
1378 &ett_packetbb_tlv_value
,
1379 &ett_packetbb_tlv_mprwillingness
,
1380 &ett_packetbb_tlv_linkmetric
1383 static ei_register_info ei
[] = {
1384 { &ei_packetbb_error
, { "packetbb.error", PI_PROTOCOL
, PI_WARN
, "ERROR!", EXPFILL
}},
1387 static int *ett
[array_length(ett_base
) + 2*PACKETBB_MSG_TLV_LENGTH
];
1388 expert_module_t
* expert_packetbb
;
1391 memcpy(ett
, ett_base
, sizeof(ett_base
));
1392 j
= array_length(ett_base
);
1393 for (i
=0; i
<PACKETBB_MSG_TLV_LENGTH
; i
++) {
1394 ett
[j
++] = &ett_packetbb_msg
[i
];
1395 ett
[j
++] = &ett_packetbb_tlv
[i
];
1398 /* name, short name, abbrev */
1399 proto_packetbb
= proto_register_protocol("PacketBB Protocol", "PacketBB", "packetbb");
1400 packetbb_handle
= register_dissector("packetbb", dissect_packetbb
, proto_packetbb
);
1402 /* Required function calls to register the header fields and subtrees used */
1403 proto_register_field_array(proto_packetbb
, hf
, array_length(hf
));
1404 proto_register_subtree_array(ett
, array_length(ett
));
1405 expert_packetbb
= expert_register_protocol(proto_packetbb
);
1406 expert_register_field_array(expert_packetbb
, ei
, array_length(ei
));
1410 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1415 * indent-tabs-mode: nil
1418 * ex: set shiftwidth=2 tabstop=8 expandtab:
1419 * :indentSize=2:tabSize=8:noTabs=true: