2 * Routines for Peer Name Resolution Protocol (PNRP) dissection
4 * Copyright 2010, Jan Gerbecks <jan.gerbecks@stud.uni-due.de>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 /* The official Documentation for the Peer Name Resolution Protocol
14 * ([MS-PNRP]) can be found at
16 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pnrp
18 * This dissector is based on Revision 6.1.2
23 #include <epan/packet.h>
24 #include <epan/exceptions.h>
25 #include <epan/reassemble.h>
27 #define PROTONAME "Peer Name Resolution Protocol"
28 #define PROTOSHORTNAME "PNRP"
29 #define PROTOABBREV "pnrp"
31 #define PNRP_PORT 3540
33 #define FIELDID_LENGTH = 2
34 #define LENGTH_FIELD = 2
36 /* Define all FieldIDs here, so we can use them later on in switch statement etc */
37 #define PNRP_HEADER 0x0010
38 #define PNRP_HEADER_ACKED 0x0018
39 #define PNRP_ID 0x0030
40 #define TARGET_PNRP_ID 0x0038
41 #define VALIDATE_PNRP_ID 0x0039
42 #define FLAGS_FIELD 0x0040
43 #define FLOOD_CONTROLS 0x0043
44 #define SOLICIT_CONTROLS 0x0044
45 #define LOOKUP_CONTROLS 0x0045
46 #define EXTENDED_PAYLOAD 0x005A
47 #define PNRP_ID_ARRAY 0x0060
48 #define CERT_CHAIN 0x0080
50 #define CLASSIFIER 0x0085
51 #define HASHED_NONCE 0x0092
53 #define SPLIT_CONTROLS 0x0098
54 #define ROUTING_ENTRY 0x009A
55 #define VALIDATE_CPA 0x009B
56 #define REVOKE_CPA 0x009C
57 #define IPV6_ENDPOINT 0x009D
58 #define IPV6_ENDPOINT_ARRAY 0x009E
60 /* Define all message types */
62 #define ADVERTISE 0x02
66 #define AUTHORITY 0x08
70 /* Define flags mask fields */
71 #define FLAGS_INQUIRE_RESERVED1 0xFFE0
72 #define FLAGS_INQUIRE_A 0x0010
73 #define FLAGS_INQUIRE_X 0x0008
74 #define FLAGS_INQUIRE_C 0x0004
75 #define FLAGS_INQUIRE_RESERVED2 0x0003
77 #define FLAGS_AUTHORITY_RESERVED1 0xFC00
78 #define FLAGS_AUTHORITY_L 0x0200
79 #define FLAGS_AUTHORITY_RESERVED2 0x01F0
80 #define FLAGS_AUTHORITY_B 0x0008
81 #define FLAGS_AUTHORITY_RESERVED3 0x0006
82 #define FLAGS_AUTHORITY_N 0x0001
84 #define FLAGS_LOOKUPCONTROLS_RESERVED 0xFFFC
85 #define FLAGS_LOOKUPCONTROLS_A 0x0002
86 #define FLAGS_LOOKUPCONTROLS_0 0x0001
88 #define FLAGS_ENCODED_CPA_RESERVED 0xC0
89 #define FLAGS_ENCODED_CPA_X 0x20
90 #define FLAGS_ENCODED_CPA_U 0x02
91 #define FLAGS_ENCODED_CPA_R 0x01
92 #define FLAGS_ENCODED_CPA_A 0x04
93 #define FLAGS_ENCODED_CPA_C 0x08
94 #define FLAGS_ENCODED_CPA_F 0x10
96 void proto_register_pnrp(void);
97 void proto_reg_handoff_pnrp(void);
99 static dissector_handle_t pnrp_handle
;
101 /* Define all helper methods */
102 static void dissect_pnrp_ids(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
103 static void dissect_ipv6_address(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
104 static void dissect_route_entry(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
105 static void dissect_ipv6_endpoint_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
106 static void dissect_encodedCPA_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
107 static void dissect_payload_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
108 static void dissect_publicKey_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
109 static void dissect_signature_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
);
111 /* Define global variables
112 ----------------------------*/
113 static int proto_pnrp
;
115 /* Define FieldIDs */
116 static const value_string fieldID
[] = {
117 { PNRP_HEADER
, "PNRP_HEADER" },
118 { PNRP_HEADER_ACKED
, "PNRP_HEADER_ACKED" },
119 { PNRP_ID
, "PNRP_ID" },
120 { TARGET_PNRP_ID
, "TARGET_PNRP_ID" },
121 { VALIDATE_PNRP_ID
, "VALIDATE_PNRP_ID" },
122 { FLAGS_FIELD
, "FLAGS_FIELD" },
123 { FLOOD_CONTROLS
, "FLOOD_CONTROLS" },
124 { SOLICIT_CONTROLS
, "SOLICIT_CONTROLS" },
125 { LOOKUP_CONTROLS
, "LOOKUP_CONTROLS" },
126 { EXTENDED_PAYLOAD
, "EXTENDED_PAYLOAD" },
127 { PNRP_ID_ARRAY
, "PNRP_ID_ARRAY" },
128 { CERT_CHAIN
, "CERT_CHAIN" },
130 { CLASSIFIER
, "CLASSIFIER" },
131 { HASHED_NONCE
, "HASHED_NONCE" },
133 { SPLIT_CONTROLS
, "SPLIT_CONTROLS" },
134 { ROUTING_ENTRY
, "ROUTING_ENTRY" },
135 { VALIDATE_CPA
, "VALIDATE_CPA" },
136 { REVOKE_CPA
, "REVOKE_CPA" },
137 { IPV6_ENDPOINT
, "IPV6_ENDPOINT" },
138 { IPV6_ENDPOINT_ARRAY
, "IPV6_ENDPOINT_ARRAY" },
142 /* Define Packetnames */
143 static const value_string messageType
[] = {
144 { SOLICIT
, "SOLICIT" },
145 { ADVERTISE
, "ADVERTISE" },
146 { REQUEST
, "REQUEST" },
148 { INQUIRE
, "INQUIRE" },
149 { AUTHORITY
, "AUTHORITY" },
151 { LOOKUP
, "LOOKUP" },
154 /* Define Solicit Type */
155 static const value_string solicitType
[] = {
156 { 0x00, "SOLICIT_TYPE_ANY" },
157 { 0x01, "SOLICIT_TYPE_LOCAL" },
160 /* Define Resolve Criteria for Lookup Controls */
161 static const value_string resolveCriteria
[] = {
162 { 0x00, "SEARCH_OPCODE_NONE" },
163 { 0x01, "SEARCH_OPCODE_ANY_PEERNAME" },
164 { 0x02, "SEARCH_OPCODE_NEAREST_PEERNAME" },
165 { 0x04, "SEARCH_OPCODE_NEAREST64_PEERNAME" },
166 { 0x08, "SEARCH_OPCODE_UPPER_BITS" },
169 /* Define Reason Code for Lookup Controls */
170 static const value_string reasonCode
[] = {
171 { 0x00, "REASON_APP_REQUEST" },
172 { 0x01, "REASON_REGISTRATION" },
173 { 0x02, "REASON_CACHE_MAINTENANCE" },
174 { 0x03, "REASON_SPLIT_DETECTION" },
178 /* Define IDs for subcomponents */
180 static int hf_pnrp_header
;
181 static int hf_pnrp_header_fieldID
;
182 static int hf_pnrp_header_length
;
183 static int hf_pnrp_header_ident
;
184 static int hf_pnrp_header_versionMajor
;
185 static int hf_pnrp_header_versionMinor
;
186 static int hf_pnrp_header_messageType
;
187 static int hf_pnrp_header_messageID
;
189 static int hf_pnrp_message_type
;
190 static int hf_pnrp_message_length
;
191 static int hf_pnrp_message_headerack
;
192 static int hf_pnrp_message_pnrpID
; /* Generic variable to display pnrp ID in various situations */
193 /* Inquire Message Flags */
194 static int hf_pnrp_message_inquire_flags
;
195 static int hf_pnrp_message_inquire_flags_reserved1
;
196 static int hf_pnrp_message_inquire_flags_Abit
;
197 static int hf_pnrp_message_inquire_flags_Xbit
;
198 static int hf_pnrp_message_inquire_flags_Cbit
;
199 static int hf_pnrp_message_inquire_flags_reserved2
;
201 static int hf_pnrp_padding
;
203 static int * const inquire_flags
[] = {
204 &hf_pnrp_message_inquire_flags_reserved1
,
205 &hf_pnrp_message_inquire_flags_Abit
,
206 &hf_pnrp_message_inquire_flags_Xbit
,
207 &hf_pnrp_message_inquire_flags_Cbit
,
208 &hf_pnrp_message_inquire_flags_reserved2
,
213 static int hf_pnrp_message_classifier_unicodeCount
;
214 static int hf_pnrp_message_classifier_arrayLength
;
215 static int hf_pnrp_message_classifier_entryLength
;
216 static int hf_pnrp_message_classifier_string
;
217 /* ACK Message Flags */
218 static int hf_pnrp_message_ack_flags_reserved
;
219 static int hf_pnrp_message_ack_flags_Nbit
;
221 static int hf_pnrp_message_splitControls_authorityBuffer
;
222 /* IPv6 Endpoint Array */
223 static int hf_pnrp_message_ipv6EndpointArray_NumberOfEntries
;
224 static int hf_pnrp_message_ipv6EndpointArray_ArrayLength
;
225 static int hf_pnrp_message_ipv6EndpointArray_EntryLength
;
226 /* AUTHORITY Message Flags */
227 static int hf_pnrp_message_authority_flags
;
228 static int hf_pnrp_message_authority_flags_reserved1
;
229 static int hf_pnrp_message_authority_flags_Lbit
;
230 static int hf_pnrp_message_authority_flags_reserved2
;
231 static int hf_pnrp_message_authority_flags_Bbit
;
232 static int hf_pnrp_message_authority_flags_reserved3
;
233 static int hf_pnrp_message_authority_flags_Nbit
;
235 static int * const authority_flags
[] = {
236 &hf_pnrp_message_authority_flags_reserved1
,
237 &hf_pnrp_message_authority_flags_Lbit
,
238 &hf_pnrp_message_authority_flags_reserved2
,
239 &hf_pnrp_message_authority_flags_Bbit
,
240 &hf_pnrp_message_authority_flags_reserved3
,
241 &hf_pnrp_message_authority_flags_Nbit
,
245 /* Flood Control Flags */
246 static int hf_pnrp_message_flood_flags_reserved1
;
247 static int hf_pnrp_message_flood_flags_Dbit
;
250 static int hf_pnrp_message_idArray_NumEntries
;
251 static int hf_pnrp_message_idArray_Length
;
252 static int hf_pnrp_message_ElementFieldType
;
253 static int hf_pnrp_message_idarray_Entrylength
;
255 static int hf_pnrp_message_solicitType
;
256 static int hf_pnrp_message_certChain
;
257 static int hf_pnrp_message_nonce
;
258 static int hf_pnrp_message_hashednonce
;
259 static int hf_pnrp_message_ipv6
;
262 static int hf_pnrp_encodedCPA
;
263 static int hf_pnrp_encodedCPA_length
;
264 static int hf_pnrp_encodedCPA_minorVersion
;
265 static int hf_pnrp_encodedCPA_majorVersion
;
266 static int hf_pnrp_encodedCPA_flags
;
267 static int hf_pnrp_encodedCPA_flags_reserved
;
268 static int hf_pnrp_encodedCPA_flags_Xbit
;
269 static int hf_pnrp_encodedCPA_flags_Fbit
;
270 static int hf_pnrp_encodedCPA_flags_Cbit
;
271 static int hf_pnrp_encodedCPA_flags_Abit
;
272 static int hf_pnrp_encodedCPA_flags_Ubit
;
273 static int hf_pnrp_encodedCPA_flags_Rbit
;
274 static int * const encodedCPA_flags
[] = {
275 &hf_pnrp_encodedCPA_flags_reserved
,
276 &hf_pnrp_encodedCPA_flags_Xbit
,
277 &hf_pnrp_encodedCPA_flags_Fbit
,
278 &hf_pnrp_encodedCPA_flags_Cbit
,
279 &hf_pnrp_encodedCPA_flags_Abit
,
280 &hf_pnrp_encodedCPA_flags_Ubit
,
281 &hf_pnrp_encodedCPA_flags_Rbit
,
284 static int hf_pnrp_encodedCPA_notAfter
;
285 static int hf_pnrp_encodedCPA_serviceLocation
;
286 static int hf_pnrp_encodedCPA_binaryAuthority
;
287 static int hf_pnrp_encodedCPA_classifierHash
;
288 static int hf_pnrp_encodedCPA_friendlyName
;
290 /* Lookup Controls */
291 static int hf_pnrp_message_lookupControls_flags
;
292 static int hf_pnrp_message_lookupControls_flags_reserved
;
293 static int hf_pnrp_message_lookupControls_flags_Abit
;
294 static int hf_pnrp_message_lookupControls_flags_0bit
;
295 static int * const lookupControls_flags
[] = {
296 &hf_pnrp_message_lookupControls_flags_reserved
,
297 &hf_pnrp_message_lookupControls_flags_Abit
,
298 &hf_pnrp_message_lookupControls_flags_0bit
,
301 static int hf_pnrp_message_lookupControls_precision
;
302 static int hf_pnrp_message_lookupControls_resolveCriteria
;
303 static int hf_pnrp_message_lookupControls_reasonCode
;
305 /* Dissect Route Entry */
306 static int hf_pnrp_message_routeEntry_portNumber
;
307 static int hf_pnrp_message_routeEntry_flags
;
308 static int hf_pnrp_message_routeEntry_addressCount
;
310 /* Public Key Structure */
311 static int hf_pnrp_publicKey_objID
;
312 static int hf_pnrp_publicKey_publicKeyData
;
314 /* Signature Structure */
315 static int hf_pnrp_signature_signatureData
;
317 /* Generated from convert_proto_tree_add_text.pl */
318 static int hf_pnrp_payload_port
;
319 static int hf_pnrp_signature_length
;
320 static int hf_pnrp_signature_structure_length
;
321 static int hf_pnrp_encodedCPA_total_bytes_of_payload
;
322 static int hf_pnrp_signature_hash_id
;
323 static int hf_pnrp_message_flags
;
324 static int hf_pnrp_encodedCPA_number_of_service_addresses
;
325 static int hf_pnrp_payload_iana_proto
;
326 static int hf_pnrp_reserved8
;
327 static int hf_pnrp_reserved16
;
328 static int hf_pnrp_encodedCPA_service_address_length
;
329 static int hf_pnrp_message_data
;
330 static int hf_pnrp_publicKey_length_of_structure
;
331 static int hf_pnrp_publicKey_size_of_cbdata
;
332 static int hf_pnrp_payload_type
;
333 static int hf_pnrp_publicKey_size_of_algorithm_oid
;
334 static int hf_pnrp_message_port_number
;
335 static int hf_pnrp_publicKey_reserved
;
336 static int hf_pnrp_encodedCPA_friendlyName_length
;
337 static int hf_pnrp_message_offset
;
338 static int hf_pnrp_publicKey_unused_bits
;
339 static int hf_pnrp_length_of_data
;
340 static int hf_pnrp_encodedCPA_number_of_payload_structures
;
343 static int hf_pnrp_fragments
;
344 static int hf_pnrp_fragment
;
345 static int hf_pnrp_fragment_overlap
;
346 static int hf_pnrp_fragment_overlap_conflict
;
347 static int hf_pnrp_fragment_multiple_tails
;
348 static int hf_pnrp_fragment_too_long_fragment
;
349 static int hf_pnrp_fragment_error
;
350 static int hf_pnrp_fragment_count
;
351 static int hf_pnrp_reassembled_in
;
352 static int hf_pnrp_reassembled_length
;
353 static int hf_pnrp_reassembled_data
;
354 static int hf_pnrp_fragmented_payload
;
356 /* Define variables to reference subtrees */
358 static int ett_pnrp_header
;
359 static int ett_pnrp_message
;
360 static int ett_pnrp_message_inquire_flags
;
361 static int ett_pnrp_message_authority_flags
;
362 static int ett_pnrp_message_encodedCPA
;
363 static int ett_pnrp_message_encodedCPA_flags
;
364 static int ett_pnrp_message_lookupControls_flags
;
365 static int ett_pnrp_message_payloadStructure
;
366 static int ett_pnrp_message_publicKeyStructure
;
367 static int ett_pnrp_message_signatureStructure
;
368 static int ett_pnrp_fragment
;
369 static int ett_pnrp_fragments
;
371 static reassembly_table pnrp_reassembly_table
;
373 static const fragment_items pnrp_frag_items
= {
378 &hf_pnrp_fragment_overlap
,
379 &hf_pnrp_fragment_overlap_conflict
,
380 &hf_pnrp_fragment_multiple_tails
,
381 &hf_pnrp_fragment_too_long_fragment
,
382 &hf_pnrp_fragment_error
,
383 &hf_pnrp_fragment_count
,
384 &hf_pnrp_reassembled_in
,
385 &hf_pnrp_reassembled_length
,
386 &hf_pnrp_reassembled_data
,
390 /* Do actual dissection work */
391 static int dissect_pnrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
393 /* Variable declaration */
394 int offset
, start_offset
;
396 uint8_t message_type
;
398 unsigned data_length
;
400 proto_tree
*pnrp_tree
;
401 proto_item
*pnrp_header_item
;
402 proto_tree
*pnrp_header_tree
;
403 proto_item
*pnrp_message_tree
= NULL
;
406 /*----------------------------------------
407 * Validate if it is really a PNRP Packet
408 *----------------------------------------*/
409 /* Check that there's enough data */
410 data_length
= tvb_captured_length(tvb
);
412 /* Shortest Message is ACK -> 12 Bytes for Header plus 8 Bytes for Data */
413 if (data_length
< 12+8 )
418 /* Check some values from the packet header */
419 /* First 2 bytes must be 0x0010 */
420 if (tvb_get_ntohs(tvb
,0) != PNRP_HEADER
)
424 /* Length of Header must be 0x000C = 12 */
425 if (tvb_get_ntohs(tvb
,2) != 0x000C) {
428 /* Identifier must 0x51 */
429 if (tvb_get_uint8(tvb
,4) != 0x51) {
434 /* Assign Values to Variables */
435 /* Use to track data */
437 /* Get the message Information beforehand */
438 message_type
= tvb_get_uint8(tvb
,7);
441 /* Simply Display the Protocol Name in the INFO column */
442 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "PNRP");
443 /* Clear out stuff in the info column */
444 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "PNRP %s Message ",
445 val_to_str(message_type
, messageType
, "Unknown (0x%02x)"));
448 /* Lets add a subtree to our dissection to display the info */
449 ti
= proto_tree_add_item(tree
, proto_pnrp
, tvb
, 0, -1, ENC_NA
);
450 proto_item_append_text(ti
, ", Message Type %s",
451 val_to_str(message_type
, messageType
, "Unknown (0x%02x)"));
452 /* Get a main tree for the whole protocol */
453 pnrp_tree
= proto_item_add_subtree(ti
, ett_pnrp
);
455 /*-------------------------------
456 *--Add all Header Fields
457 *------------------------------*/
458 /* Get a subtree for the Header */
459 pnrp_header_item
= proto_tree_add_item(pnrp_tree
, hf_pnrp_header
, tvb
, offset
,12,ENC_NA
);
460 pnrp_header_tree
= proto_item_add_subtree(pnrp_header_item
, ett_pnrp_header
);
462 /* Add Field ID should be 0c0010 */
463 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_fieldID
,tvb
,offset
,2,ENC_BIG_ENDIAN
);
465 /* Add Length should be 0x000C */
466 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_length
,tvb
,offset
,2,ENC_BIG_ENDIAN
);
468 /* Add Ident should be 0x51 */
469 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_ident
,tvb
,offset
,1,ENC_BIG_ENDIAN
);
471 /* Add Major Version */
472 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_versionMajor
,tvb
,offset
,1,ENC_BIG_ENDIAN
);
474 /* Add Minor Version */
475 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_versionMinor
,tvb
,offset
,1,ENC_BIG_ENDIAN
);
477 /* Add Message Type */
478 proto_tree_add_item(pnrp_header_tree
,hf_pnrp_header_messageType
,tvb
,offset
,1,ENC_BIG_ENDIAN
);
481 proto_tree_add_item_ret_uint(pnrp_header_tree
,hf_pnrp_header_messageID
,tvb
,offset
,4,ENC_BIG_ENDIAN
,&msg_id
);
485 /*-------------------------------
486 *--Add all Message Fields
487 *------------------------------*/
489 /* The following part has dynamic length depending on message type */
490 start_offset
= offset
;
491 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
492 /* Determine the Field Type */
493 field_type
= tvb_get_ntohs(tvb
,offset
);
494 /* Determine length of this message */
495 data_length
= tvb_get_ntohs(tvb
,offset
+ 2);
497 /* Length must be at least 4, because field_type and data_length are part of data_length information */
498 if (data_length
< 4) {
500 pnrp_message_tree
= proto_tree_add_subtree_format(pnrp_tree
, tvb
, offset
, 4, ett_pnrp_message
, NULL
,
501 "Message with invalid length %u (< 4)", data_length
);
502 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
503 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
506 /* Don't continue parsing this message segment */
509 /* Actual Parsing of the message Type */
510 switch (field_type
) {
511 /* First Field in ACK Message */
512 case PNRP_HEADER_ACKED
:
514 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
515 data_length
, ett_pnrp_message
, NULL
, "Message ACK ID: ");
516 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
517 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
518 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_headerack
, tvb
, offset
+ 4, data_length
-4, ENC_BIG_ENDIAN
);
521 offset
+= data_length
;
524 /* A validate pnrp id follows as found in FLOOD */
525 case VALIDATE_PNRP_ID
:
527 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
528 data_length
, ett_pnrp_message
, NULL
, "Validate PNRP ID: ");
529 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
530 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
531 /* We can have a large number of pnrp IDs here */
532 dissect_pnrp_ids(tvb
,offset
+4,data_length
-4,pnrp_message_tree
);
535 offset
+= data_length
;
538 /* The Flags have different meaning, depending on the message */
541 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
542 data_length
, ett_pnrp_message
, NULL
, "Flags Field: ");
543 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
544 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
546 switch (message_type
) {
548 proto_tree_add_bitmask(pnrp_message_tree
, tvb
, offset
+4, hf_pnrp_message_inquire_flags
, ett_pnrp_message_inquire_flags
, inquire_flags
, ENC_BIG_ENDIAN
);
549 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ 6, 2, ENC_NA
);
550 offset
+= data_length
+2;
555 /* Reserved 0 - 14 bits */
556 proto_tree_add_bits_item(pnrp_message_tree
, hf_pnrp_message_ack_flags_reserved
, tvb
, (offset
+ 4)*8, 15, ENC_BIG_ENDIAN
);
558 proto_tree_add_bits_item(pnrp_message_tree
, hf_pnrp_message_ack_flags_Nbit
, tvb
,((offset
+ 4)*8)+15, 1, ENC_BIG_ENDIAN
);
559 offset
+= data_length
;
562 proto_tree_add_bitmask(pnrp_message_tree
, tvb
, offset
+4, hf_pnrp_message_authority_flags
, ett_pnrp_message_authority_flags
, authority_flags
, ENC_BIG_ENDIAN
);
563 /* Check if the Flags Field is the last message part. If so, no padding of 2 bytes is added */
564 if(tvb_reported_length_remaining(tvb
, offset
+data_length
)==0)
566 offset
+= data_length
;
570 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ 6, padding_bytes
, ENC_NA
);
571 offset
+= data_length
+2;
576 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_flags
, tvb
, offset
+ 4, data_length
-4, ENC_BIG_ENDIAN
);
577 offset
+= data_length
;
582 /* Flood controls found in FLOOD Message */
585 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
586 data_length
, ett_pnrp_message
, NULL
, "Flood Control: ");
587 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
588 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
589 /* Reserved 1 - 15 bits */
590 proto_tree_add_bits_item(pnrp_message_tree
, hf_pnrp_message_flood_flags_reserved1
, tvb
, (offset
+ 4)*8, 15, ENC_BIG_ENDIAN
);
592 proto_tree_add_bits_item(pnrp_message_tree
, hf_pnrp_message_flood_flags_Dbit
, tvb
,((offset
+ 4)*8)+15, 1, ENC_BIG_ENDIAN
);
594 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_reserved8
, tvb
, offset
+ 6, 1, ENC_NA
);
596 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ 7, 1, ENC_NA
);
599 offset
+= data_length
+1;
602 /* Solicit Controls found in SOLICIT Message */
603 case SOLICIT_CONTROLS
:
605 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
606 data_length
, ett_pnrp_message
, NULL
, "Solicit Controls: ");
607 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
608 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
609 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_reserved8
, tvb
, offset
+ 4, 1, ENC_NA
);
610 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_solicitType
, tvb
, offset
+ 5, 1, ENC_BIG_ENDIAN
);
611 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_reserved16
, tvb
, offset
+ 6, 2, ENC_LITTLE_ENDIAN
);
613 offset
+= data_length
+2; /* Padding involved */
615 /* Lookup controls found in LOOKUP Message */
616 case LOOKUP_CONTROLS
:
618 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
619 data_length
, ett_pnrp_message
, NULL
, "Lookup Control: ");
620 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
621 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
622 /* 2 Bytes of Flags */
623 proto_tree_add_bitmask(pnrp_message_tree
, tvb
, offset
+4, hf_pnrp_message_lookupControls_flags
, ett_pnrp_message_lookupControls_flags
, lookupControls_flags
, ENC_BIG_ENDIAN
);
624 /* Precision Bytes */
625 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_lookupControls_precision
, tvb
, offset
+ 6, 2, ENC_BIG_ENDIAN
);
626 /* Resolve Criteria */
627 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_lookupControls_resolveCriteria
, tvb
, offset
+ 8, 1, ENC_BIG_ENDIAN
);
629 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_lookupControls_reasonCode
, tvb
, offset
+ 9, 1, ENC_BIG_ENDIAN
);
631 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_reserved16
, tvb
, offset
+ 10, 2, ENC_LITTLE_ENDIAN
);
635 offset
+= data_length
;
637 /* Target PNRP ID found in Lookup Message */
640 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
641 data_length
, ett_pnrp_message
, NULL
, "Target PNRP ID: ");
642 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
643 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
644 dissect_pnrp_ids(tvb
, offset
+4, data_length
-4, pnrp_message_tree
);
647 offset
+= data_length
;
650 /* Extended Payload found in AUTHORITY Message */
651 case EXTENDED_PAYLOAD
:
653 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
654 data_length
, ett_pnrp_message
, NULL
, "Extended Payload: ");
655 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
656 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
657 /* TODO: Do actual parsing */
660 offset
+= data_length
;
662 /* Pnrp id Array as found in REQUEST & ADVERTISE Message */
665 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
666 data_length
, ett_pnrp_message
, NULL
, "PNRP ID Array: ");
667 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
668 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
669 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_idArray_NumEntries
, tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
670 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_idArray_Length
, tvb
, offset
+ 6, 2, ENC_BIG_ENDIAN
);
671 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_ElementFieldType
, tvb
, offset
+ 8, 2, ENC_BIG_ENDIAN
);
672 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_idarray_Entrylength
, tvb
, offset
+ 10, 2, ENC_BIG_ENDIAN
);
673 dissect_pnrp_ids(tvb
,offset
+12,data_length
-12,pnrp_message_tree
);
676 offset
+= data_length
;
678 /* Cert Chain follows as found in AUTHORITY */
681 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
682 data_length
, ett_pnrp_message
, NULL
, "CERT Chain: ");
683 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
684 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
685 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_certChain
, tvb
, offset
+ 4, data_length
-4, ENC_NA
);
688 /* There might be padding, so fill up to the next byte */
690 while (data_length
%4 != 0 &&tvb_reported_length_remaining(tvb
, offset
+data_length
)>0) {
694 /* Check if we actually had some padding bytes */
695 if (0<padding_bytes
) {
696 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ data_length
-padding_bytes
, padding_bytes
, ENC_NA
);
698 offset
+= data_length
;
700 /* classifier: A classifier string follows as found in AUTHORITY */
703 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
704 data_length
, ett_pnrp_message
, NULL
, "Classifier: ");
705 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
706 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
708 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_classifier_unicodeCount
, tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
709 /* Array Length: 8+(NumEntries*EntryLength */
710 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_classifier_arrayLength
, tvb
, offset
+ 6, 2, ENC_BIG_ENDIAN
);
711 /* Element Field Type: WCHAR */
712 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
+8 , 2, ENC_BIG_ENDIAN
);
713 /* Entry Length: Must be 0x0002 */
714 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_classifier_entryLength
, tvb
, offset
+ 10, 2, ENC_BIG_ENDIAN
);
715 /* The actual classifier String */
716 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_classifier_string
, tvb
, offset
+ 12, tvb_get_ntohs(tvb
,offset
+6)-8, ENC_UTF_16
|ENC_BIG_ENDIAN
);
719 /* There might be padding, so fill up to the next byte */
721 while (data_length
%4 != 0 &&tvb_reported_length_remaining(tvb
, offset
+data_length
)>0) {
725 /* Check if we actually had some padding bytes */
726 if (0<padding_bytes
) {
727 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ data_length
-padding_bytes
, padding_bytes
, ENC_NA
);
729 offset
+= data_length
;
731 /* A hashed nonce follows as found in ADVERTISE & SOLICIT */
734 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
735 data_length
, ett_pnrp_message
, NULL
, "Hashed Nonce: ");
736 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
737 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
738 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_hashednonce
, tvb
, offset
+ 4, data_length
-4, ENC_NA
);
742 offset
+= data_length
;
745 /* A nonce follows as found in REQUEST & INQUIRE */
748 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
749 data_length
, ett_pnrp_message
, NULL
, "Nonce: ");
750 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
751 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
752 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_nonce
, tvb
, offset
+ 4, data_length
-4, ENC_NA
);
755 offset
+= data_length
;
758 /* split controls as found in AUTHORITY */
761 fragment_head
*frag_data
;
763 uint32_t buffer_len
, frag_offset
, remaining_len
;
766 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
767 data_length
, ett_pnrp_message
, NULL
, "Split controls: ");
768 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
769 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
771 /* Size of Authority Buffer */
772 proto_tree_add_item_ret_uint(pnrp_message_tree
, hf_pnrp_message_splitControls_authorityBuffer
,
773 tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
, &buffer_len
);
775 proto_tree_add_item_ret_uint(pnrp_message_tree
, hf_pnrp_message_offset
,
776 tvb
, offset
+ 6, 2, ENC_BIG_ENDIAN
, &frag_offset
);
777 offset
+= data_length
;
778 remaining_len
= tvb_reported_length_remaining(tvb
, offset
);
780 frag_data
= fragment_add_check(&pnrp_reassembly_table
, tvb
, offset
, pinfo
,
781 msg_id
, NULL
, frag_offset
, remaining_len
,
782 (buffer_len
!= (frag_offset
+ remaining_len
)));
783 frag_tvb
= process_reassembled_data(tvb
, offset
, pinfo
, "Reassembled PNRP message",
784 frag_data
, &pnrp_frag_items
, NULL
, pnrp_message_tree
);
789 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_fragmented_payload
, tvb
, offset
, -1, ENC_NA
);
790 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Fragmented message]");
791 return tvb_captured_length(tvb
);
796 /* routing entry: A route entry follows as found in ADVERTISE, INQUIRE, LOOKUP & AUTHORITY */
799 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
800 data_length
, ett_pnrp_message
, NULL
, "Routing Entry: ");
801 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
802 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
803 dissect_route_entry(tvb
,offset
+4, tvb_get_ntohs(tvb
,offset
+2)-4, pnrp_message_tree
);
806 /* There might be padding, so fill up to the next byte */
808 while (data_length
%4 != 0 &&tvb_reported_length_remaining(tvb
, offset
+data_length
)>0) {
812 /* Check if we actually had some padding bytes */
813 if (0<padding_bytes
) {
814 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_padding
, tvb
, offset
+ data_length
-padding_bytes
, padding_bytes
, ENC_NA
);
816 offset
+= data_length
;
819 /* validate cpa: an encoded CPA structure follows as found in AUTHORITY */
822 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
823 data_length
, ett_pnrp_message
, NULL
, "Validate CPA: ");
824 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
825 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
826 /* Do the actual parsing in own method */
827 dissect_encodedCPA_structure(tvb
, offset
+4, data_length
-4, pnrp_message_tree
);
831 offset
+= data_length
;
835 /* IPV6 Endpoint: an ipv6 endpoint array structure follows as found in LOOKUP */
836 case IPV6_ENDPOINT_ARRAY
:
838 pnrp_message_tree
= proto_tree_add_subtree(pnrp_tree
, tvb
, offset
,
839 data_length
, ett_pnrp_message
, NULL
, "IPv6 Endpoint Array: ");
840 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
841 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
842 /* Number of route entries */
843 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_ipv6EndpointArray_NumberOfEntries
, tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
845 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_ipv6EndpointArray_ArrayLength
, tvb
, offset
+ 6, 2, ENC_BIG_ENDIAN
);
846 /* Element Field Type */
847 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
+8 , 2, ENC_BIG_ENDIAN
);
848 /* Entry Length: must be 0x0012 (18 bytes) */
849 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_ipv6EndpointArray_EntryLength
, tvb
, offset
+ 10, 2, ENC_BIG_ENDIAN
);
851 dissect_ipv6_endpoint_structure(tvb
, offset
+12, tvb_get_ntohs(tvb
,offset
+6)-8,pnrp_message_tree
);
854 offset
+= data_length
;
859 pnrp_message_tree
= proto_tree_add_subtree_format(pnrp_tree
, tvb
, offset
,
860 data_length
, ett_pnrp_message
, NULL
, "Type: %s, length: %u",
861 val_to_str(field_type
, fieldID
, "Unknown (0x%04x)"), data_length
);
862 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
863 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_length
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
866 proto_tree_add_item(pnrp_message_tree
, hf_pnrp_message_data
, tvb
, offset
+ 4, data_length
-4, ENC_NA
);
872 offset
+= data_length
;
875 // SPLIT_CONTROLS might reset our offset.
876 if (start_offset
<= offset
) {
877 THROW(ReportedBoundsError
);
884 /*--------------------------------------------------------------*
885 * Dissecting helper methods *
886 *--------------------------------------------------------------*/
888 static void dissect_pnrp_ids(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
890 while (32 <=length
) {
891 proto_tree_add_item(tree
, hf_pnrp_message_pnrpID
, tvb
, offset
, 32, ENC_NA
);
898 static void dissect_route_entry(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
901 /* Check if we don't run out of data */
902 if (0 <= tvb_reported_length_remaining(tvb
, offset
+length
)) {
904 /* First, we have a 32 Bit long PNRP ID */
905 proto_tree_add_item(tree
, hf_pnrp_message_pnrpID
, tvb
, offset
+tmp_offset
, 32, ENC_NA
);
907 /* Add PNRP Major Version */
908 proto_tree_add_item(tree
,hf_pnrp_header_versionMajor
,tvb
,offset
+tmp_offset
,1,ENC_BIG_ENDIAN
);
910 /* Add Minor Version */
911 proto_tree_add_item(tree
,hf_pnrp_header_versionMinor
,tvb
,offset
+tmp_offset
,1,ENC_BIG_ENDIAN
);
914 proto_tree_add_item(tree
,hf_pnrp_message_routeEntry_portNumber
,tvb
,offset
+tmp_offset
,2,ENC_BIG_ENDIAN
);
917 proto_tree_add_item(tree
,hf_pnrp_message_routeEntry_flags
,tvb
,offset
+tmp_offset
,1,ENC_BIG_ENDIAN
);
920 proto_tree_add_item(tree
,hf_pnrp_message_routeEntry_addressCount
,tvb
,offset
+tmp_offset
,1,ENC_BIG_ENDIAN
);
923 dissect_ipv6_address(tvb
, offset
+tmp_offset
, length
-tmp_offset
, tree
);
927 static void dissect_ipv6_endpoint_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
929 /* Check if we don't run out of data */
930 while (0 <= tvb_reported_length_remaining(tvb
, offset
+18) && 18 <=length
) {
932 proto_tree_add_item(tree
, hf_pnrp_message_port_number
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
934 dissect_ipv6_address(tvb
, offset
+2,16,tree
);
940 static void dissect_ipv6_address(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
942 while (0 <= tvb_reported_length_remaining(tvb
, offset
+16) && 16 <=length
) {
943 proto_tree_add_item(tree
, hf_pnrp_message_ipv6
, tvb
, offset
, 16, ENC_NA
);
949 static void dissect_encodedCPA_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
951 /* Check if we don't run out of data */
952 if (0 <= tvb_reported_length_remaining(tvb
, offset
+length
)) {
954 /* Add a new subtree */
955 proto_item
*pnrp_encodedCPA_tree
= NULL
;
956 proto_item
*pnrp_encodedCPA_item
= NULL
;
957 pnrp_encodedCPA_item
= proto_tree_add_item(tree
, hf_pnrp_encodedCPA
, tvb
, offset
,length
,ENC_NA
);
958 pnrp_encodedCPA_tree
= proto_item_add_subtree(pnrp_encodedCPA_item
, ett_pnrp_message_encodedCPA
);
960 /* Length information */
961 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
962 /* CPA Minor Version */
963 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_minorVersion
, tvb
, offset
+2, 1, ENC_BIG_ENDIAN
);
964 /* CPA Major Version */
965 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_majorVersion
, tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
966 /* PNRP Minor Version */
967 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_header_versionMinor
, tvb
, offset
+4, 1, ENC_BIG_ENDIAN
);
968 /* PNRP Major Version */
969 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_header_versionMajor
, tvb
, offset
+5, 1, ENC_BIG_ENDIAN
);
971 proto_tree_add_bitmask(pnrp_encodedCPA_tree
, tvb
, offset
+6, hf_pnrp_encodedCPA_flags
, ett_pnrp_message_encodedCPA_flags
, encodedCPA_flags
, ENC_BIG_ENDIAN
);
972 flagsField
= tvb_get_uint8(tvb
,offset
+6);
974 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_reserved8
, tvb
, offset
+ 7, 1, ENC_NA
);
976 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_notAfter
, tvb
, offset
+8, 8, ENC_BIG_ENDIAN
);
977 /* Service Location */
978 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_serviceLocation
, tvb
, offset
+16, 16, ENC_NA
);
980 /* now, the structure is variable, so add bytes to offset */
983 /* Check if R Flag is set */
984 if ((flagsField
& FLAGS_ENCODED_CPA_R
)==0x00) {
986 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_message_nonce
, tvb
, offset
, 16, ENC_NA
);
989 /* Check if A Flag is set */
990 if (flagsField
& FLAGS_ENCODED_CPA_A
) {
991 /* Binary authority */
992 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_binaryAuthority
, tvb
, offset
, 20, ENC_NA
);
995 /* Check if C Flag is set */
996 if (flagsField
& FLAGS_ENCODED_CPA_C
) {
997 /* Classifier Hash */
998 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_classifierHash
, tvb
, offset
, 20, ENC_NA
);
1001 /* Check if F Flag is set */
1002 if (flagsField
& FLAGS_ENCODED_CPA_F
) {
1003 /* Friendly Name Length */
1004 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_friendlyName_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1006 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_friendlyName
, tvb
, offset
+2, tvb_get_letohs(tvb
,offset
), ENC_ASCII
);
1007 offset
+=tvb_get_letohs(tvb
,offset
)+2;
1009 /* Service Address List */
1010 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_number_of_service_addresses
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1012 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_service_address_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1014 /* A list of IPV6_Endpoint Structures follows */
1015 dissect_ipv6_endpoint_structure(tvb
, offset
,tvb_get_letohs(tvb
,offset
-4)*tvb_get_letohs(tvb
,offset
-2) , pnrp_encodedCPA_tree
);
1016 offset
+= tvb_get_letohs(tvb
,offset
-4)*tvb_get_letohs(tvb
,offset
-2);
1017 /* A number of Payload Structures */
1018 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_number_of_payload_structures
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1020 proto_tree_add_item(pnrp_encodedCPA_tree
, hf_pnrp_encodedCPA_total_bytes_of_payload
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1022 dissect_payload_structure(tvb
,offset
, tvb_get_letohs(tvb
,offset
-2)-4,pnrp_encodedCPA_tree
);
1023 offset
+= tvb_get_letohs(tvb
,offset
-2)-4;
1025 dissect_publicKey_structure(tvb
, offset
,tvb_get_letohs(tvb
,offset
),pnrp_encodedCPA_tree
);
1026 offset
+= tvb_get_letohs(tvb
,offset
);
1028 dissect_signature_structure(tvb
, offset
,tvb_get_letohs(tvb
,offset
),pnrp_encodedCPA_tree
);
1029 /*offset += tvb_get_letohs(tvb,offset);*/
1032 static void dissect_payload_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
1034 uint16_t lengthOfData
;
1035 /* Add a new Subtree */
1036 proto_item
*pnrp_payload_tree
;
1037 /* Check if we actually should display something */
1041 pnrp_payload_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, length
, ett_pnrp_message_payloadStructure
, NULL
, "Payload Structure");
1043 /* Dissect the Payload Structure */
1045 proto_tree_add_item(pnrp_payload_tree
, hf_pnrp_payload_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1048 lengthOfData
= tvb_get_letohs(tvb
,offset
);
1049 proto_tree_add_item(pnrp_payload_tree
, hf_pnrp_length_of_data
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1051 /* IPV6_APP_ENDPOINT Structure */
1052 while (0 <= tvb_reported_length_remaining(tvb
, offset
+20)&& 20 <= lengthOfData
) {
1053 dissect_ipv6_address(tvb
, offset
, 16, pnrp_payload_tree
);
1055 proto_tree_add_item(pnrp_payload_tree
, hf_pnrp_payload_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1057 proto_tree_add_item(pnrp_payload_tree
, hf_pnrp_payload_iana_proto
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1063 static void dissect_publicKey_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
1065 uint16_t objIDLength
;
1066 uint16_t cbDataLength
;
1067 /* Add a new Subtree */
1068 proto_tree
*pnrp_publicKey_tree
;
1069 /* Check if we can safely parse Data */
1070 if (0 < length
&& 0 <= tvb_reported_length_remaining(tvb
, offset
+length
)) {
1071 pnrp_publicKey_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, length
, ett_pnrp_message_publicKeyStructure
, NULL
, "CPA Public Key Structure");
1072 /* Parsing of Data */
1073 /* Field Length of Structure */
1074 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_length_of_structure
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1077 objIDLength
= tvb_get_letohs(tvb
,offset
);
1078 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_size_of_algorithm_oid
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1081 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_reserved
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1083 /* Public Key cbData Length */
1084 cbDataLength
= tvb_get_letohs(tvb
,offset
);
1085 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_size_of_cbdata
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1087 /* Unused Bits, actually only 7... */
1088 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_unused_bits
, tvb
, offset
, 1, ENC_NA
);
1090 /* Algorithm ObjID */
1091 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_objID
, tvb
, offset
, objIDLength
, ENC_ASCII
);
1092 offset
+= objIDLength
;
1093 /* Public Key Data */
1094 proto_tree_add_item(pnrp_publicKey_tree
, hf_pnrp_publicKey_publicKeyData
, tvb
, offset
, cbDataLength
, ENC_ASCII
);
1097 static void dissect_signature_structure(tvbuff_t
*tvb
, int offset
, int length
, proto_tree
*tree
)
1099 uint16_t signatureLength
;
1100 /* Add a new Subtree */
1101 proto_tree
*pnrp_signature_tree
;
1103 /* Check if we can safely parse Data */
1104 if (0 < length
&& 0 <= tvb_reported_length_remaining(tvb
, offset
+length
)) {
1105 pnrp_signature_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, length
, ett_pnrp_message_signatureStructure
, NULL
, "Signature Structure");
1106 /* Parsing of Data */
1107 /* Field Length of Structure */
1108 proto_tree_add_item(pnrp_signature_tree
, hf_pnrp_signature_structure_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1110 /* Signature Length */
1111 signatureLength
= tvb_get_letohs(tvb
,offset
);
1112 proto_tree_add_item(pnrp_signature_tree
, hf_pnrp_signature_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1114 /* Hash Algorithm Identifier */
1115 proto_tree_add_item(pnrp_signature_tree
, hf_pnrp_signature_hash_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1117 /* Signature Data */
1118 proto_tree_add_item(pnrp_signature_tree
, hf_pnrp_signature_signatureData
, tvb
, offset
, signatureLength
, ENC_NA
);
1122 /* Register the protocol */
1123 void proto_register_pnrp(void)
1125 /* A header field is something you can search/filter on.
1127 * We create a structure to register our fields. It consists of an
1128 * array of hf_register_info structures, each of which are of the format
1129 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1131 static hf_register_info hf
[] = {
1133 { "Header", "pnrp.header", FT_NONE
, BASE_NONE
, NULL
, 0x0,
1134 "PNRP Header", HFILL
}},
1135 { &hf_pnrp_header_fieldID
,
1136 { "Header FieldID", "pnrp.header.fieldID", FT_UINT16
, BASE_HEX
, VALS(fieldID
), 0x0,
1138 { &hf_pnrp_header_length
,
1139 { "Header length", "pnrp.header.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1141 { &hf_pnrp_header_ident
,
1142 { "Ident", "pnrp.ident", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1144 { &hf_pnrp_header_versionMajor
,
1145 { "Version Major", "pnrp.vMajor", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1147 { &hf_pnrp_header_versionMinor
,
1148 { "Version Minor", "pnrp.vMinor", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1150 { &hf_pnrp_header_messageType
,
1151 { "Message Type", "pnrp.messageType", FT_UINT8
, BASE_DEC
, VALS(messageType
), 0x0,
1153 { &hf_pnrp_header_messageID
,
1154 { "Message ID", "pnrp.header.messageID", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1156 { &hf_pnrp_message_type
,
1157 { "Segment Type", "pnrp.segment.type", FT_UINT16
, BASE_HEX
, VALS(fieldID
), 0x0,
1159 { &hf_pnrp_message_length
,
1160 { "Segment length", "pnrp.segment.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1161 "Message length", HFILL
}},
1162 { &hf_pnrp_message_headerack
,
1163 { "ACKed Header ID", "pnrp.segment.headerAck", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1165 { &hf_pnrp_message_pnrpID
,
1166 { "PNRP ID", "pnrp.segment.pnrpID", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1169 { &hf_pnrp_message_inquire_flags
,
1170 { "Flags", "pnrp.segment.inquire.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1172 { &hf_pnrp_message_inquire_flags_reserved1
,
1173 { "Reserved 1", "pnrp.segment.inquire.flags.reserved1", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_INQUIRE_RESERVED1
,
1175 { &hf_pnrp_message_inquire_flags_Abit
,
1176 { "CPA should (a)ppear in response", "pnrp.segment.inquire.flags.Abit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_INQUIRE_A
,
1178 { &hf_pnrp_message_inquire_flags_Xbit
,
1179 { "E(X)tended Payload sent in Authority response", "pnrp.segment.inquire.flags.Xbit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_INQUIRE_X
,
1181 { &hf_pnrp_message_inquire_flags_Cbit
,
1182 { "(C)ertificate Chain sent in Authority response", "pnrp.segment.inquire.flags.Cbit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_INQUIRE_C
,
1184 { &hf_pnrp_message_inquire_flags_reserved2
,
1185 { "Reserved 2", "pnrp.segment.inquire.flags.reserved2", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_INQUIRE_RESERVED2
,
1188 { "Padding", "pnrp.padding", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1191 { &hf_pnrp_message_classifier_unicodeCount
,
1192 { "Number of Unicode Characters", "pnrp.segment.classifier.unicodeCount", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1194 { &hf_pnrp_message_classifier_arrayLength
,
1195 { "Array Length", "pnrp.segment.classifier.arrayLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1197 { &hf_pnrp_message_classifier_entryLength
,
1198 { "Entry Length", "pnrp.segment.classifier.entryLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1200 { &hf_pnrp_message_classifier_string
,
1201 { "Classifier", "pnrp.segment.classifier.string", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1204 { &hf_pnrp_message_ack_flags_reserved
,
1205 { "Reserved", "pnrp.segment.ack.flags.reserved", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1207 { &hf_pnrp_message_ack_flags_Nbit
,
1208 { "(N)ot found Bit", "pnrp.segment.ack.flags.Nbit", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1210 /* Authority Flags */
1211 { &hf_pnrp_message_authority_flags
,
1212 { "Flags", "pnrp.segment.authority.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1214 { &hf_pnrp_message_authority_flags_reserved1
,
1215 { "Reserved 1", "pnrp.segment.authority.flags.reserved1", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_RESERVED1
,
1217 { &hf_pnrp_message_authority_flags_Lbit
,
1218 { "(L)eaf Set", "pnrp.segment.authority.flags.Lbit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_L
,
1220 { &hf_pnrp_message_authority_flags_reserved2
,
1221 { "Reserved 2", "pnrp.segment.authority.flags.reserved2", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_RESERVED2
,
1223 { &hf_pnrp_message_authority_flags_Bbit
,
1224 { "(B)usy", "pnrp.segment.authority.flags.Bbit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_B
,
1226 { &hf_pnrp_message_authority_flags_reserved3
,
1227 { "Reserved 3", "pnrp.segment.authority.flags.reserved3", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_RESERVED3
,
1229 { &hf_pnrp_message_authority_flags_Nbit
,
1230 { "(N)ot found", "pnrp.segment.authority.flags.Nbit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_AUTHORITY_N
,
1232 /* Flood Control Flags */
1233 { &hf_pnrp_message_flood_flags_reserved1
,
1234 { "Reserved", "pnrp.segment.flood.flags.reserved", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1236 { &hf_pnrp_message_flood_flags_Dbit
,
1237 { "(D)on't send ACK", "pnrp.segment.flood.flags.Dbit", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1239 /* Split Controls */
1240 { &hf_pnrp_message_splitControls_authorityBuffer
,
1241 { "Authority Buffer Size", "pnrp.segment.splitControls.authorityBuffer", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1243 /* IPv6 Endpoint Array */
1244 { &hf_pnrp_message_ipv6EndpointArray_NumberOfEntries
,
1245 { "Number of Entries", "pnrp.segment.ipv6EndpointArray.NumberOfEntries", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1247 { &hf_pnrp_message_ipv6EndpointArray_ArrayLength
,
1248 { "Array Length", "pnrp.segment.ipv6EndpointArray.ArrayLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1250 { &hf_pnrp_message_ipv6EndpointArray_EntryLength
,
1251 { "Entry Length", "pnrp.segment.ipv6EndpointArray.EntryLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1253 /* Encoded CPA structrue */
1254 { &hf_pnrp_encodedCPA
,
1255 { "Encoded CPA structure", "pnrp.encodedCPA", FT_NONE
, BASE_NONE
, NULL
, 0x0,
1257 { &hf_pnrp_encodedCPA_length
,
1258 { "Length", "pnrp.encodedCPA.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1260 { &hf_pnrp_encodedCPA_majorVersion
,
1261 { "CPA Major Version", "pnrp.encodedCPA.vMajor", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1263 { &hf_pnrp_encodedCPA_minorVersion
,
1264 { "CPA Minor Version", "pnrp.encodedCPA.vMinor", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1266 /* Encoded CPA flags */
1267 { &hf_pnrp_encodedCPA_flags
,
1268 { "Flags", "pnrp.encodedCPA.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1270 { &hf_pnrp_encodedCPA_flags_reserved
,
1271 { "Reserved", "pnrp.encodedCPA.flags.reserved", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_RESERVED
,
1273 { &hf_pnrp_encodedCPA_flags_Xbit
,
1274 { "CPA has E(X)tended Payload", "pnrp.encodedCPA.flags.xbit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_X
,
1276 { &hf_pnrp_encodedCPA_flags_Fbit
,
1277 { "CPA contains (F)riendly Name", "pnrp.encodedCPA.flags.fbit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_F
,
1279 { &hf_pnrp_encodedCPA_flags_Cbit
,
1280 { "CPA contains (C)lassifier Hash", "pnrp.encodedCPA.flags.cbit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_C
,
1282 { &hf_pnrp_encodedCPA_flags_Abit
,
1283 { "CPA contains Binary (A)uthority field", "pnrp.encodedCPA.flags.abit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_A
,
1285 { &hf_pnrp_encodedCPA_flags_Ubit
,
1286 { "Friendly Name in (U)TF-8", "pnrp.encodedCPA.flags.ubit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_U
,
1288 { &hf_pnrp_encodedCPA_flags_Rbit
,
1289 { "This is a (r)evoke CPA", "pnrp.encodedCPA.flags.rbit", FT_UINT8
, BASE_HEX
, NULL
, FLAGS_ENCODED_CPA_R
,
1291 /* TODO: Find correct way to Display Time */
1292 { &hf_pnrp_encodedCPA_notAfter
,
1293 { "CPA expiration Date", "pnrp.encodedCPA.expirationDate", FT_UINT64
,BASE_DEC
, NULL
, 0x0,
1294 "CPA expiration Date since January 1, 1601 UTC", HFILL
}},
1295 { &hf_pnrp_encodedCPA_serviceLocation
,
1296 { "Service Location", "pnrp.encodedCPA.serviceLocation", FT_BYTES
,BASE_NONE
, NULL
, 0x0,
1298 { &hf_pnrp_encodedCPA_binaryAuthority
,
1299 { "Binary Authority", "pnrp.encodedCPA.binaryAuthority", FT_BYTES
,BASE_NONE
, NULL
, 0x0,
1300 "SHA-1 Hash of PublicKey Data field", HFILL
}},
1301 { &hf_pnrp_encodedCPA_classifierHash
,
1302 { "Classifier Hash", "pnrp.encodedCPA.classifierHash", FT_BYTES
,BASE_NONE
, NULL
, 0x0,
1303 "SHA-1 Hash of the classifier text", HFILL
}},
1304 { &hf_pnrp_encodedCPA_friendlyName
,
1305 { "Friendly Name of PNRP ID", "pnrp.encodedCPA.friendlyName", FT_STRING
,BASE_NONE
, NULL
, 0x0,
1306 "A human-readable label identifying the PNRP ID", HFILL
}},
1307 /* Lookup Controls */
1308 { &hf_pnrp_message_lookupControls_flags
,
1309 { "Flags", "pnrp.lookupControls.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1311 { &hf_pnrp_message_lookupControls_flags_reserved
,
1312 { "Reserved", "pnrp.lookupControls.flags.reserved", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_LOOKUPCONTROLS_RESERVED
,
1314 { &hf_pnrp_message_lookupControls_flags_Abit
,
1315 { "A bit", "pnrp.lookupControls.flags.Abit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_LOOKUPCONTROLS_A
,
1316 "Sender is willing to accept returned nodes that are not closer to the target ID than the Validate PNRP ID", HFILL
}},
1317 { &hf_pnrp_message_lookupControls_flags_0bit
,
1318 { "0 bit - reserved", "pnrp.lookupControls.flags.0bit", FT_UINT16
, BASE_HEX
, NULL
, FLAGS_LOOKUPCONTROLS_0
,
1320 { &hf_pnrp_message_lookupControls_precision
,
1321 { "Precision", "pnrp.lookupControls.precision", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1322 "Precision - Number of significant bits to match", HFILL
}},
1323 { &hf_pnrp_message_lookupControls_resolveCriteria
,
1324 { "Resolve Criteria", "pnrp.lookupControls.resolveCriteria", FT_UINT8
, BASE_HEX
, VALS(resolveCriteria
), 0x0,
1326 { &hf_pnrp_message_lookupControls_reasonCode
,
1327 { "Reason Code", "pnrp.lookupControls.reasonCode", FT_UINT8
, BASE_HEX
, VALS(reasonCode
), 0x0,
1329 /* Public Key Structure */
1330 { &hf_pnrp_publicKey_objID
,
1331 { "Public Key Object Identifier", "pnrp.publicKey.objID", FT_STRING
,BASE_NONE
, NULL
, 0x0,
1332 "An ASN.1-encoded object identifier (OID) indicating the public key format", HFILL
}},
1333 { &hf_pnrp_publicKey_publicKeyData
,
1334 { "Public Key Data", "pnrp.publicKey.publicKeyData", FT_STRING
,BASE_NONE
, NULL
, 0x0,
1335 "An ASN.1-encoded 1024-bit RSA public key", HFILL
}},
1336 /* Signature Structure */
1337 { &hf_pnrp_signature_signatureData
,
1338 { "Signature", "pnrp.signature.data", FT_BYTES
,BASE_NONE
, NULL
, 0x0,
1339 "Signature created when signing the CPA", HFILL
}},
1342 { &hf_pnrp_message_routeEntry_portNumber
,
1343 { "Port Number", "pnrp.segment.routeEntry.portNumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1345 { &hf_pnrp_message_routeEntry_flags
,
1346 { "Flags", "pnrp.segment.routeEntry.flags", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1348 { &hf_pnrp_message_routeEntry_addressCount
,
1349 { "Address Count", "pnrp.segment.routeEntry.addressCount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1351 { &hf_pnrp_message_nonce
,
1352 { "Nonce", "pnrp.segment.nonce", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1354 { &hf_pnrp_message_hashednonce
,
1355 { "Hashed Nonce", "pnrp.segment.hashednonce", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1357 { &hf_pnrp_message_idArray_NumEntries
,
1358 { "Number of Entries", "pnrp.segment.idArray.NumEntries", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1360 { &hf_pnrp_message_idArray_Length
,
1361 { "Length of Array", "pnrp.segment.idArray.Length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1363 { &hf_pnrp_message_ElementFieldType
,
1364 { "Type of Array Entry", "pnrp.segment.ElementFieldType", FT_UINT16
, BASE_HEX
, VALS(fieldID
), 0x0,
1366 { &hf_pnrp_message_idarray_Entrylength
,
1367 { "Length of each Array Entry", "pnrp.segment.idArray.Entrylength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1369 { &hf_pnrp_message_certChain
,
1370 { "Certificate Chain", "pnrp.segment.certChain", FT_BYTES
,BASE_NONE
, NULL
, 0x0,
1371 "A Certificate Chain, containing the public key used to sign the CPA and its Certificate Chain", HFILL
}},
1372 { &hf_pnrp_message_solicitType
,
1373 { "Solicit Type", "pnrp.segment.solicitType", FT_UINT8
, BASE_DEC
, VALS(solicitType
), 0x0,
1375 { &hf_pnrp_message_ipv6
,
1376 { "IPv6 Address","pnrp.segment.ipv6Address",FT_IPv6
, BASE_NONE
, NULL
, 0x0,NULL
,HFILL
}},
1378 { &hf_pnrp_fragments
,
1379 { "Fragments", "pnrp.segment.splitControls.fragments", FT_NONE
, BASE_NONE
, NULL
, 0,
1381 { &hf_pnrp_fragment
,
1382 { "Fragment", "pnrp.segment.splitControls.fragment", FT_FRAMENUM
, BASE_NONE
, NULL
, 0,
1384 { &hf_pnrp_fragment_overlap
,
1385 { "Fragment Overlap", "pnrp.segment.splitControls.fragment_overlap", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1387 { &hf_pnrp_fragment_overlap_conflict
,
1388 { "Fragment Overlap Conflict", "pnrp.segment.splitControls.fragment_overlap_conflict", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1390 { &hf_pnrp_fragment_multiple_tails
,
1391 { "Fragment Multiple Tails", "pnrp.segment.splitControls.fragment_multiple_tails", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1393 { &hf_pnrp_fragment_too_long_fragment
,
1394 { "Too Long Fragment", "pnrp.segment.splitControls.fragment_too_long_fragment", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1396 { &hf_pnrp_fragment_error
,
1397 { "Fragment Error", "pnrp.segment.splitControls.fragment_error", FT_FRAMENUM
, BASE_NONE
, NULL
, 0,
1399 { &hf_pnrp_fragment_count
,
1400 { "Fragment Count", "pnrp.segment.splitControls.fragment_count", FT_UINT32
, BASE_DEC
, NULL
, 0,
1402 { &hf_pnrp_reassembled_in
,
1403 { "Reassembled In", "pnrp.segment.splitControls.reassembled_in", FT_FRAMENUM
, BASE_NONE
, NULL
, 0,
1405 { &hf_pnrp_reassembled_length
,
1406 { "Reassembled Length", "pnrp.segment.splitControls.reassembled_length", FT_UINT32
, BASE_DEC
, NULL
, 0,
1408 { &hf_pnrp_reassembled_data
,
1409 { "Reassembled Data", "pnrp.segment.splitControls.reassembled_data", FT_BYTES
, BASE_NONE
, NULL
, 0,
1411 { &hf_pnrp_fragmented_payload
,
1412 { "Fragmented Payload", "pnrp.segment.splitControls.fragmented_payload", FT_BYTES
, BASE_NONE
, NULL
, 0,
1415 /* Generated from convert_proto_tree_add_text.pl */
1416 { &hf_pnrp_message_flags
, { "Flags", "pnrp.segment.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1417 { &hf_pnrp_reserved8
, { "Reserved", "pnrp.reserved", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1418 { &hf_pnrp_reserved16
, { "Reserved", "pnrp.reserved", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1419 { &hf_pnrp_message_offset
, { "Offset", "pnrp.segment.offset", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1420 { &hf_pnrp_message_data
, { "Data", "pnrp.segment.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1421 { &hf_pnrp_message_port_number
, { "Port Number", "pnrp.segment.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1422 { &hf_pnrp_encodedCPA_friendlyName_length
, { "Length of Friendly name", "pnrp.encodedCPA.friendlyName.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1423 { &hf_pnrp_encodedCPA_number_of_service_addresses
, { "Number of Service Addresses", "pnrp.encodedCPA.number_of_service_addresses", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1424 { &hf_pnrp_encodedCPA_service_address_length
, { "Service Address Length", "pnrp.encodedCPA.service_address_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1425 { &hf_pnrp_encodedCPA_number_of_payload_structures
, { "Number of Payload Structures", "pnrp.encodedCPA.number_of_payload_structures", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1426 { &hf_pnrp_encodedCPA_total_bytes_of_payload
, { "Total Bytes of Payload", "pnrp.encodedCPA.total_bytes_of_payload", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1427 { &hf_pnrp_payload_type
, { "Payload Type", "pnrp.payload.type", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1428 { &hf_pnrp_length_of_data
, { "Length of Data", "pnrp.payload.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1429 { &hf_pnrp_payload_port
, { "Port Number", "pnrp.payload.port", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1430 { &hf_pnrp_payload_iana_proto
, { "IANA Protocol Number", "pnrp.payload.iana_proto", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1431 { &hf_pnrp_publicKey_length_of_structure
, { "Length of Structure", "pnrp.publicKey.structure_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1432 { &hf_pnrp_publicKey_size_of_algorithm_oid
, { "Size of Algorithm OID", "pnrp.publicKey.algorithm_oid_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1433 { &hf_pnrp_publicKey_reserved
, { "Reserved", "pnrp.publicKey.reserved", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1434 { &hf_pnrp_publicKey_size_of_cbdata
, { "Size of cbData", "pnrp.publicKey.cbdata_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1435 { &hf_pnrp_publicKey_unused_bits
, { "Unused Bits", "pnrp.publicKey.unused_bits", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1436 { &hf_pnrp_signature_structure_length
, { "Length of Structure", "pnrp.signature.structure_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1437 { &hf_pnrp_signature_length
, { "Length of Signature", "pnrp.signature.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
1438 { &hf_pnrp_signature_hash_id
, { "Hash Algorithm Identifier", "pnrp.signature.hash_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1442 /* Protocol subtree array */
1443 static int *ett
[] = {
1447 &ett_pnrp_message_inquire_flags
,
1448 &ett_pnrp_message_authority_flags
,
1449 &ett_pnrp_message_encodedCPA
,
1450 &ett_pnrp_message_encodedCPA_flags
,
1451 &ett_pnrp_message_payloadStructure
,
1452 &ett_pnrp_message_publicKeyStructure
,
1453 &ett_pnrp_message_signatureStructure
,
1454 &ett_pnrp_message_lookupControls_flags
,
1458 /* Register the Dissector with Wireshark */
1459 proto_pnrp
= proto_register_protocol(PROTONAME
,PROTOSHORTNAME
,PROTOABBREV
);
1461 proto_register_field_array(proto_pnrp
,hf
,array_length(hf
));
1462 proto_register_subtree_array (ett
, array_length(ett
));
1464 pnrp_handle
= register_dissector(PROTOABBREV
, dissect_pnrp
, proto_pnrp
);
1466 reassembly_table_register(&pnrp_reassembly_table
,
1467 &addresses_reassembly_table_functions
);
1470 /* Initialise the dissector */
1471 void proto_reg_handoff_pnrp(void)
1473 dissector_add_uint_with_preference("udp.port",PNRP_PORT
,pnrp_handle
);
1477 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1482 * indent-tabs-mode: nil
1485 * vi: set shiftwidth=4 tabstop=8 expandtab:
1486 * :indentSize=4:tabSize=8:noTabs=true: