Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-packetbb.c
blobccc218a490a56f30824ed5532878cde89bf6fe6b
1 /* packet-packetbb.c
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
15 #include "config.h"
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 {
72 RFC7182_TLV_ICV = 5,
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)" },
109 { 0, NULL }};
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" },
115 { 0 , NULL }};
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" },
125 { 0 , NULL }};
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" },
140 { 0 , NULL }};
142 /* Values of LOCALIF TLV of RFC6130 */
143 static const value_string localif_vals[] = {
144 { 0, "THIS_IF" },
145 { 1, "OTHER_IF" },
146 { 0, NULL }};
148 /* Values of LINKSTATUS TLV of RFC6130 */
149 static const value_string linkstatus_vals[] = {
150 { 0, "LOST" },
151 { 1, "SYMMETRIC" },
152 { 2, "HEARD" },
153 { 0, NULL }};
155 /* Values of OTHERNEIGH TLV of RFC6130 */
156 static const value_string otherneigh_vals[] = {
157 { 0, "LOST" },
158 { 1, "SYMMETRIC" },
159 { 0, NULL }};
161 /* Values of MPR TLV of RFC7181 */
162 static const value_string mpr_vals[] = {
163 { 1, "FLOODING" },
164 { 2, "ROUTING" },
165 { 3, "FLOOD_ROUTE" },
166 { 0, NULL }};
168 /* Values of NBRADDRTYPE TLV of RFC7181 */
169 static const value_string nbraddrtype_vals[] = {
170 { 1, "ORIGINATOR" },
171 { 2, "ROUTABLE" },
172 { 3, "ROUTABLE_ORIG" },
173 { 0, NULL }};
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,
292 NULL
295 switch (tlvCat) {
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);
300 break;
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);
304 break;
307 /* other tlvTypes are common with categories PACKET and ADDRESS,
308 do not break.
310 /* FALL THROUGH */
311 case TLV_CAT_PACKET:
312 case TLV_CAT_ADDRESS:
314 switch (tlvType) {
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)));
318 break;
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)));
322 break;
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);
325 break;
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);
328 break;
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);
331 break;
332 case RFC7182_TLV_ICV:
333 tlv_decoded_value_item = proto_tree_add_item(tlvTree, hf_packetbb_tlv_icv, tvb, offset, len, ENC_NA);
334 break;
335 case RFC7182_TLV_TIMESTAMP:
336 tlv_decoded_value_item = proto_tree_add_item(tlvTree, hf_packetbb_tlv_timestamp, tvb, offset, len, ENC_NA);
337 break;
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)));
346 break;
347 case RFC7181_ADDRTLV_MPR:
348 tlv_decoded_value_item = proto_tree_add_item(tlvTree, hf_packetbb_tlv_mpr, tvb, offset, len, ENC_NA);
349 break;
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);
352 break;
353 case RFC7181_ADDRTLV_GATEWAY:
354 tlv_decoded_value_item = proto_tree_add_item(tlvTree, hf_packetbb_tlv_gateway, tvb, offset, len, ENC_NA);
355 break;
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;
368 int tlvCount = 0;
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,
377 NULL
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");
383 return maxoffset;
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");
392 return maxoffset;
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);
400 offset += 2;
401 while (offset < tlvblockEnd) {
402 unsigned tlvStart, tlvLength;
403 uint8_t tlvType, tlvFlags, /*tlvExtType, */indexStart, indexEnd;
404 uint16_t length = 0;
405 int hf_packetbb_tlv_type = 0;
406 const value_string *tlv_type_vals;
408 tlvStart = offset;
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 */
414 offset++;
417 indexStart = 0;
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);
431 offset += 2;
433 else {
434 length = tvb_get_uint8(tvb, offset++);
438 tlvLength = offset - tlvStart + length;
439 offset = tlvStart;
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;
453 else {
454 /* assume TLV_CAT_ADDRESS */
455 hf_packetbb_tlv_type = hf_packetbb_addrtlv_type;
456 tlv_type_vals = addrtlv_type_vals;
459 /* add type */
460 proto_tree_add_item(tlv_tree, hf_packetbb_tlv_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
462 /* add flags */
463 proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_packetbb_tlv_flags, ett_packetbb_tlv_flags, flags, ENC_BIG_ENDIAN);
464 offset++;
466 if ((tlvFlags & TLV_HAS_TYPEEXT) != 0) {
467 /* add ext-type */
468 proto_tree_add_item(tlv_tree, hf_packetbb_tlv_typeext, tvb, offset++, 1, ENC_BIG_ENDIAN);
471 if (addrCount > 0) {
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);
482 else {
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);
488 /* add length */
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);
492 offset += 2;
494 else {
495 proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_length, tvb, offset++, 1, length);
498 else {
499 proto_tree_add_uint_format_value(tlv_tree, hf_packetbb_tlv_length, tvb, offset, 0, 0, "0 (implicit)");
502 /* add value */
503 if (length > 0) {
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) {
506 /* single value */
507 dissect_pbb_tlvvalue(tvb, tlv_tree, offset, length, tlvCat, tlvType);
508 offset += length;
510 else {
511 /* multiple values */
512 int i;
513 unsigned c = indexEnd - indexStart + 1;
514 if (c > 0) {
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);
525 if (tlv_item) {
526 proto_item_append_text(tlv_item, " (t=%d,l=%d): %s", tlvType, length, val_to_str(tlvType, tlv_type_vals, "Unknown Type (%d)") );
528 tlvCount++;
531 proto_item_append_text(tlvBlock_item, " (%d TLVs)", tlvCount);
533 return offset;
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];
540 uint8_t numAddr;
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;
552 int i = 0;
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,
560 NULL
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);
573 block_length = 2;
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) {
581 head_index = offset;
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) {
607 tail_index = offset;
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;
621 block_length++;
623 else if ((address_flags & ADDR_HASFULLTAIL) != 0) {
624 tail_index = offset;
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;
650 mid_index = offset;
651 block_length += numAddr * midSize;
652 offset += numAddr * midSize;
654 if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) {
655 prefix_index = offset;
656 block_length++;
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");
666 return maxoffset;
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);
674 /* add num-addr */
675 proto_tree_add_item(addr_tree, hf_packetbb_addr_num, tvb, block_index, 1, ENC_BIG_ENDIAN);
677 /* add flags */
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) {
681 /* add head */
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) {
686 /* add full tail */
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) {
690 /* add zero tail */
691 proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, 1, ENC_NA);
693 for (i=0; i<numAddr; i++) {
694 uint32_t ipv4 = 0;
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) {
701 case 0:
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);
704 break;
705 case 1:
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);
708 break;
709 case 2:
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);
712 break;
713 case 3:
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));
717 break;
718 default:
719 break;
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);
738 return offset;
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;
750 uint8_t messageType;
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) {
767 case 4:
768 addressType = 0;
769 break;
770 case 16:
771 addressType = 1;
772 break;
773 case 6:
774 addressType = 2;
775 break;
776 default:
777 addressType = 3;
778 break;
781 messageEnd = offset + messageLength;
783 headerLength = 4;
785 /* calculate header size */
786 if ((messageFlags & MSG_HEADER_HASORIG) != 0) {
787 headerLength += addressSize;
789 if ((messageFlags & MSG_HEADER_HASHOPLIMIT) != 0) {
790 headerLength ++;
792 if ((messageFlags & MSG_HEADER_HASHOPCOUNT) != 0) {
793 headerLength ++;
795 if ((messageFlags & MSG_HEADER_HASSEQNR) != 0) {
796 headerLength += 2;
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);
814 /* type */
815 proto_tree_add_item(header_tree, hf_packetbb_msgheader_type, tvb, offset, 1, ENC_BIG_ENDIAN);
817 /* flags */
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);
834 /* size */
835 proto_tree_add_item(header_tree, hf_packetbb_msgheader_size, tvb, offset+2, 2, ENC_BIG_ENDIAN);
837 offset += 4;
839 /* originator address */
840 if ((messageFlags & MSG_HEADER_HASORIG) != 0) {
841 switch (addressSize) {
842 case 4:
843 /* IPv4 */
844 proto_tree_add_item(header_tree, hf_packetbb_msgheader_origaddripv4,
845 tvb, offset, addressSize, ENC_BIG_ENDIAN);
846 break;
847 case 16:
848 /* IPv6 */
849 proto_tree_add_item(header_tree, hf_packetbb_msgheader_origaddripv6,
850 tvb, offset, addressSize, ENC_NA);
851 break;
852 case 6:
853 /* MAC */
854 proto_tree_add_item(header_tree, hf_packetbb_msgheader_origaddrmac,
855 tvb, offset, addressSize, ENC_NA);
856 break;
857 default:
858 /* Unknown */
859 proto_tree_add_item(header_tree, hf_packetbb_msgheader_origaddrcustom,
860 tvb, offset, addressSize, ENC_NA);
861 break;
863 offset += addressSize;
866 /* hop limit */
867 if ((messageFlags & MSG_HEADER_HASHOPLIMIT) != 0) {
868 proto_tree_add_item(header_tree, hf_packetbb_msgheader_hoplimit, tvb, offset++, 1, ENC_BIG_ENDIAN);
871 /* hop count */
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);
879 offset += 2;
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);
890 return offset;
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,
902 NULL
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);
908 /* version */
909 proto_tree_add_item(header_tree, hf_packetbb_version, tvb, 0, 1, ENC_BIG_ENDIAN);
911 /* flags */
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);
922 return headerLength;
925 static int dissect_packetbb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
927 proto_item *ti;
928 proto_tree *packetbb_tree;
929 unsigned offset;
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) {
939 headerLength += 2;
941 if ((packet_flags & PACKET_HEADER_HASTLV) != 0) {
942 tlvIndex = headerLength;
943 headerLength += 2;
946 if (tvb_reported_length(tvb) < headerLength) {
947 return 0;
949 if ((packet_flags & PACKET_HEADER_HASTLV) != 0) {
950 headerLength += tvb_get_ntohs(tvb, tlvIndex);
952 if (tvb_reported_length(tvb) < headerLength) {
953 return 0;
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,
981 NULL, HFILL }
983 { &hf_packetbb_version,
984 { "Version", "packetbb.version",
985 FT_UINT8, BASE_DEC, NULL, 0xF0,
986 NULL, HFILL }
988 { &hf_packetbb_header_flags,
989 { "Flags", "packetbb.flags",
990 FT_UINT8, BASE_HEX, NULL, 0x0F,
991 NULL, HFILL }
993 { &hf_packetbb_header_flags_phasseqnum,
994 { "Has sequence number", "packetbb.flags.phasseqnum",
995 FT_BOOLEAN, 8, NULL, PACKET_HEADER_HASSEQNR,
996 NULL, HFILL }
998 { &hf_packetbb_header_flags_phastlv,
999 { "Has tlv block", "packetbb.flags.phastlv",
1000 FT_BOOLEAN, 8, NULL, PACKET_HEADER_HASTLV,
1001 NULL, HFILL }
1003 { &hf_packetbb_seqnr,
1004 { "Sequence number", "packetbb.seqnr",
1005 FT_UINT16, BASE_DEC, NULL, 0x0,
1006 NULL, HFILL }
1008 { &hf_packetbb_msg,
1009 { "Message", "packetbb.msg",
1010 FT_NONE, BASE_NONE, NULL, 0,
1011 NULL, HFILL }
1013 { &hf_packetbb_msgheader,
1014 { "Message header", "packetbb.msg.header",
1015 FT_NONE, BASE_NONE, NULL, 0,
1016 NULL, HFILL }
1018 { &hf_packetbb_msgheader_type,
1019 { "Type", "packetbb.msg.type",
1020 FT_UINT8, BASE_DEC, VALS(msgheader_type_vals), 0,
1021 NULL, HFILL }
1023 { &hf_packetbb_msgheader_flags,
1024 { "Flags", "packetbb.msg.flags",
1025 FT_UINT8, BASE_HEX, NULL, 0,
1026 NULL, HFILL }
1028 { &hf_packetbb_msgheader_flags_mhasorig,
1029 { "Has originator address", "packetbb.msg.flags.mhasorig",
1030 FT_BOOLEAN, 8, NULL, MSG_HEADER_HASORIG,
1031 NULL, HFILL }
1033 { &hf_packetbb_msgheader_flags_mhashoplimit,
1034 { "Has hoplimit", "packetbb.msg.flags.mhashoplimit",
1035 FT_BOOLEAN, 8, NULL, MSG_HEADER_HASHOPLIMIT,
1036 NULL, HFILL }
1038 { &hf_packetbb_msgheader_flags_mhashopcount,
1039 { "Has hopcount", "packetbb.msg.flags.mhashopcount",
1040 FT_BOOLEAN, 8, NULL, MSG_HEADER_HASHOPCOUNT,
1041 NULL, HFILL }
1043 { &hf_packetbb_msgheader_flags_mhasseqnr,
1044 { "Has sequence number", "packetbb.msg.flags.mhasseqnum",
1045 FT_BOOLEAN, 8, NULL, MSG_HEADER_HASSEQNR,
1046 NULL, HFILL }
1048 { &hf_packetbb_msgheader_addresssize,
1049 { "AddressSize", "packetbb.msg.addrsize",
1050 FT_UINT8, BASE_DEC, NULL, 0,
1051 NULL, HFILL }
1053 { &hf_packetbb_msgheader_size,
1054 { "Size", "packetbb.msg.size",
1055 FT_UINT16, BASE_DEC, NULL, 0,
1056 NULL, HFILL }
1058 { &hf_packetbb_msgheader_origaddripv4,
1059 { "Originator address", "packetbb.msg.origaddr4",
1060 FT_IPv4, BASE_NONE, NULL, 0,
1061 NULL, HFILL }
1063 { &hf_packetbb_msgheader_origaddripv6,
1064 { "Originator address", "packetbb.msg.origaddr6",
1065 FT_IPv6, BASE_NONE, NULL, 0,
1066 NULL, HFILL }
1068 { &hf_packetbb_msgheader_origaddrmac,
1069 { "Originator address", "packetbb.msg.origaddrmac",
1070 FT_ETHER, BASE_NONE, NULL, 0,
1071 NULL, HFILL }
1073 { &hf_packetbb_msgheader_origaddrcustom,
1074 { "Originator address", "packetbb.msg.origaddrcustom",
1075 FT_BYTES, BASE_NONE, NULL, 0,
1076 NULL, HFILL }
1078 { &hf_packetbb_msgheader_hoplimit,
1079 { "Hop limit", "packetbb.msg.hoplimit",
1080 FT_UINT8, BASE_DEC, NULL, 0,
1081 NULL, HFILL }
1083 { &hf_packetbb_msgheader_hopcount,
1084 { "Hop count", "packetbb.msg.hopcount",
1085 FT_UINT8, BASE_DEC, NULL, 0,
1086 NULL, HFILL }
1088 { &hf_packetbb_msgheader_seqnr,
1089 { "Sequence number", "packetbb.msg.seqnum",
1090 FT_UINT16, BASE_DEC, NULL, 0,
1091 NULL, HFILL }
1094 { &hf_packetbb_addr,
1095 { "Address block", "packetbb.msg.addr",
1096 FT_NONE, BASE_NONE, NULL, 0,
1097 NULL, HFILL }
1099 { &hf_packetbb_addr_num,
1100 { "Count", "packetbb.msg.addr.num",
1101 FT_UINT8, BASE_DEC, NULL, 0,
1102 NULL, HFILL }
1104 { &hf_packetbb_addr_flags,
1105 { "Flags", "packetbb.msg.addr.flags",
1106 FT_UINT8, BASE_HEX, NULL, 0,
1107 NULL, HFILL }
1109 { &hf_packetbb_addr_flags_hashead,
1110 { "Has head", "packetbb.msg.addr.hashead",
1111 FT_BOOLEAN, 8, NULL, ADDR_HASHEAD,
1112 NULL, HFILL }
1114 { &hf_packetbb_addr_flags_hasfulltail,
1115 { "Has full tail", "packetbb.msg.addr.hasfulltail",
1116 FT_BOOLEAN, 8, NULL, ADDR_HASFULLTAIL,
1117 NULL, HFILL }
1119 { &hf_packetbb_addr_flags_haszerotail,
1120 { "Has zero tail", "packetbb.msg.addr.haszerotail",
1121 FT_BOOLEAN, 8, NULL, ADDR_HASZEROTAIL,
1122 NULL, HFILL }
1124 { &hf_packetbb_addr_flags_hassingleprelen,
1125 { "Has single prelen", "packetbb.msg.addr.hassingleprelen",
1126 FT_BOOLEAN, 8, NULL, ADDR_HASSINGLEPRELEN,
1127 NULL, HFILL }
1129 { &hf_packetbb_addr_flags_hasmultiprelen,
1130 { "Has multiple prelen", "packetbb.msg.addr.hasmultiprelen",
1131 FT_BOOLEAN, 8, NULL, ADDR_HASMULTIPRELEN,
1132 NULL, HFILL }
1134 { &hf_packetbb_addr_head,
1135 { "Head", "packetbb.msg.addr.head",
1136 FT_BYTES, BASE_NONE, NULL, 0,
1137 NULL, HFILL }
1139 { &hf_packetbb_addr_tail,
1140 { "Tail", "packetbb.msg.addr.tail",
1141 FT_BYTES, BASE_NONE, NULL, 0,
1142 NULL, HFILL }
1144 { &hf_packetbb_addr_value[0],
1145 { "Address", "packetbb.msg.addr.value4",
1146 FT_IPv4, BASE_NONE, NULL, 0,
1147 NULL, HFILL }
1149 { &hf_packetbb_addr_value[1],
1150 { "Address", "packetbb.msg.addr.value6",
1151 FT_IPv6, BASE_NONE, NULL, 0,
1152 NULL, HFILL }
1154 { &hf_packetbb_addr_value[2],
1155 { "Address", "packetbb.msg.addr.valuemac",
1156 FT_ETHER, BASE_NONE, NULL, 0,
1157 NULL, HFILL }
1159 { &hf_packetbb_addr_value[3],
1160 { "Address", "packetbb.msg.addr.valuecustom",
1161 FT_BYTES, BASE_NONE, NULL, 0,
1162 NULL, HFILL }
1164 { &hf_packetbb_addr_value_mid,
1165 { "Mid", "packetbb.msg.addr.value.mid",
1166 FT_BYTES, BASE_NONE, NULL, 0,
1167 NULL, HFILL }
1169 { &hf_packetbb_addr_value_prefix,
1170 { "Prefix", "packetbb.msg.addr.value.prefix",
1171 FT_UINT8, BASE_DEC, NULL, 0,
1172 NULL, HFILL }
1174 { &hf_packetbb_tlvblock,
1175 { "TLV block", "packetbb.tlvblock",
1176 FT_NONE, BASE_NONE, NULL, 0,
1177 NULL, HFILL }
1179 { &hf_packetbb_tlvblock_length,
1180 { "Length", "packetbb.tlvblock.length",
1181 FT_UINT16, BASE_DEC, NULL, 0,
1182 NULL, HFILL }
1184 { &hf_packetbb_tlv,
1185 { "TLV", "packetbb.tlv",
1186 FT_NONE, BASE_NONE, NULL, 0,
1187 NULL, HFILL }
1189 { &hf_packetbb_pkttlv_type,
1190 { "Type", "packetbb.pkttlv.type",
1191 FT_UINT8, BASE_DEC, VALS(pkttlv_type_vals), 0,
1192 NULL, HFILL }
1194 { &hf_packetbb_msgtlv_type,
1195 { "Type", "packetbb.msgtlv.type",
1196 FT_UINT8, BASE_DEC, VALS(msgtlv_type_vals), 0,
1197 NULL, HFILL }
1199 { &hf_packetbb_addrtlv_type,
1200 { "Type", "packetbb.addrtlv.type",
1201 FT_UINT8, BASE_DEC, VALS(addrtlv_type_vals), 0,
1202 NULL, HFILL }
1204 { &hf_packetbb_tlv_flags,
1205 { "Flags", "packetbb.tlv.flags",
1206 FT_UINT8, BASE_HEX, NULL, 0,
1207 NULL, HFILL }
1209 { &hf_packetbb_tlv_typeext,
1210 { "Extended Type", "packetbb.tlv.typeext",
1211 FT_UINT8, BASE_DEC, NULL, 0,
1212 NULL, HFILL }
1214 { &hf_packetbb_tlv_flags_hastypext,
1215 { "Has type-ext", "packetbb.tlv.hastypeext",
1216 FT_BOOLEAN, 8, NULL, TLV_HAS_TYPEEXT,
1217 NULL, HFILL }
1219 { &hf_packetbb_tlv_flags_hassingleindex,
1220 { "Has single index", "packetbb.tlv.hassingleindex",
1221 FT_BOOLEAN, 8, NULL, TLV_HAS_SINGLEINDEX,
1222 NULL, HFILL }
1224 { &hf_packetbb_tlv_flags_hasmultiindex,
1225 { "Has multiple indices", "packetbb.tlv.hasmultiindex",
1226 FT_BOOLEAN, 8, NULL, TLV_HAS_MULTIINDEX,
1227 NULL, HFILL }
1229 { &hf_packetbb_tlv_flags_hasvalue,
1230 { "Has value", "packetbb.tlv.hasvalue",
1231 FT_BOOLEAN, 8, NULL, TLV_HAS_VALUE,
1232 NULL, HFILL }
1234 { &hf_packetbb_tlv_flags_hasextlen,
1235 { "Has extended length", "packetbb.tlv.hasextlen",
1236 FT_BOOLEAN, 8, NULL, TLV_HAS_EXTLEN,
1237 NULL, HFILL }
1239 { &hf_packetbb_tlv_flags_hasmultivalue,
1240 { "Has multiple values", "packetbb.tlv.hasmultivalue",
1241 FT_BOOLEAN, 8, NULL, TLV_HAS_MULTIVALUE,
1242 NULL, HFILL }
1244 { &hf_packetbb_tlv_indexstart,
1245 { "Index start", "packetbb.tlv.indexstart",
1246 FT_UINT8, BASE_DEC, NULL, 0,
1247 NULL, HFILL }
1249 { &hf_packetbb_tlv_indexend,
1250 { "Index end", "packetbb.tlv.indexend",
1251 FT_UINT8, BASE_DEC, NULL, 0,
1252 NULL, HFILL }
1254 { &hf_packetbb_tlv_length,
1255 { "Length", "packetbb.tlv.length",
1256 FT_UINT16, BASE_DEC, NULL, 0,
1257 NULL, HFILL }
1259 { &hf_packetbb_tlv_value,
1260 { "Value", "packetbb.tlv.value",
1261 FT_BYTES, BASE_NONE, NULL, 0,
1262 NULL, HFILL }
1264 { &hf_packetbb_tlv_multivalue,
1265 { "Multivalue", "packetbb.tlv.multivalue",
1266 FT_BYTES, BASE_NONE, NULL, 0,
1267 NULL, HFILL }
1269 { &hf_packetbb_tlv_intervaltime,
1270 { "Signaling message interval", "packetbb.tlv.intervaltime",
1271 FT_UINT8, BASE_HEX, NULL, 0,
1272 NULL, HFILL }
1274 { &hf_packetbb_tlv_validitytime,
1275 { "Message validity time", "packetbb.tlv.validitytime",
1276 FT_UINT8, BASE_HEX, NULL, 0,
1277 NULL, HFILL }
1279 { &hf_packetbb_tlv_localifs,
1280 { "Local interface status", "packetbb.tlv.localifs",
1281 FT_UINT8, BASE_DEC, VALS(localif_vals), 0,
1282 NULL, HFILL }
1284 { &hf_packetbb_tlv_linkstatus,
1285 { "Link status", "packetbb.tlv.linkstatus",
1286 FT_UINT8, BASE_DEC, VALS(linkstatus_vals), 0,
1287 NULL, HFILL }
1289 { &hf_packetbb_tlv_otherneigh,
1290 { "Other neighbor status", "packetbb.tlv.otherneigh",
1291 FT_UINT8, BASE_DEC, VALS(otherneigh_vals), 0,
1292 NULL, HFILL }
1294 { &hf_packetbb_tlv_icv,
1295 { "Integrity Check Value", "packetbb.tlv.icv",
1296 FT_BYTES, BASE_NONE, NULL, 0,
1297 NULL, HFILL }
1299 { &hf_packetbb_tlv_timestamp,
1300 { "Timestamp", "packetbb.tlv.timestamp",
1301 FT_BYTES, BASE_NONE, NULL, 0,
1302 NULL, HFILL }
1304 { &hf_packetbb_tlv_mprwillingness,
1305 { "MPR willingness", "packetbb.tlv.mprwillingness",
1306 FT_UINT8, BASE_HEX, NULL, 0,
1307 NULL, HFILL }
1309 { &hf_packetbb_tlv_mprwillingness_flooding,
1310 { "Flooding", "packetbb.tlv.mprwillingnessflooding",
1311 FT_UINT8, BASE_DEC, NULL, 0xF0,
1312 NULL, HFILL }
1314 { &hf_packetbb_tlv_mprwillingness_routing,
1315 { "Routing", "packetbb.tlv.mprwillingnessrouting",
1316 FT_UINT8, BASE_DEC, NULL, 0x0F,
1317 NULL, HFILL }
1319 { &hf_packetbb_tlv_contseqnum,
1320 { "Content sequence number", "packetbb.tlv.contseqnum",
1321 FT_UINT16, BASE_HEX, NULL, 0,
1322 NULL, HFILL }
1324 { &hf_packetbb_tlv_linkmetric_flags_linkin,
1325 { "Incoming link", "packetbb.tlv.linkmetriclinkin",
1326 FT_BOOLEAN, 16, NULL, RFC7181_LINKMETRIC_INCOMING_LINK,
1327 NULL, HFILL }
1329 { &hf_packetbb_tlv_linkmetric_flags_linkout,
1330 { "Outgoing link", "packetbb.tlv.linkmetriclinkout",
1331 FT_BOOLEAN, 16, NULL, RFC7181_LINKMETRIC_OUTGOING_LINK,
1332 NULL, HFILL }
1334 { &hf_packetbb_tlv_linkmetric_flags_neighin,
1335 { "Incoming neighbor", "packetbb.tlv.linkmetricneighin",
1336 FT_BOOLEAN, 16, NULL, RFC7181_LINKMETRIC_INCOMING_NEIGH,
1337 NULL, HFILL }
1339 { &hf_packetbb_tlv_linkmetric_flags_neighout,
1340 { "Outgoing neighbor", "packetbb.tlv.linkmetricneighout",
1341 FT_BOOLEAN, 16, NULL, RFC7181_LINKMETRIC_OUTGOING_NEIGH,
1342 NULL, HFILL }
1344 { &hf_packetbb_tlv_linkmetric_value,
1345 { "Link metric", "packetbb.tlv.linkmetricvalue",
1346 FT_UINT16, BASE_HEX, NULL, 0,
1347 NULL, HFILL }
1349 { &hf_packetbb_tlv_mpr,
1350 { "Multipoint Relay", "packetbb.tlv.mpr",
1351 FT_UINT8, BASE_DEC, VALS(mpr_vals), 0,
1352 NULL, HFILL }
1354 { &hf_packetbb_tlv_nbraddrtype,
1355 { "Neighbor address type", "packetbb.tlv.nbraddrtype",
1356 FT_UINT8, BASE_DEC, VALS(nbraddrtype_vals), 0,
1357 NULL, HFILL }
1359 { &hf_packetbb_tlv_gateway,
1360 { "Gateway", "packetbb.tlv.gateway",
1361 FT_UINT8, BASE_DEC, NULL, 0,
1362 NULL, HFILL }
1366 /* Setup protocol subtree array */
1367 int *ett_base[] = {
1368 &ett_packetbb,
1369 &ett_packetbb_header,
1370 &ett_packetbb_header_flags,
1371 &ett_packetbb_msgheader,
1372 &ett_packetbb_msgheader_flags,
1373 &ett_packetbb_addr,
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;
1389 int i,j;
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
1412 * Local Variables:
1413 * c-basic-offset: 2
1414 * tab-width: 8
1415 * indent-tabs-mode: nil
1416 * End:
1418 * ex: set shiftwidth=2 tabstop=8 expandtab:
1419 * :indentSize=2:tabSize=8:noTabs=true: