Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-pnrp.c
blob0f88071e2093ea0b16de4bf5409dd6722d08093c
1 /* packet-pnrp.c
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
21 #include "config.h"
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
49 #define WCHAR 0x0084
50 #define CLASSIFIER 0x0085
51 #define HASHED_NONCE 0x0092
52 #define NONCE 0x0093
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 */
61 #define SOLICIT 0x01
62 #define ADVERTISE 0x02
63 #define REQUEST 0x03
64 #define FLOOD 0x04
65 #define INQUIRE 0x07
66 #define AUTHORITY 0x08
67 #define ACK 0x09
68 #define LOOKUP 0x0B
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" },
129 { WCHAR, "WCHAR" },
130 { CLASSIFIER, "CLASSIFIER" },
131 { HASHED_NONCE, "HASHED_NONCE" },
132 { NONCE, "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" },
139 {0, NULL}
142 /* Define Packetnames */
143 static const value_string messageType[] = {
144 { SOLICIT, "SOLICIT" },
145 { ADVERTISE, "ADVERTISE" },
146 { REQUEST, "REQUEST" },
147 { FLOOD, "FLOOD" },
148 { INQUIRE, "INQUIRE" },
149 { AUTHORITY, "AUTHORITY" },
150 { ACK, "ACK" },
151 { LOOKUP, "LOOKUP" },
152 {0, NULL}
154 /* Define Solicit Type */
155 static const value_string solicitType[] = {
156 { 0x00, "SOLICIT_TYPE_ANY" },
157 { 0x01, "SOLICIT_TYPE_LOCAL" },
158 {0, NULL}
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" },
167 {0, NULL}
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" },
175 {0, NULL}
178 /* Define IDs for subcomponents */
179 /* Message Header */
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;
188 /* Message Body */
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,
209 NULL
212 /* Classifier */
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;
220 /* SplitControls */
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,
242 NULL
245 /* Flood Control Flags */
246 static int hf_pnrp_message_flood_flags_reserved1;
247 static int hf_pnrp_message_flood_flags_Dbit;
249 /* PNRP ID Array */
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;
261 /* Encoded CPA */
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,
282 NULL
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,
299 NULL
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;
342 /* Reassembly */
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 */
357 static int ett_pnrp;
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 = {
374 &ett_pnrp_fragment,
375 &ett_pnrp_fragments,
376 &hf_pnrp_fragments,
377 &hf_pnrp_fragment,
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,
387 "PNRP fragments"
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;
395 int padding_bytes;
396 uint8_t message_type;
397 uint16_t field_type;
398 unsigned data_length;
399 proto_item *ti;
400 proto_tree *pnrp_tree;
401 proto_item *pnrp_header_item;
402 proto_tree *pnrp_header_tree;
403 proto_item *pnrp_message_tree = NULL;
404 uint32_t msg_id;
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 )
415 return 0;
418 /* Check some values from the packet header */
419 /* First 2 bytes must be 0x0010 */
420 if (tvb_get_ntohs(tvb,0) != PNRP_HEADER )
422 return 0;
424 /* Length of Header must be 0x000C = 12 */
425 if (tvb_get_ntohs(tvb,2) != 0x000C) {
426 return 0;
428 /* Identifier must 0x51 */
429 if (tvb_get_uint8(tvb,4) != 0x51) {
430 return 0;
434 /* Assign Values to Variables */
435 /* Use to track data */
436 offset= 0;
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);
464 offset += 2;
465 /* Add Length should be 0x000C */
466 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_length,tvb,offset,2,ENC_BIG_ENDIAN);
467 offset += 2;
468 /* Add Ident should be 0x51 */
469 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_ident,tvb,offset,1,ENC_BIG_ENDIAN);
470 offset += 1;
471 /* Add Major Version */
472 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMajor,tvb,offset,1,ENC_BIG_ENDIAN);
473 offset += 1;
474 /* Add Minor Version */
475 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMinor,tvb,offset,1,ENC_BIG_ENDIAN);
476 offset += 1;
477 /* Add Message Type */
478 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_messageType,tvb,offset,1,ENC_BIG_ENDIAN);
479 offset += 1;
480 /* Add Message ID */
481 proto_tree_add_item_ret_uint(pnrp_header_tree,hf_pnrp_header_messageID,tvb,offset,4,ENC_BIG_ENDIAN,&msg_id);
482 offset += 4;
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) {
499 if (tree) {
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);
505 offset += 4;
506 /* Don't continue parsing this message segment */
507 break;
509 /* Actual Parsing of the message Type */
510 switch (field_type) {
511 /* First Field in ACK Message */
512 case PNRP_HEADER_ACKED:
513 if (tree) {
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;
522 break;
524 /* A validate pnrp id follows as found in FLOOD */
525 case VALIDATE_PNRP_ID:
526 if (tree) {
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;
536 break;
538 /* The Flags have different meaning, depending on the message */
539 case FLAGS_FIELD:
540 if (tree) {
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) {
547 case INQUIRE:
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;
552 break;
554 case ACK:
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);
557 /* N - Bit */
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;
560 break;
561 case AUTHORITY:
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;
568 else {
569 padding_bytes = 2;
570 proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + 6, padding_bytes, ENC_NA);
571 offset += data_length+2;
573 break;
575 default:
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;
578 break;
580 break;
582 /* Flood controls found in FLOOD Message */
583 case FLOOD_CONTROLS:
584 if (tree) {
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);
591 /* D - Bit */
592 proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_flood_flags_Dbit, tvb,((offset + 4)*8)+15, 1, ENC_BIG_ENDIAN);
593 /* Reserved 2 */
594 proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved8, tvb, offset + 6, 1, ENC_NA);
595 /* Padding 1 */
596 proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + 7, 1, ENC_NA);
599 offset += data_length+1;
600 break;
602 /* Solicit Controls found in SOLICIT Message */
603 case SOLICIT_CONTROLS:
604 if (tree) {
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 */
614 break;
615 /* Lookup controls found in LOOKUP Message */
616 case LOOKUP_CONTROLS:
617 if (tree) {
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);
628 /* Reason Code */
629 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_reasonCode, tvb, offset + 9, 1, ENC_BIG_ENDIAN);
630 /* Reserved */
631 proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved16, tvb, offset + 10, 2, ENC_LITTLE_ENDIAN);
635 offset += data_length;
636 break;
637 /* Target PNRP ID found in Lookup Message */
638 case TARGET_PNRP_ID:
639 if (tree) {
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;
648 break;
650 /* Extended Payload found in AUTHORITY Message */
651 case EXTENDED_PAYLOAD:
652 if (tree) {
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;
661 break;
662 /* Pnrp id Array as found in REQUEST & ADVERTISE Message */
663 case PNRP_ID_ARRAY:
664 if (tree) {
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;
677 break;
678 /* Cert Chain follows as found in AUTHORITY */
679 case CERT_CHAIN:
680 if (tree) {
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 */
689 padding_bytes = 0;
690 while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
691 data_length++;
692 padding_bytes++;
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;
699 break;
700 /* classifier: A classifier string follows as found in AUTHORITY */
701 case CLASSIFIER:
702 if (tree) {
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);
707 /* NumEntries */
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 */
720 padding_bytes = 0;
721 while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
722 data_length++;
723 padding_bytes++;
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;
730 break;
731 /* A hashed nonce follows as found in ADVERTISE & SOLICIT */
732 case HASHED_NONCE:
733 if (tree) {
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;
743 break;
745 /* A nonce follows as found in REQUEST & INQUIRE */
746 case NONCE:
747 if (tree) {
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;
756 break;
758 /* split controls as found in AUTHORITY */
759 case SPLIT_CONTROLS:
761 fragment_head *frag_data;
762 tvbuff_t *frag_tvb;
763 uint32_t buffer_len, frag_offset, remaining_len;
765 if (tree) {
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);
774 /* Byte offset */
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);
785 if (frag_tvb) {
786 tvb = frag_tvb;
787 offset = 0;
788 } else {
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);
793 break;
796 /* routing entry: A route entry follows as found in ADVERTISE, INQUIRE, LOOKUP & AUTHORITY */
797 case ROUTING_ENTRY:
798 if (tree) {
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 */
807 padding_bytes = 0;
808 while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
809 data_length++;
810 padding_bytes++;
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;
817 break;
819 /* validate cpa: an encoded CPA structure follows as found in AUTHORITY */
820 case VALIDATE_CPA:
821 if (tree) {
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;
832 break;
835 /* IPV6 Endpoint: an ipv6 endpoint array structure follows as found in LOOKUP */
836 case IPV6_ENDPOINT_ARRAY:
837 if (tree) {
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);
844 /* Array length */
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);
850 /* Flagged Path */
851 dissect_ipv6_endpoint_structure(tvb, offset+12, tvb_get_ntohs(tvb,offset+6)-8,pnrp_message_tree);
854 offset += data_length;
855 break;
857 default:
858 if (tree) {
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);
864 if(data_length > 4)
866 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_data, tvb, offset + 4, data_length -4, ENC_NA);
868 else {
869 return 0;
872 offset += data_length;
873 break;
875 // SPLIT_CONTROLS might reset our offset.
876 if (start_offset <= offset) {
877 THROW(ReportedBoundsError);
880 return offset;
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);
892 length -= 32;
893 offset += 32;
898 static void dissect_route_entry(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
900 int tmp_offset;
901 /* Check if we don't run out of data */
902 if (0 <= tvb_reported_length_remaining(tvb, offset+length)) {
903 tmp_offset = 0;
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);
906 tmp_offset +=32;
907 /* Add PNRP Major Version */
908 proto_tree_add_item(tree,hf_pnrp_header_versionMajor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
909 tmp_offset += 1;
910 /* Add Minor Version */
911 proto_tree_add_item(tree,hf_pnrp_header_versionMinor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
912 tmp_offset +=1;
913 /* Port Number */
914 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_portNumber,tvb,offset+tmp_offset,2,ENC_BIG_ENDIAN);
915 tmp_offset +=2;
916 /* Flags */
917 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_flags,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
918 tmp_offset +=1;
919 /* Address count */
920 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_addressCount,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
921 tmp_offset +=1;
922 /* IPv6 Addresses */
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) {
931 /* Port Number */
932 proto_tree_add_item(tree, hf_pnrp_message_port_number, tvb, offset, 2, ENC_BIG_ENDIAN);
933 /* IPv6 Addresses */
934 dissect_ipv6_address(tvb, offset+2,16,tree);
935 offset += 18;
936 length -= 18;
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);
944 offset += 16;
945 length -= 16;
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)) {
953 uint8_t flagsField;
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);
970 /* Flags Field */
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);
973 /* Reserved */
974 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_reserved8, tvb, offset + 7, 1, ENC_NA);
975 /* Not After */
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 */
981 offset +=32;
983 /* Check if R Flag is set */
984 if ((flagsField & FLAGS_ENCODED_CPA_R)==0x00) {
985 /* Nonce follows */
986 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_message_nonce, tvb, offset, 16, ENC_NA);
987 offset +=16;
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);
993 offset +=20;
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);
999 offset +=20;
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);
1005 /* Friendly Name */
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);
1011 offset += 2;
1012 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_service_address_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1013 offset += 2;
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);
1019 offset += 2;
1020 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_total_bytes_of_payload, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1021 offset += 2;
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;
1024 /* Public Key */
1025 dissect_publicKey_structure(tvb, offset,tvb_get_letohs(tvb,offset),pnrp_encodedCPA_tree);
1026 offset += tvb_get_letohs(tvb,offset);
1027 /* Signature */
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 */
1038 if (0>=length )
1039 return;
1041 pnrp_payload_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_pnrp_message_payloadStructure, NULL, "Payload Structure");
1043 /* Dissect the Payload Structure */
1044 /* Payload Type */
1045 proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1046 offset += 4;
1047 /* Data Length */
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);
1050 offset += 2;
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);
1054 offset += 16;
1055 proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1056 offset += 2;
1057 proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_iana_proto, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1058 offset += 2;
1059 lengthOfData -=20;
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);
1075 offset += 2;
1076 /* ObjID length */
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);
1079 offset += 2;
1080 /* Reserved */
1081 proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1082 offset +=2;
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);
1086 offset += 2;
1087 /* Unused Bits, actually only 7... */
1088 proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_unused_bits, tvb, offset, 1, ENC_NA);
1089 offset +=1;
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);
1109 offset +=2;
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);
1113 offset += 2;
1114 /* Hash Algorithm Identifier */
1115 proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_hash_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1116 offset += 4;
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[] = {
1132 { &hf_pnrp_header,
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,
1137 NULL, HFILL }},
1138 { &hf_pnrp_header_length,
1139 { "Header length", "pnrp.header.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1140 NULL, HFILL }},
1141 { &hf_pnrp_header_ident,
1142 { "Ident", "pnrp.ident", FT_UINT8, BASE_HEX, NULL, 0x0,
1143 NULL, HFILL }},
1144 { &hf_pnrp_header_versionMajor,
1145 { "Version Major", "pnrp.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1146 NULL, HFILL }},
1147 { &hf_pnrp_header_versionMinor,
1148 { "Version Minor", "pnrp.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1149 NULL, HFILL }},
1150 { &hf_pnrp_header_messageType,
1151 { "Message Type", "pnrp.messageType", FT_UINT8, BASE_DEC, VALS(messageType), 0x0,
1152 NULL, HFILL }},
1153 { &hf_pnrp_header_messageID,
1154 { "Message ID", "pnrp.header.messageID", FT_UINT32, BASE_HEX, NULL, 0x0,
1155 NULL, HFILL }},
1156 { &hf_pnrp_message_type,
1157 { "Segment Type", "pnrp.segment.type", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1158 NULL, HFILL }},
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,
1164 NULL, HFILL }},
1165 { &hf_pnrp_message_pnrpID,
1166 { "PNRP ID", "pnrp.segment.pnrpID", FT_BYTES, BASE_NONE, NULL, 0x0,
1167 NULL, HFILL }},
1168 /* Inquire Flags */
1169 { &hf_pnrp_message_inquire_flags,
1170 { "Flags", "pnrp.segment.inquire.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1171 NULL, HFILL }},
1172 { &hf_pnrp_message_inquire_flags_reserved1,
1173 { "Reserved 1", "pnrp.segment.inquire.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED1,
1174 NULL, HFILL }},
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,
1177 NULL, HFILL }},
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,
1180 NULL, HFILL }},
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,
1183 NULL, HFILL }},
1184 { &hf_pnrp_message_inquire_flags_reserved2,
1185 { "Reserved 2", "pnrp.segment.inquire.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED2,
1186 NULL, HFILL }},
1187 { &hf_pnrp_padding,
1188 { "Padding", "pnrp.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
1189 NULL, HFILL }},
1190 /* Classifier */
1191 { &hf_pnrp_message_classifier_unicodeCount,
1192 { "Number of Unicode Characters", "pnrp.segment.classifier.unicodeCount", FT_UINT16, BASE_DEC, NULL, 0x0,
1193 NULL, HFILL }},
1194 { &hf_pnrp_message_classifier_arrayLength,
1195 { "Array Length", "pnrp.segment.classifier.arrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1196 NULL, HFILL }},
1197 { &hf_pnrp_message_classifier_entryLength,
1198 { "Entry Length", "pnrp.segment.classifier.entryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1199 NULL, HFILL }},
1200 { &hf_pnrp_message_classifier_string,
1201 { "Classifier", "pnrp.segment.classifier.string", FT_STRING, BASE_NONE, NULL, 0x0,
1202 NULL, HFILL }},
1203 /* Ack Flags */
1204 { &hf_pnrp_message_ack_flags_reserved,
1205 { "Reserved", "pnrp.segment.ack.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1206 NULL, HFILL }},
1207 { &hf_pnrp_message_ack_flags_Nbit,
1208 { "(N)ot found Bit", "pnrp.segment.ack.flags.Nbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1209 NULL, HFILL }},
1210 /* Authority Flags */
1211 { &hf_pnrp_message_authority_flags,
1212 { "Flags", "pnrp.segment.authority.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1213 NULL, HFILL }},
1214 { &hf_pnrp_message_authority_flags_reserved1,
1215 { "Reserved 1", "pnrp.segment.authority.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED1,
1216 NULL, HFILL }},
1217 { &hf_pnrp_message_authority_flags_Lbit,
1218 { "(L)eaf Set", "pnrp.segment.authority.flags.Lbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_L,
1219 NULL, HFILL }},
1220 { &hf_pnrp_message_authority_flags_reserved2,
1221 { "Reserved 2", "pnrp.segment.authority.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED2,
1222 NULL, HFILL }},
1223 { &hf_pnrp_message_authority_flags_Bbit,
1224 { "(B)usy", "pnrp.segment.authority.flags.Bbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_B,
1225 NULL, HFILL }},
1226 { &hf_pnrp_message_authority_flags_reserved3,
1227 { "Reserved 3", "pnrp.segment.authority.flags.reserved3", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED3,
1228 NULL, HFILL }},
1229 { &hf_pnrp_message_authority_flags_Nbit,
1230 { "(N)ot found", "pnrp.segment.authority.flags.Nbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_N,
1231 NULL, HFILL }},
1232 /* Flood Control Flags */
1233 { &hf_pnrp_message_flood_flags_reserved1,
1234 { "Reserved", "pnrp.segment.flood.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1235 NULL, HFILL }},
1236 { &hf_pnrp_message_flood_flags_Dbit,
1237 { "(D)on't send ACK", "pnrp.segment.flood.flags.Dbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1238 NULL, HFILL }},
1239 /* Split Controls */
1240 { &hf_pnrp_message_splitControls_authorityBuffer,
1241 { "Authority Buffer Size", "pnrp.segment.splitControls.authorityBuffer", FT_UINT16, BASE_DEC, NULL, 0x0,
1242 NULL, HFILL }},
1243 /* IPv6 Endpoint Array */
1244 { &hf_pnrp_message_ipv6EndpointArray_NumberOfEntries,
1245 { "Number of Entries", "pnrp.segment.ipv6EndpointArray.NumberOfEntries", FT_UINT16, BASE_DEC, NULL, 0x0,
1246 NULL, HFILL }},
1247 { &hf_pnrp_message_ipv6EndpointArray_ArrayLength,
1248 { "Array Length", "pnrp.segment.ipv6EndpointArray.ArrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1249 NULL, HFILL }},
1250 { &hf_pnrp_message_ipv6EndpointArray_EntryLength,
1251 { "Entry Length", "pnrp.segment.ipv6EndpointArray.EntryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1252 NULL, HFILL }},
1253 /* Encoded CPA structrue */
1254 { &hf_pnrp_encodedCPA,
1255 { "Encoded CPA structure", "pnrp.encodedCPA", FT_NONE, BASE_NONE, NULL, 0x0,
1256 NULL, HFILL }},
1257 { &hf_pnrp_encodedCPA_length,
1258 { "Length", "pnrp.encodedCPA.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1259 NULL, HFILL }},
1260 { &hf_pnrp_encodedCPA_majorVersion,
1261 { "CPA Major Version", "pnrp.encodedCPA.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1262 NULL, HFILL }},
1263 { &hf_pnrp_encodedCPA_minorVersion,
1264 { "CPA Minor Version", "pnrp.encodedCPA.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1265 NULL, HFILL }},
1266 /* Encoded CPA flags */
1267 { &hf_pnrp_encodedCPA_flags,
1268 { "Flags", "pnrp.encodedCPA.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1269 NULL, HFILL }},
1270 { &hf_pnrp_encodedCPA_flags_reserved,
1271 { "Reserved", "pnrp.encodedCPA.flags.reserved", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_RESERVED,
1272 NULL, HFILL }},
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,
1275 NULL, HFILL }},
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,
1278 NULL, HFILL }},
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,
1281 NULL, HFILL }},
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,
1284 NULL, HFILL }},
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,
1287 NULL, HFILL }},
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,
1290 NULL, HFILL }},
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,
1297 NULL, HFILL }},
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,
1310 NULL, HFILL }},
1311 { &hf_pnrp_message_lookupControls_flags_reserved,
1312 { "Reserved", "pnrp.lookupControls.flags.reserved", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_RESERVED,
1313 NULL, HFILL }},
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,
1319 NULL, HFILL }},
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,
1325 NULL, HFILL }},
1326 { &hf_pnrp_message_lookupControls_reasonCode,
1327 { "Reason Code", "pnrp.lookupControls.reasonCode", FT_UINT8, BASE_HEX, VALS(reasonCode), 0x0,
1328 NULL, HFILL }},
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 }},
1341 /* Route Entry */
1342 { &hf_pnrp_message_routeEntry_portNumber,
1343 { "Port Number", "pnrp.segment.routeEntry.portNumber", FT_UINT16, BASE_DEC, NULL, 0x0,
1344 NULL, HFILL }},
1345 { &hf_pnrp_message_routeEntry_flags,
1346 { "Flags", "pnrp.segment.routeEntry.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
1347 NULL, HFILL }},
1348 { &hf_pnrp_message_routeEntry_addressCount,
1349 { "Address Count", "pnrp.segment.routeEntry.addressCount", FT_UINT8, BASE_DEC, NULL, 0x0,
1350 NULL, HFILL }},
1351 { &hf_pnrp_message_nonce,
1352 { "Nonce", "pnrp.segment.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1353 NULL, HFILL }},
1354 { &hf_pnrp_message_hashednonce,
1355 { "Hashed Nonce", "pnrp.segment.hashednonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1356 NULL, HFILL }},
1357 { &hf_pnrp_message_idArray_NumEntries,
1358 { "Number of Entries", "pnrp.segment.idArray.NumEntries", FT_UINT16, BASE_DEC, NULL, 0x0,
1359 NULL, HFILL }},
1360 { &hf_pnrp_message_idArray_Length,
1361 { "Length of Array", "pnrp.segment.idArray.Length", FT_UINT16, BASE_DEC, NULL, 0x0,
1362 NULL, HFILL }},
1363 { &hf_pnrp_message_ElementFieldType,
1364 { "Type of Array Entry", "pnrp.segment.ElementFieldType", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1365 NULL, HFILL }},
1366 { &hf_pnrp_message_idarray_Entrylength,
1367 { "Length of each Array Entry", "pnrp.segment.idArray.Entrylength", FT_UINT16, BASE_DEC, NULL, 0x0,
1368 NULL, HFILL }},
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,
1374 NULL, HFILL }},
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,
1380 NULL, HFILL }},
1381 { &hf_pnrp_fragment,
1382 { "Fragment", "pnrp.segment.splitControls.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0,
1383 NULL, HFILL }},
1384 { &hf_pnrp_fragment_overlap,
1385 { "Fragment Overlap", "pnrp.segment.splitControls.fragment_overlap", FT_BOOLEAN, BASE_NONE, NULL, 0,
1386 NULL, HFILL }},
1387 { &hf_pnrp_fragment_overlap_conflict,
1388 { "Fragment Overlap Conflict", "pnrp.segment.splitControls.fragment_overlap_conflict", FT_BOOLEAN, BASE_NONE, NULL, 0,
1389 NULL, HFILL }},
1390 { &hf_pnrp_fragment_multiple_tails,
1391 { "Fragment Multiple Tails", "pnrp.segment.splitControls.fragment_multiple_tails", FT_BOOLEAN, BASE_NONE, NULL, 0,
1392 NULL, HFILL }},
1393 { &hf_pnrp_fragment_too_long_fragment,
1394 { "Too Long Fragment", "pnrp.segment.splitControls.fragment_too_long_fragment", FT_BOOLEAN, BASE_NONE, NULL, 0,
1395 NULL, HFILL }},
1396 { &hf_pnrp_fragment_error,
1397 { "Fragment Error", "pnrp.segment.splitControls.fragment_error", FT_FRAMENUM, BASE_NONE, NULL, 0,
1398 NULL, HFILL }},
1399 { &hf_pnrp_fragment_count,
1400 { "Fragment Count", "pnrp.segment.splitControls.fragment_count", FT_UINT32, BASE_DEC, NULL, 0,
1401 NULL, HFILL }},
1402 { &hf_pnrp_reassembled_in,
1403 { "Reassembled In", "pnrp.segment.splitControls.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0,
1404 NULL, HFILL }},
1405 { &hf_pnrp_reassembled_length,
1406 { "Reassembled Length", "pnrp.segment.splitControls.reassembled_length", FT_UINT32, BASE_DEC, NULL, 0,
1407 NULL, HFILL }},
1408 { &hf_pnrp_reassembled_data,
1409 { "Reassembled Data", "pnrp.segment.splitControls.reassembled_data", FT_BYTES, BASE_NONE, NULL, 0,
1410 NULL, HFILL }},
1411 { &hf_pnrp_fragmented_payload,
1412 { "Fragmented Payload", "pnrp.segment.splitControls.fragmented_payload", FT_BYTES, BASE_NONE, NULL, 0,
1413 NULL, HFILL }},
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[] = {
1444 &ett_pnrp,
1445 &ett_pnrp_header,
1446 &ett_pnrp_message,
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,
1455 &ett_pnrp_fragment,
1456 &ett_pnrp_fragments
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
1479 * Local variables:
1480 * c-basic-offset: 4
1481 * tab-width: 8
1482 * indent-tabs-mode: nil
1483 * End:
1485 * vi: set shiftwidth=4 tabstop=8 expandtab:
1486 * :indentSize=4:tabSize=8:noTabs=true: