HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-pnrp.c
blob05b65893d4a83fa705b36f9513064db6998de573
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 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* The official Dokumentation for the Peer Name Resolution Protocol can be found at
29 http://msdn.microsoft.com/en-us/library/cc239047(PROT.13).aspx
30 This dissector is based on Revision 6.1.2
33 #include "config.h"
35 #include <glib.h>
37 #include <epan/packet.h>
39 #define PROTONAME "Peer Name Resolution Protocol"
40 #define PROTOSHORTNAME "PNRP"
41 #define PROTOABBREV "pnrp"
43 #define PNRP_PORT 3540
45 #define FIELDID_LENGTH = 2
46 #define LENGTH_FIELD = 2
48 /* Define all FieldIDs here, so we can use them later on in switch statement etc */
49 #define PNRP_HEADER 0x0010
50 #define PNRP_HEADER_ACKED 0x0018
51 #define PNRP_ID 0x0030
52 #define TARGET_PNRP_ID 0x0038
53 #define VALIDATE_PNRP_ID 0x0039
54 #define FLAGS_FIELD 0x0040
55 #define FLOOD_CONTROLS 0x0043
56 #define SOLICIT_CONTROLS 0x0044
57 #define LOOKUP_CONTROLS 0x0045
58 #define EXTENDED_PAYLOAD 0x005A
59 #define PNRP_ID_ARRAY 0x0060
60 #define CERT_CHAIN 0x0080
61 #define WCHAR 0x0084
62 #define CLASSIFIER 0x0085
63 #define HASHED_NONCE 0x0092
64 #define NONCE 0x0093
65 #define SPLIT_CONTROLS 0x0098
66 #define ROUTING_ENTRY 0x009A
67 #define VALIDATE_CPA 0x009B
68 #define REVOKE_CPA 0x009C
69 #define IPV6_ENDPOINT 0x009D
70 #define IPV6_ENDPOINT_ARRAY 0x009E
72 /* Define all message types */
73 #define SOLICIT 0x01
74 #define ADVERTISE 0x02
75 #define REQUEST 0x03
76 #define FLOOD 0x04
77 #define INQUIRE 0x07
78 #define AUTHORITY 0x08
79 #define ACK 0x09
80 #define LOOKUP 0x0B
82 /* Define flags mask fields */
83 #define FLAGS_INQUIRE_RESERVED1 0xFFE0
84 #define FLAGS_INQUIRE_A 0x0010
85 #define FLAGS_INQUIRE_X 0x0008
86 #define FLAGS_INQUIRE_C 0x0004
87 #define FLAGS_INQUIRE_RESERVED2 0x0003
89 #define FLAGS_AUTHORITY_RESERVED1 0xFC00
90 #define FLAGS_AUTHORITY_L 0x0200
91 #define FLAGS_AUTHORITY_RESERVED2 0x01F0
92 #define FLAGS_AUTHORITY_B 0x0008
93 #define FLAGS_AUTHORITY_RESERVED3 0x0006
94 #define FLAGS_AUTHORITY_N 0x0001
96 #define FLAGS_LOOKUPCONTROLS_RESERVED 0xFFFC
97 #define FLAGS_LOOKUPCONTROLS_A 0x0002
98 #define FLAGS_LOOKUPCONTROLS_0 0x0001
100 #define FLAGS_ENCODED_CPA_RESERVED 0xC0
101 #define FLAGS_ENCODED_CPA_X 0x20
102 #define FLAGS_ENCODED_CPA_U 0x02
103 #define FLAGS_ENCODED_CPA_R 0x01
104 #define FLAGS_ENCODED_CPA_A 0x04
105 #define FLAGS_ENCODED_CPA_C 0x08
106 #define FLAGS_ENCODED_CPA_F 0x10
108 /* Define all helper methods */
109 static void dissect_pnrp_ids(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
110 static void dissect_ipv6_address(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
111 static void dissect_route_entry(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
112 static void dissect_ipv6_endpoint_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
113 static void dissect_encodedCPA_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
114 static void dissect_payload_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
115 static void dissect_publicKey_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
116 static void dissect_signature_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree);
118 /* Define global variables
119 ----------------------------*/
120 static int proto_pnrp = -1;
122 /* Define FieldIDs */
123 static const value_string fieldID[] = {
124 { PNRP_HEADER, "PNRP_HEADER" },
125 { PNRP_HEADER_ACKED, "PNRP_HEADER_ACKED" },
126 { PNRP_ID, "PNRP_ID" },
127 { TARGET_PNRP_ID, "TARGET_PNRP_ID" },
128 { VALIDATE_PNRP_ID, "VALIDATE_PNRP_ID" },
129 { FLAGS_FIELD, "FLAGS_FIELD" },
130 { FLOOD_CONTROLS, "FLOOD_CONTROLS" },
131 { SOLICIT_CONTROLS, "SOLICIT_CONTROLS" },
132 { LOOKUP_CONTROLS, "LOOKUP_CONTROLS" },
133 { EXTENDED_PAYLOAD, "EXTENDED_PAYLOAD" },
134 { PNRP_ID_ARRAY, "PNRP_ID_ARRAY" },
135 { CERT_CHAIN, "CERT_CHAIN" },
136 { WCHAR, "WCHAR" },
137 { CLASSIFIER, "CLASSIFIER" },
138 { HASHED_NONCE, "HASHED_NONCE" },
139 { NONCE, "NONCE" },
140 { SPLIT_CONTROLS, "SPLIT_CONTROLS" },
141 { ROUTING_ENTRY, "ROUTING_ENTRY" },
142 { VALIDATE_CPA, "VALIDATE_CPA" },
143 { REVOKE_CPA, "REVOKE_CPA" },
144 { IPV6_ENDPOINT, "IPV6_ENDPOINT" },
145 { IPV6_ENDPOINT_ARRAY, "IPV6_ENDPOINT_ARRAY" },
146 {0, NULL}
149 /* Define Packetnames */
150 static const value_string messageType[] = {
151 { SOLICIT, "SOLICIT" },
152 { ADVERTISE, "ADVERTISE" },
153 { REQUEST, "REQUEST" },
154 { FLOOD, "FLOOD" },
155 { INQUIRE, "INQUIRE" },
156 { AUTHORITY, "AUTHORITY" },
157 { ACK, "ACK" },
158 { LOOKUP, "LOOKUP" },
159 {0, NULL}
161 /* Define Solicit Type */
162 static const value_string solicitType[] = {
163 { 0x00, "SOLICIT_TYPE_ANY" },
164 { 0x01, "SOLICIT_TYPE_LOCAL" },
165 {0, NULL}
167 /* Define Resolve Criteria for Lookup Controls */
168 static const value_string resolveCriteria[] = {
169 { 0x00, "SEARCH_OPCODE_NONE" },
170 { 0x01, "SEARCH_OPCODE_ANY_PEERNAME" },
171 { 0x02, "SEARCH_OPCODE_NEAREST_PEERNAME" },
172 { 0x04, "SEARCH_OPCODE_NEAREST64_PEERNAME" },
173 { 0x08, "SEARCH_OPCODE_UPPER_BITS" },
174 {0, NULL}
176 /* Define Reason Code for Lookup Controls */
177 static const value_string reasonCode[] = {
178 { 0x00, "REASON_APP_REQUEST" },
179 { 0x01, "REASON_REGISTRATION" },
180 { 0x02, "REASON_CACHE_MAINTENANCE" },
181 { 0x03, "REASON_SPLIT_DETECTION" },
182 {0, NULL}
185 /* Define IDs for subcomponents */
186 /* Message Header */
187 static gint hf_pnrp_header = -1;
188 static gint hf_pnrp_header_fieldID = -1;
189 static gint hf_pnrp_header_length = -1;
190 static gint hf_pnrp_header_ident = -1;
191 static gint hf_pnrp_header_versionMajor = -1;
192 static gint hf_pnrp_header_versionMinor = -1;
193 static gint hf_pnrp_header_messageType = -1;
194 static gint hf_pnrp_header_messageID = -1;
195 /* Message Body */
196 static gint hf_pnrp_message_type = -1;
197 static gint hf_pnrp_message_length = -1;
198 static gint hf_pnrp_message_headerack = -1;
199 static gint hf_pnrp_message_pnrpID = -1; /* Generic variable to display pnrp ID in various situations */
200 /* Inquire Message Flags */
201 static gint hf_pnrp_message_inquire_flags = -1;
202 static gint hf_pnrp_message_inquire_flags_reserved1 = -1;
203 static gint hf_pnrp_message_inquire_flags_Abit = -1;
204 static gint hf_pnrp_message_inquire_flags_Xbit = -1;
205 static gint hf_pnrp_message_inquire_flags_Cbit = -1;
206 static gint hf_pnrp_message_inquire_flags_reserved2 = -1;
208 static const int *inquire_flags[] = {
209 &hf_pnrp_message_inquire_flags_reserved1,
210 &hf_pnrp_message_inquire_flags_Abit,
211 &hf_pnrp_message_inquire_flags_Xbit,
212 &hf_pnrp_message_inquire_flags_Cbit,
213 &hf_pnrp_message_inquire_flags_reserved2,
214 NULL
217 /* Classifier */
218 static gint hf_pnrp_message_classifier_unicodeCount = -1;
219 static gint hf_pnrp_message_classifier_arrayLength = -1;
220 static gint hf_pnrp_message_classifier_entryLength = -1;
221 /* ACK Message Flags */
222 static gint hf_pnrp_message_ack_flags_reserved = -1;
223 static gint hf_pnrp_message_ack_flags_Nbit = -1;
224 /* SplitControls */
225 static gint hf_pnrp_message_splitControls_authorityBuffer = -1;
226 /* IPv6 Endpoint Array */
227 static gint hf_pnrp_message_ipv6EndpointArray_NumberOfEntries = -1;
228 static gint hf_pnrp_message_ipv6EndpointArray_ArrayLength = -1;
229 static gint hf_pnrp_message_ipv6EndpointArray_EntryLength = -1;
230 /* AUTHORITY Message Flags */
231 static gint hf_pnrp_message_authority_flags = -1;
232 static gint hf_pnrp_message_authority_flags_reserved1 = -1;
233 static gint hf_pnrp_message_authority_flags_Lbit = -1;
234 static gint hf_pnrp_message_authority_flags_reserved2 = -1;
235 static gint hf_pnrp_message_authority_flags_Bbit = -1;
236 static gint hf_pnrp_message_authority_flags_reserved3= -1;
237 static gint hf_pnrp_message_authority_flags_Nbit = -1;
239 static const int *authority_flags[] = {
240 &hf_pnrp_message_authority_flags_reserved1,
241 &hf_pnrp_message_authority_flags_Lbit,
242 &hf_pnrp_message_authority_flags_reserved2,
243 &hf_pnrp_message_authority_flags_Bbit,
244 &hf_pnrp_message_authority_flags_reserved3,
245 &hf_pnrp_message_authority_flags_Nbit,
246 NULL
249 /* Flood Control Flags */
250 static gint hf_pnrp_message_flood_flags_reserved1 = -1;
251 static gint hf_pnrp_message_flood_flags_Dbit = -1;
253 /* PNRP ID Array */
254 static gint hf_pnrp_message_idArray_NumEntries = -1;
255 static gint hf_pnrp_message_idArray_Length = -1;
256 static gint hf_pnrp_message_ElementFieldType = -1;
257 static gint hf_pnrp_message_idarray_Entrylength = -1;
259 static gint hf_pnrp_message_solicitType = -1;
260 static gint hf_pnrp_message_certChain = -1;
261 static gint hf_pnrp_message_nonce = -1;
262 static gint hf_pnrp_message_hashednonce = -1;
263 static gint hf_pnrp_message_ipv6 = -1;
265 /* Encoded CPA */
266 static gint hf_pnrp_encodedCPA = -1;
267 static gint hf_pnrp_encodedCPA_length = -1;
268 static gint hf_pnrp_encodedCPA_minorVersion = -1;
269 static gint hf_pnrp_encodedCPA_majorVersion = -1;
270 static gint hf_pnrp_encodedCPA_flags = -1;
271 static gint hf_pnrp_encodedCPA_flags_reserved = -1;
272 static gint hf_pnrp_encodedCPA_flags_Xbit = -1;
273 static gint hf_pnrp_encodedCPA_flags_Fbit = -1;
274 static gint hf_pnrp_encodedCPA_flags_Cbit = -1;
275 static gint hf_pnrp_encodedCPA_flags_Abit = -1;
276 static gint hf_pnrp_encodedCPA_flags_Ubit = -1;
277 static gint hf_pnrp_encodedCPA_flags_Rbit = -1;
278 static const int *encodedCPA_flags[] = {
279 &hf_pnrp_encodedCPA_flags_reserved,
280 &hf_pnrp_encodedCPA_flags_Xbit,
281 &hf_pnrp_encodedCPA_flags_Fbit,
282 &hf_pnrp_encodedCPA_flags_Cbit,
283 &hf_pnrp_encodedCPA_flags_Abit,
284 &hf_pnrp_encodedCPA_flags_Ubit,
285 &hf_pnrp_encodedCPA_flags_Rbit,
286 NULL
288 static gint hf_pnrp_encodedCPA_notAfter = -1;
289 static gint hf_pnrp_encodedCPA_serviceLocation = -1;
290 static gint hf_pnrp_encodedCPA_binaryAuthority = -1;
291 static gint hf_pnrp_encodedCPA_classifiertHash = -1;
292 static gint hf_pnrp_encodedCPA_friendlyName = -1;
294 /* Lookup Controls */
295 static gint hf_pnrp_message_lookupControls_flags = -1;
296 static gint hf_pnrp_message_lookupControls_flags_reserved = -1;
297 static gint hf_pnrp_message_lookupControls_flags_Abit = -1;
298 static gint hf_pnrp_message_lookupControls_flags_0bit = -1;
299 static const int *lookupControls_flags[] = {
300 &hf_pnrp_message_lookupControls_flags_reserved,
301 &hf_pnrp_message_lookupControls_flags_Abit,
302 &hf_pnrp_message_lookupControls_flags_0bit,
303 NULL
305 static gint hf_pnrp_message_lookupControls_precision =-1;
306 static gint hf_pnrp_message_lookupControls_resolveCriteria =-1;
307 static gint hf_pnrp_message_lookupControls_reasonCode =-1;
309 /* Dissect Route Entry */
310 static gint hf_pnrp_message_routeEntry_portNumber = -1;
311 static gint hf_pnrp_message_routeEntry_flags = -1;
312 static gint hf_pnrp_message_routeEntry_addressCount = -1;
314 /* Public Key Structure */
315 static gint hf_pnrp_publicKey_objID = -1;
316 static gint hf_pnrp_publicKey_publicKeyData = -1;
318 /* Signature Structure */
319 static gint hf_pnrp_signature_signatureData = -1;
321 /* Define variables to reference subtrees */
322 static gint ett_pnrp = -1;
323 static gint ett_pnrp_header = -1;
324 static gint ett_pnrp_message = -1;
325 static gint ett_pnrp_message_inquire_flags = -1;
326 static gint ett_pnrp_message_authority_flags = -1;
327 static gint ett_pnrp_message_encodedCPA = -1;
328 static gint ett_pnrp_message_encodedCPA_flags = -1;
329 static gint ett_pnrp_message_lookupControls_flags = -1;
330 static gint ett_pnrp_message_payloadStructure = -1;
331 static gint ett_pnrp_message_publicKeyStructure = -1;
332 static gint ett_pnrp_message_signatureStructure = -1;
335 /* Do actual dissection work */
336 static int dissect_pnrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
338 /* Variable declaration */
339 gint offset;
340 gint padding_bytes;
341 guint8 message_type;
342 guint16 field_type;
343 guint16 data_length;
346 /*----------------------------------------
347 * Validate if it is really a PNRP Packet
348 *----------------------------------------*/
349 /* Check that there's enough data */
350 /* XXX: ISTR that tvb_length should be used when */
351 /* initially checking for a valid packet for a */
352 /* new style dissector. */
353 /* ToDo: confirm */
354 data_length = tvb_reported_length(tvb);
356 /* Shortest Message is ACK -> 12 Bytes for Header plus 8 Bytes for Data */
357 if (data_length < 12+8 )
359 return 0;
362 /* Check some values from the packet header */
363 /* First 2 bytes must be 0x0010 */
364 if (tvb_get_ntohs(tvb,0) != PNRP_HEADER )
366 return 0;
368 /* Length of Header must be 0x000C = 12 */
369 if (tvb_get_ntohs(tvb,2) != 0x000C) {
370 return 0;
372 /* Identifier must 0x51 */
373 if (tvb_get_guint8(tvb,4) != 0x51) {
374 return 0;
378 /* Assign Values to Variables */
379 /* Use to track data */
380 offset= 0;
381 /* Get the message Information beforehand */
382 message_type = tvb_get_guint8(tvb,7);
385 /* Simply Display the Protcol Name in the INFO column */
386 col_set_str(pinfo->cinfo, COL_PROTOCOL, "pnrp");
387 /* Clear out stuff in the info column */
388 col_add_fstr(pinfo->cinfo, COL_INFO, "PNRP %s Message ",
389 val_to_str(message_type, messageType, "Unknown (0x%02x)"));
392 /* If tree is NULL we are asked for summary, otherwise for details */
393 if(tree){ /* we are beeing asked for details */
394 proto_item *ti;
395 proto_tree *pnrp_tree;
397 proto_item *pnrp_header_item;
398 proto_tree *pnrp_header_tree;
400 proto_item *pnrp_message_tree = NULL;
401 proto_item *pnrp_message_item = NULL;
404 /* Lets add a subtree to our dissection to display the info */
405 ti = proto_tree_add_item(tree, proto_pnrp, tvb, 0, -1, ENC_NA);
406 proto_item_append_text(ti, ", Message Type %s",
407 val_to_str(message_type, messageType, "Unknown (0x%02x)"));
408 /* Get a main tree for the whole protocol */
409 pnrp_tree = proto_item_add_subtree(ti, ett_pnrp);
411 /*-------------------------------
412 *--Add all Header Fields
413 *------------------------------*/
414 /* Get a subtree for the Header */
415 pnrp_header_item = proto_tree_add_item(pnrp_tree, hf_pnrp_header, tvb, offset,12,ENC_NA);
416 pnrp_header_tree = proto_item_add_subtree(pnrp_header_item, ett_pnrp_header);
418 /* Add Field ID should be 0c0010 */
419 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_fieldID,tvb,offset,2,ENC_BIG_ENDIAN);
420 offset += 2;
421 /* Add Length should be 0x000C */
422 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_length,tvb,offset,2,ENC_BIG_ENDIAN);
423 offset += 2;
424 /* Add Ident should be 0x51 */
425 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_ident,tvb,offset,1,ENC_BIG_ENDIAN);
426 offset += 1;
427 /* Add Major Version */
428 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMajor,tvb,offset,1,ENC_BIG_ENDIAN);
429 offset += 1;
430 /* Add Minor Version */
431 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMinor,tvb,offset,1,ENC_BIG_ENDIAN);
432 offset += 1;
433 /* Add Message Type */
434 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_messageType,tvb,offset,1,ENC_BIG_ENDIAN);
435 offset += 1;
436 /* Add Message ID */
437 proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_messageID,tvb,offset,4,ENC_BIG_ENDIAN);
438 offset += 4;
441 /*-------------------------------
442 *--Add all Message Fields
443 *------------------------------*/
445 /* The following part has dynamic length depending on message type */
446 while (tvb_reported_length_remaining(tvb, offset) > 0) {
447 /* Determine the Field Type */
448 field_type = tvb_get_ntohs(tvb,offset );
449 /* Determine length of this message */
450 data_length = tvb_get_ntohs(tvb,offset + 2);
452 /* Length must be at least 4, because field_type and data_length are part of data_length information */
453 if (data_length < 4) {
454 if (tree) {
455 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset, 4, "Message with invalid length %u (< 4)", data_length);
456 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
457 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
458 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
460 offset += 4;
461 /* Don't continue parsing this message segment */
462 break;
464 /* Actual Parsing of the message Type */
465 switch (field_type) {
466 /* First Field in ACK Message */
467 case PNRP_HEADER_ACKED:
468 if (tree) {
469 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
470 data_length, "Message ACK ID: ");
471 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
472 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
473 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
474 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_headerack, tvb, offset + 4, data_length -4, ENC_BIG_ENDIAN);
477 offset += data_length;
478 break;
480 /* A validate pnrp id follows as found in FLOOD */
481 case VALIDATE_PNRP_ID:
482 if (tree) {
483 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
484 data_length, "Validate PNRP ID: ");
485 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
486 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
487 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
488 /* We can have a large number of pnrp IDs here */
489 dissect_pnrp_ids(tvb,offset+4,data_length-4,pnrp_message_tree);
492 offset += data_length;
493 break;
495 /* The Flags have different meaning, depending on the message */
496 case FLAGS_FIELD:
497 if (tree) {
498 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
499 data_length, "Flags Field: ");
500 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
501 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
502 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
503 switch (message_type) {
504 case INQUIRE:
505 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);
506 proto_tree_add_text(pnrp_message_tree, tvb, offset + 6, 2, "Padding : %d - 2 Bytes",tvb_get_ntohs(tvb,offset+6));
507 offset += data_length+2;
509 break;
511 case ACK:
512 /* Reserved 0 - 14 bits */
513 proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_ack_flags_reserved, tvb, (offset + 4)*8, 15, ENC_BIG_ENDIAN);
514 /* N - Bit */
515 proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_ack_flags_Nbit, tvb,((offset + 4)*8)+15, 1, ENC_BIG_ENDIAN);
516 offset += data_length;
517 break;
518 case AUTHORITY:
519 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);
520 /* Check if the Flags Field is the last message part. If so, no padding of 2 bytes is added */
521 if(tvb_reported_length_remaining(tvb, offset+data_length)==0)
523 offset += data_length;
525 else {
526 padding_bytes = 2;
527 proto_tree_add_text(pnrp_message_tree, tvb, offset + 6, padding_bytes, "Padding: %d bytes", padding_bytes);
528 offset += data_length+2;
530 break;
533 default:
534 proto_tree_add_text(pnrp_message_tree, tvb, offset + 4, data_length -4, "Flags");
535 offset += data_length;
536 break;
541 break;
543 /* Flood controls found in FLOOD Message */
544 case FLOOD_CONTROLS:
545 if (tree) {
546 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
547 data_length, "Flood Control: ");
548 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
549 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
550 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
551 /* Reserved 1 - 15 bits */
552 proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_flood_flags_reserved1, tvb, (offset + 4)*8, 15, ENC_BIG_ENDIAN);
553 /* D - Bit */
554 proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_flood_flags_Dbit, tvb,((offset + 4)*8)+15, 1, ENC_BIG_ENDIAN);
555 /* Reserved 2 */
556 proto_tree_add_text(pnrp_message_tree, tvb, offset + 6, 1, "Reserved 2: %d",tvb_get_guint8(tvb,offset+6));
557 /* Padding 1 */
558 proto_tree_add_text(pnrp_message_tree, tvb, offset + 7, 1, "Padding: %d",tvb_get_guint8(tvb,offset+7));
561 offset += data_length+1;
562 break;
564 /* Solicit Controls found in SOLICIT Message */
565 case SOLICIT_CONTROLS:
566 if (tree) {
567 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
568 data_length, "Solicit Controls: ");
569 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
570 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
571 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
572 proto_tree_add_text(pnrp_message_tree, tvb, offset + 4, 1, "Reserved : %d",tvb_get_guint8(tvb,offset+4));
573 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_solicitType, tvb, offset + 5, 1, ENC_BIG_ENDIAN);
574 proto_tree_add_text(pnrp_message_tree, tvb, offset + 6, 2, "Reserved : %d",tvb_get_ntohs(tvb,offset+6));
576 offset += data_length +2; /* Padding involved */
577 break;
578 /* Lookup controls found in LOOKUP Message */
579 case LOOKUP_CONTROLS:
580 if (tree) {
581 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
582 data_length, "Lookup Control: ");
583 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
584 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
585 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
586 /* 2 Bytes of Flags */
587 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);
588 /* Precision Bytes */
589 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_precision, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
590 /* Resolve Criteria */
591 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_resolveCriteria, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
592 /* Reason Code */
593 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_reasonCode, tvb, offset + 9, 1, ENC_BIG_ENDIAN);
594 /* Reserved */
595 proto_tree_add_text(pnrp_message_tree, tvb, offset + 10, 2, "Reserved : %d",tvb_get_ntohs(tvb,offset+10));
599 offset += data_length;
600 break;
601 /* Target PNRP ID found in Lookup Message */
602 case TARGET_PNRP_ID:
603 if (tree) {
604 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
605 data_length, "Target PNRP ID: ");
606 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
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 dissect_pnrp_ids(tvb, offset+4, data_length-4, pnrp_message_tree);
612 offset += data_length;
613 break;
615 /* Extended Payload found in AUTHORITY Message */
616 case EXTENDED_PAYLOAD:
617 if (tree) {
618 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
619 data_length, "Extended Payload: ");
620 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
621 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
622 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
623 /* TODO: Do actual parsing */
626 offset += data_length;
627 break;
628 /* Pnrp id Array as found in REQUEST & ADVERTISE Message */
629 case PNRP_ID_ARRAY:
630 if (tree) {
631 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
632 data_length, "PNRP ID Array: ");
633 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
634 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
635 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
636 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idArray_NumEntries, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
637 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idArray_Length, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
638 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ElementFieldType, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
639 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idarray_Entrylength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
640 dissect_pnrp_ids(tvb,offset+12,data_length-12,pnrp_message_tree);
643 offset += data_length;
644 break;
645 /* Cert Chain follows as found in AUTHORITY */
646 case CERT_CHAIN:
647 if (tree) {
648 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
649 data_length, "CERT Chain: ");
650 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
651 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
652 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
653 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_certChain, tvb, offset + 4, data_length-4, ENC_NA);
656 /* There might be padding, so fill up to the next byte */
657 padding_bytes = 0;
658 while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
659 data_length++;
660 padding_bytes++;
662 /* Check if we actually had some padding bytes */
663 if (0<padding_bytes) {
664 proto_tree_add_text(pnrp_message_tree, tvb, offset + data_length-padding_bytes, padding_bytes, "Padding: %d bytes", padding_bytes);
666 offset += data_length;
667 break;
668 /* classifier: A classifier string follows as found in AUTHORITY */
669 case CLASSIFIER:
670 if (tree) {
671 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
672 data_length, "Classifier: ");
673 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
674 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
675 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
676 /* NumEntries */
677 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_unicodeCount, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
678 /* Array Length: 8+(NumEntries*EntryLength */
679 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_arrayLength, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
680 /* Element Field Type: WCHAR */
681 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset+8 , 2, ENC_BIG_ENDIAN);
682 /* Entry Length: Must be 0x0002 */
683 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_entryLength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
684 /* The actual classifier String */
685 proto_tree_add_text(pnrp_message_tree, tvb, offset + 12, tvb_get_ntohs(tvb,offset+6)-8, "Classifier: %s",tvb_get_unicode_string(wmem_packet_scope(), tvb, offset + 12, tvb_get_ntohs(tvb,offset+6)-8, ENC_BIG_ENDIAN));
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_text(pnrp_message_tree, tvb, offset + data_length-padding_bytes, padding_bytes, "Padding: %d bytes", padding_bytes);
698 offset += data_length;
699 break;
700 /* A hashed nonce follows as found in ADVERTISE & SOLICIT */
701 case HASHED_NONCE:
702 if (tree) {
703 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
704 data_length, "Hashed Nonce: ");
705 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
706 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
707 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_hashednonce, tvb, offset + 4, data_length-4, ENC_NA);
712 offset += data_length;
713 break;
715 /* A nonce follows as found in REQUEST & INQUIRE */
716 case NONCE:
717 if (tree) {
718 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
719 data_length, "Nonce: ");
720 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
721 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
722 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
723 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_nonce, tvb, offset + 4, data_length-4, ENC_NA);
726 offset += data_length;
727 break;
729 /* split controls as found in AUTHORITY */
730 case SPLIT_CONTROLS:
731 if (tree) {
732 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
733 data_length, "Split controls: ");
734 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
735 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
736 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
737 /* Size of Authority Buffer */
738 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_splitControls_authorityBuffer, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
739 /* Byte offset */
740 proto_tree_add_text(pnrp_message_tree, tvb, offset + 6, 2, "Offset : %d",tvb_get_ntohs(tvb,offset+6));
744 /* There could be data offset */
745 offset += data_length+tvb_get_ntohs(tvb,offset+6);
746 break;
748 /* routing entry: A route entry follows as found in ADVERTISE, INQUIRE, LOOKUP & AUTHORITY */
749 case ROUTING_ENTRY:
750 if (tree) {
751 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
752 data_length, "Routing Entry: ");
753 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
754 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
755 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
756 dissect_route_entry(tvb,offset+4, tvb_get_ntohs(tvb,offset+2)-4, pnrp_message_tree);
759 /* There might be padding, so fill up to the next byte */
760 padding_bytes = 0;
761 while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
762 data_length++;
763 padding_bytes++;
765 /* Check if we actually had some padding bytes */
766 if (0<padding_bytes) {
767 proto_tree_add_text(pnrp_message_tree, tvb, offset + data_length-padding_bytes, padding_bytes, "Padding: %d bytes", padding_bytes);
769 offset += data_length;
770 break;
772 /* validate cpa: an encoded CPA structure follows as found in AUTHORITY */
773 case VALIDATE_CPA:
774 if (tree) {
775 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
776 data_length, "Validate CPA: ");
777 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
778 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
779 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
780 /* Do the actual parsing in own method */
781 dissect_encodedCPA_structure(tvb, offset+4, data_length-4, pnrp_message_tree);
785 offset += data_length;
786 break;
789 /* IPV6 Endpoint: an ipv6 endpoint array structure follows as found in LOOKUP */
790 case IPV6_ENDPOINT_ARRAY:
791 if (tree) {
792 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
793 data_length, "IPv6 Endpoint Array: ");
794 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
795 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
796 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
797 /* Number of route entries */
798 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_NumberOfEntries, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
799 /* Array length */
800 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_ArrayLength, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
801 /* Element Field Type */
802 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset+8 , 2, ENC_BIG_ENDIAN);
803 /* Entry Length: must be 0x0012 (18 bytes) */
804 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_EntryLength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
805 /* Flagged Path */
806 dissect_ipv6_endpoint_structure(tvb, offset+12, tvb_get_ntohs(tvb,offset+6)-8,pnrp_message_tree);
809 offset += data_length;
810 break;
812 default:
813 if (tree) {
814 pnrp_message_item = proto_tree_add_text(pnrp_tree, tvb, offset,
815 data_length, "Type: %s, length: %u",
816 val_to_str(field_type, fieldID, "Unknown (0x%04x)"), data_length);
817 pnrp_message_tree = proto_item_add_subtree(pnrp_message_item, ett_pnrp_message);
818 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
819 proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
820 if(data_length > 4)
822 proto_tree_add_text(pnrp_message_tree, tvb, offset + 4, data_length -4, "Data");
824 else {
825 return 0;
828 offset += data_length;
829 break;
833 return offset;
837 /*--------------------------------------------------------------*
838 * Dissecting helper methods *
839 *--------------------------------------------------------------*/
841 static void dissect_pnrp_ids(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
843 while (32 <=length) {
844 proto_tree_add_item(tree, hf_pnrp_message_pnrpID, tvb, offset, 32, ENC_NA);
845 length -= 32;
846 offset += 32;
851 static void dissect_route_entry(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
853 gint tmp_offset;
854 /* Check if we don't run out of data */
855 if (0 <= tvb_reported_length_remaining(tvb, offset+length)) {
856 tmp_offset = 0;
857 /* First, we have a 32 Bit long PNRP ID */
858 proto_tree_add_item(tree, hf_pnrp_message_pnrpID, tvb, offset+tmp_offset, 32, ENC_NA);
859 tmp_offset +=32;
860 /* Add PNRP Major Version */
861 proto_tree_add_item(tree,hf_pnrp_header_versionMajor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
862 tmp_offset += 1;
863 /* Add Minor Version */
864 proto_tree_add_item(tree,hf_pnrp_header_versionMinor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
865 tmp_offset +=1;
866 /* Port Number */
867 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_portNumber,tvb,offset+tmp_offset,2,ENC_BIG_ENDIAN);
868 tmp_offset +=2;
869 /* Flags */
870 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_flags,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
871 tmp_offset +=1;
872 /* Address count */
873 proto_tree_add_item(tree,hf_pnrp_message_routeEntry_addressCount,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
874 tmp_offset +=1;
875 /* IPv6 Addresses */
876 dissect_ipv6_address(tvb, offset+tmp_offset, length -tmp_offset, tree);
880 static void dissect_ipv6_endpoint_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
882 /* Check if we don't run out of data */
883 while (0 <= tvb_reported_length_remaining(tvb, offset+18) && 18 <=length) {
884 /* Port Number */
885 proto_tree_add_text(tree, tvb, offset, 2, "Port Number : %d",tvb_get_ntohs(tvb, offset));
886 /* IPv6 Addresses */
887 dissect_ipv6_address(tvb, offset+2,16,tree);
888 offset += 18;
889 length -= 18;
893 static void dissect_ipv6_address(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
895 while (0 <= tvb_reported_length_remaining(tvb, offset+16) && 16 <=length) {
896 proto_tree_add_item(tree, hf_pnrp_message_ipv6, tvb, offset, 16, ENC_NA);
897 offset += 16;
898 length -= 16;
902 static void dissect_encodedCPA_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
904 /* Check if we don't run out of data */
905 if (0 <= tvb_reported_length_remaining(tvb, offset+length)) {
906 guint8 flagsField;
907 /* Add a new subtree */
908 proto_item *pnrp_encodedCPA_tree = NULL;
909 proto_item *pnrp_encodedCPA_item = NULL;
910 pnrp_encodedCPA_item = proto_tree_add_item(tree, hf_pnrp_encodedCPA, tvb, offset,length,ENC_NA);
911 pnrp_encodedCPA_tree = proto_item_add_subtree(pnrp_encodedCPA_item, ett_pnrp_message_encodedCPA);
913 /* Length information */
914 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_length, tvb, offset, 2, ENC_BIG_ENDIAN);
915 /* CPA Minor Version */
916 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_minorVersion, tvb, offset+2, 1, ENC_BIG_ENDIAN);
917 /* CPA Major Version */
918 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_majorVersion, tvb, offset+3, 1, ENC_BIG_ENDIAN);
919 /* PNRP Minor Version */
920 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_header_versionMinor, tvb, offset+4, 1, ENC_BIG_ENDIAN);
921 /* PNRP Major Version */
922 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_header_versionMajor, tvb, offset+5, 1, ENC_BIG_ENDIAN);
923 /* Flags Field */
924 proto_tree_add_bitmask(pnrp_encodedCPA_tree, tvb, offset+6, hf_pnrp_encodedCPA_flags, ett_pnrp_message_encodedCPA_flags, encodedCPA_flags, ENC_BIG_ENDIAN);
925 flagsField = tvb_get_guint8(tvb,offset+6);
926 /* Reserved */
927 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset + 7, 1, "Reserved");
928 /* Not After */
929 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_notAfter, tvb, offset+8, 8, ENC_BIG_ENDIAN);
930 /* Service Location */
931 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_serviceLocation, tvb, offset+16, 16, ENC_NA);
933 /* now, the structure is variable, so add bytes to offset */
934 offset +=32;
936 /* Check if R Flag is set */
937 if ((flagsField & FLAGS_ENCODED_CPA_R)==0x00) {
938 /* Nonce follows */
939 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_message_nonce, tvb, offset, 16, ENC_NA);
940 offset +=16;
942 /* Check if A Flag is set */
943 if (flagsField & FLAGS_ENCODED_CPA_A) {
944 /* Binary authority */
945 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_binaryAuthority, tvb, offset, 20, ENC_NA);
946 offset +=20;
948 /* Check if C Flag is set */
949 if (flagsField & FLAGS_ENCODED_CPA_C) {
950 /* Classifiert Hash */
951 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_classifiertHash, tvb, offset, 20, ENC_NA);
952 offset +=20;
954 /* Check if F Flag is set */
955 if (flagsField & FLAGS_ENCODED_CPA_F) {
956 /* Friendly Name Length */
957 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset,2, "Length of Friendly name : %d",tvb_get_letohs(tvb,offset));
958 /* Friendly Name */
959 proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_friendlyName, tvb, offset+2, tvb_get_letohs(tvb,offset), ENC_ASCII|ENC_NA);
960 offset +=tvb_get_letohs(tvb,offset)+2;
962 /* Service Address List */
963 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset,2, "Number of Service Addresses : %d",tvb_get_letohs(tvb,offset));
964 offset += 2;
965 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset,2, "Service Address Length : %d",tvb_get_letohs(tvb,offset));
966 offset += 2;
967 /* A list of IPV6_Endpoint Structures follows */
968 dissect_ipv6_endpoint_structure(tvb, offset,tvb_get_letohs(tvb,offset-4)*tvb_get_letohs(tvb,offset-2) , pnrp_encodedCPA_tree);
969 offset += tvb_get_letohs(tvb,offset-4)*tvb_get_letohs(tvb,offset-2);
970 /* A number of Payload Structures */
971 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset,2, "Number of Payload Structures : %d",tvb_get_letohs(tvb,offset));
972 offset += 2;
973 proto_tree_add_text(pnrp_encodedCPA_tree, tvb, offset,2, "Total Bytes of Payload : %d",tvb_get_letohs(tvb,offset));
974 offset += 2;
975 dissect_payload_structure(tvb,offset, tvb_get_letohs(tvb,offset-2)-4,pnrp_encodedCPA_tree);
976 offset += tvb_get_letohs(tvb,offset-2)-4;
977 /* Public Key */
978 dissect_publicKey_structure(tvb, offset,tvb_get_letohs(tvb,offset),pnrp_encodedCPA_tree);
979 offset += tvb_get_letohs(tvb,offset);
980 /* Signature */
981 dissect_signature_structure(tvb, offset,tvb_get_letohs(tvb,offset),pnrp_encodedCPA_tree);
982 /*offset += tvb_get_letohs(tvb,offset);*/
985 static void dissect_payload_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
987 guint16 lengthOfData;
988 /* Add a new Subtree */
989 proto_item *pnrp_payload_tree = NULL;
990 proto_item *pnrp_payload_item = NULL;
991 /* Check if we actually should display something */
992 if (0<length ) {
993 pnrp_payload_item = proto_tree_add_text(tree, tvb, offset, length, "Payload Structure");
994 pnrp_payload_tree = proto_item_add_subtree(pnrp_payload_item, ett_pnrp_message_payloadStructure);
996 /* Dissect the Payload Structure */
997 /* Payload Type */
998 proto_tree_add_text(pnrp_payload_tree, tvb, offset,4, "Payload Type : %d",tvb_get_letohl(tvb,offset));
999 offset += 4;
1000 /* Data Length */
1001 lengthOfData = tvb_get_letohs(tvb,offset);
1002 proto_tree_add_text(pnrp_payload_tree, tvb, offset,2, "Length of Data : %d",lengthOfData);
1003 offset += 2;
1004 /* IPV6_APP_ENDPOINT Structure */
1005 while (0 <= tvb_reported_length_remaining(tvb, offset+20)&& 20 <= lengthOfData) {
1006 dissect_ipv6_address(tvb, offset, 16, pnrp_payload_tree);
1007 offset += 16;
1008 proto_tree_add_text(pnrp_payload_tree, tvb, offset,2, "Port Number : %d",tvb_get_letohs(tvb,offset));
1009 /* proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_port, tvb, offset, 2, ENC_BIG_ENDIAN); */
1010 offset += 2;
1011 proto_tree_add_text(pnrp_payload_tree, tvb, offset,2, "IANA Protocol Number : %d",tvb_get_letohs(tvb,offset));
1012 offset += 2;
1013 lengthOfData -=20;
1017 static void dissect_publicKey_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
1019 guint16 objIDLength;
1020 guint16 cbDataLength;
1021 /* Add a new Subtree */
1022 proto_item *pnrp_publicKey_tree = NULL;
1023 proto_item *pnrp_publicKey_item = NULL;
1024 /* Check if we can safely parse Data */
1025 if (0 < length && 0 <= tvb_reported_length_remaining(tvb, offset+length)) {
1026 pnrp_publicKey_item = proto_tree_add_text(tree, tvb, offset, length, "CPA Public Key Structure");
1027 pnrp_publicKey_tree = proto_item_add_subtree(pnrp_publicKey_item, ett_pnrp_message_publicKeyStructure);
1028 /* Parsing of Data */
1029 /* Field Length of Structure */
1030 proto_tree_add_text(pnrp_publicKey_tree, tvb, offset,2, "Length of Structure : %d",tvb_get_letohs(tvb,offset));
1031 offset += 2;
1032 /* ObjID length */
1033 objIDLength = tvb_get_letohs(tvb,offset);
1034 proto_tree_add_text(pnrp_publicKey_tree, tvb, offset,2, "Size of Algorithm OID : %d",objIDLength);
1035 offset += 2;
1036 /* Reserved */
1037 proto_tree_add_text(pnrp_publicKey_tree, tvb, offset,2, "Reserved : %d",tvb_get_ntohs(tvb,offset));
1038 offset +=2;
1039 /* Public Key cbData Length */
1040 cbDataLength = tvb_get_letohs(tvb,offset);
1041 proto_tree_add_text(pnrp_publicKey_tree, tvb, offset,2, "Size of cbData : %d",cbDataLength);
1042 offset += 2;
1043 /* Unused Bits, actually only 7... */
1044 proto_tree_add_text(pnrp_publicKey_tree, tvb, offset,1, "Unused Bits : %d",7);
1045 offset +=1;
1046 /* Algorithm ObjID */
1047 proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_objID, tvb, offset, objIDLength, ENC_ASCII|ENC_NA);
1048 offset += objIDLength;
1049 /* Public Key Data */
1050 proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_publicKeyData, tvb, offset, cbDataLength, ENC_ASCII|ENC_NA);
1053 static void dissect_signature_structure(tvbuff_t *tvb, gint offset, gint length, proto_tree *tree)
1055 guint16 signatureLength;
1056 /* Add a new Subtree */
1057 proto_item *pnrp_signature_tree = NULL;
1058 proto_item *pnrp_signature_item = NULL;
1059 /* Check if we can safely parse Data */
1060 if (0 < length && 0 <= tvb_reported_length_remaining(tvb, offset+length)) {
1061 pnrp_signature_item = proto_tree_add_text(tree, tvb, offset, length, "Signature Structure");
1062 pnrp_signature_tree = proto_item_add_subtree(pnrp_signature_item, ett_pnrp_message_signatureStructure);
1063 /* Parsing of Data */
1064 /* Field Length of Structure */
1065 proto_tree_add_text(pnrp_signature_tree, tvb, offset,2, "Length of Structure : %d",tvb_get_letohs(tvb,offset));
1066 offset +=2;
1067 /* Signature Length */
1068 signatureLength = tvb_get_letohs(tvb,offset);
1069 proto_tree_add_text(pnrp_signature_tree, tvb, offset,2, "Length of Signature : %d",signatureLength);
1070 offset += 2;
1071 /* Hash Algorithm Identifier */
1072 proto_tree_add_text(pnrp_signature_tree, tvb, offset,4, "Hash Algorithm Identifier : %x",tvb_get_letohl(tvb,offset));
1073 offset += 4;
1074 /* Signature Data */
1075 proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_signatureData, tvb, offset, signatureLength, ENC_NA);
1078 /* Register the protocol */
1079 void proto_register_pnrp(void)
1081 /* A header field is something you can search/filter on.
1083 * We create a structure to register our fields. It consists of an
1084 * array of hf_register_info structures, each of which are of the format
1085 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1087 static hf_register_info hf[] = {
1088 { &hf_pnrp_header,
1089 { "Header", "pnrp.header", FT_NONE, BASE_NONE, NULL, 0x0,
1090 "PNRP Header", HFILL }},
1091 { &hf_pnrp_header_fieldID,
1092 { "Header FieldID", "pnrp.header.fieldID", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1093 NULL, HFILL }},
1094 { &hf_pnrp_header_length,
1095 { "Header length", "pnrp.header.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1096 NULL, HFILL }},
1097 { &hf_pnrp_header_ident,
1098 { "Ident", "pnrp.ident", FT_UINT8, BASE_HEX, NULL, 0x0,
1099 NULL, HFILL }},
1100 { &hf_pnrp_header_versionMajor,
1101 { "Version Major", "pnrp.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1102 NULL, HFILL }},
1103 { &hf_pnrp_header_versionMinor,
1104 { "Version Minor", "pnrp.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1105 NULL, HFILL }},
1106 { &hf_pnrp_header_messageType,
1107 { "Message Type", "pnrp.messageType", FT_UINT8, BASE_DEC, VALS(messageType), 0x0,
1108 NULL, HFILL }},
1109 { &hf_pnrp_header_messageID,
1110 { "Message ID", "pnrp.header.messageID", FT_UINT32, BASE_HEX, NULL, 0x0,
1111 NULL, HFILL }},
1112 { &hf_pnrp_message_type,
1113 { "Segment Type", "pnrp.segment.type", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1114 NULL, HFILL }},
1115 { &hf_pnrp_message_length,
1116 { "Segment length", "pnrp.segment.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1117 "Message length", HFILL }},
1118 { &hf_pnrp_message_headerack,
1119 { "ACKed Header ID", "pnrp.segment.headerAck", FT_UINT32, BASE_HEX, NULL, 0x0,
1120 NULL, HFILL }},
1121 { &hf_pnrp_message_pnrpID,
1122 { "PNRP ID", "pnrp.segment.pnrpID", FT_BYTES, BASE_NONE, NULL, 0x0,
1123 NULL, HFILL }},
1124 /* Inquire Flags */
1125 { &hf_pnrp_message_inquire_flags,
1126 { "Flags", "pnrp.segment.inquire.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1127 NULL, HFILL }},
1128 { &hf_pnrp_message_inquire_flags_reserved1,
1129 { "Reserved 1", "pnrp.segment.inquire.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED1,
1130 NULL, HFILL }},
1131 { &hf_pnrp_message_inquire_flags_Abit,
1132 { "CPA should (a)ppear in response", "pnrp.segment.inquire.flags.Abit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_A,
1133 NULL, HFILL }},
1134 { &hf_pnrp_message_inquire_flags_Xbit,
1135 { "E(X)tended Payload sent in Authority response", "pnrp.segment.inquire.flags.Xbit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_X,
1136 NULL, HFILL }},
1137 { &hf_pnrp_message_inquire_flags_Cbit,
1138 { "(C)ertificate Chain sent in Authority response", "pnrp.segment.inquire.flags.Cbit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_C,
1139 NULL, HFILL }},
1140 { &hf_pnrp_message_inquire_flags_reserved2,
1141 { "Reserved 2", "pnrp.segment.inquire.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED2,
1142 NULL, HFILL }},
1143 /* Classifier */
1144 { &hf_pnrp_message_classifier_unicodeCount,
1145 { "Number of Unicode Characters", "pnrp.segment.classifier.unicodeCount", FT_UINT16, BASE_DEC, NULL, 0x0,
1146 NULL, HFILL }},
1147 { &hf_pnrp_message_classifier_arrayLength,
1148 { "Array Length", "pnrp.segment.classifier.arrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1149 NULL, HFILL }},
1150 { &hf_pnrp_message_classifier_entryLength,
1151 { "Entry Length", "pnrp.segment.classifier.entryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1152 NULL, HFILL }},
1153 /* Ack Flags */
1154 { &hf_pnrp_message_ack_flags_reserved,
1155 { "Reserved", "pnrp.segment.ack.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1156 NULL, HFILL }},
1157 { &hf_pnrp_message_ack_flags_Nbit,
1158 { "(N)ot found Bit", "pnrp.segment.ack.flags.Nbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1159 NULL, HFILL }},
1160 /* Authority Flags */
1161 { &hf_pnrp_message_authority_flags,
1162 { "Flags", "pnrp.segment.authority.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1163 NULL, HFILL }},
1164 { &hf_pnrp_message_authority_flags_reserved1,
1165 { "Reserved 1", "pnrp.segment.authority.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED1,
1166 NULL, HFILL }},
1167 { &hf_pnrp_message_authority_flags_Lbit,
1168 { "(L)eaf Set", "pnrp.segment.authority.flags.Lbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_L,
1169 NULL, HFILL }},
1170 { &hf_pnrp_message_authority_flags_reserved2,
1171 { "Reserved 2", "pnrp.segment.authority.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED2,
1172 NULL, HFILL }},
1173 { &hf_pnrp_message_authority_flags_Bbit,
1174 { "(B)usy", "pnrp.segment.authority.flags.Bbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_B,
1175 NULL, HFILL }},
1176 { &hf_pnrp_message_authority_flags_reserved3,
1177 { "Reserved 3", "pnrp.segment.authority.flags.reserved3", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED3,
1178 NULL, HFILL }},
1179 { &hf_pnrp_message_authority_flags_Nbit,
1180 { "(N)ot found", "pnrp.segment.authority.flags.Nbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_N,
1181 NULL, HFILL }},
1182 /* Flood Control Flags */
1183 { &hf_pnrp_message_flood_flags_reserved1,
1184 { "Reserved", "pnrp.segment.flood.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1185 NULL, HFILL }},
1186 { &hf_pnrp_message_flood_flags_Dbit,
1187 { "(D)on't send ACK", "pnrp.segment.flood.flags.Dbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1188 NULL, HFILL }},
1189 /* Split Controls */
1190 { &hf_pnrp_message_splitControls_authorityBuffer,
1191 { "Authority Buffer Size:", "pnrp.segment.splitControls.authorityBuffer", FT_UINT16, BASE_DEC, NULL, 0x0,
1192 NULL, HFILL }},
1193 /* IPv6 Endpoint Array */
1194 { &hf_pnrp_message_ipv6EndpointArray_NumberOfEntries,
1195 { "Number of Entries:", "pnrp.segment.ipv6EndpointArray.NumberOfEntries", FT_UINT16, BASE_DEC, NULL, 0x0,
1196 NULL, HFILL }},
1197 { &hf_pnrp_message_ipv6EndpointArray_ArrayLength,
1198 { "Array Length:", "pnrp.segment.ipv6EndpointArray.ArrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1199 NULL, HFILL }},
1200 { &hf_pnrp_message_ipv6EndpointArray_EntryLength,
1201 { "Entry Length", "pnrp.segment.ipv6EndpointArray.EntryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1202 NULL, HFILL }},
1203 /* Encoded CPA structrue */
1204 { &hf_pnrp_encodedCPA,
1205 { "Encoded CPA structure", "pnrp.encodedCPA", FT_NONE, BASE_NONE, NULL, 0x0,
1206 NULL, HFILL }},
1207 { &hf_pnrp_encodedCPA_length,
1208 { "Length", "pnrp.encodedCPA.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1209 NULL, HFILL }},
1210 { &hf_pnrp_encodedCPA_majorVersion,
1211 { "CPA Major Version", "pnrp.encodedCPA.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1212 NULL, HFILL }},
1213 { &hf_pnrp_encodedCPA_minorVersion,
1214 { "CPA Minor Version", "pnrp.encodedCPA.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1215 NULL, HFILL }},
1216 /* Encoded CPA flags */
1217 { &hf_pnrp_encodedCPA_flags,
1218 { "Flags", "pnrp.encodedCPA.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1219 NULL, HFILL }},
1220 { &hf_pnrp_encodedCPA_flags_reserved,
1221 { "Reserved", "pnrp.encodedCPA.flags.reserved", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_RESERVED,
1222 NULL, HFILL }},
1223 { &hf_pnrp_encodedCPA_flags_Xbit,
1224 { "CPA has E(X)tended Payload", "pnrp.encodedCPA.flags.xbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_X,
1225 NULL, HFILL }},
1226 { &hf_pnrp_encodedCPA_flags_Fbit,
1227 { "CPA contains (F)riendly Name", "pnrp.encodedCPA.flags.fbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_F,
1228 NULL, HFILL }},
1229 { &hf_pnrp_encodedCPA_flags_Cbit,
1230 { "CPA contains (C)lassifier Hash", "pnrp.encodedCPA.flags.cbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_C,
1231 NULL, HFILL }},
1232 { &hf_pnrp_encodedCPA_flags_Abit,
1233 { "CPA contains Binary (A)uthority field", "pnrp.encodedCPA.flags.abit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_A,
1234 NULL, HFILL }},
1235 { &hf_pnrp_encodedCPA_flags_Ubit,
1236 { "Friendly Name in (U)TF-8", "pnrp.encodedCPA.flags.ubit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_U,
1237 NULL, HFILL }},
1238 { &hf_pnrp_encodedCPA_flags_Rbit,
1239 { "This is a (r)evoke CPA", "pnrp.encodedCPA.flags.rbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_R,
1240 NULL, HFILL }},
1241 /* TODO: Find correct way to Display Time */
1242 { &hf_pnrp_encodedCPA_notAfter,
1243 { "CPA expiration Date", "pnrp.encodedCPA.expirationDate", FT_UINT64,BASE_DEC, NULL, 0x0,
1244 "CPA expiration Date since January 1, 1601 UTC", HFILL }},
1245 { &hf_pnrp_encodedCPA_serviceLocation,
1246 { "Service Location", "pnrp.encodedCPA.serviceLocation", FT_BYTES,BASE_NONE, NULL, 0x0,
1247 NULL, HFILL }},
1248 { &hf_pnrp_encodedCPA_binaryAuthority,
1249 { "Binary Authority", "pnrp.encodedCPA.binaryAuthority", FT_BYTES,BASE_NONE, NULL, 0x0,
1250 "SHA-1 Hash of PublicKey Data field", HFILL }},
1251 { &hf_pnrp_encodedCPA_classifiertHash,
1252 { "Classifiert Hash", "pnrp.encodedCPA.classifierHash", FT_BYTES,BASE_NONE, NULL, 0x0,
1253 "SHA-1 Hash of the classifier text", HFILL }},
1254 { &hf_pnrp_encodedCPA_friendlyName,
1255 { "Friendly Name of PNRP ID", "pnrp.encodedCPA.friendlyName", FT_STRING,BASE_NONE, NULL, 0x0,
1256 "A human-readable label identifying the PNRP ID", HFILL }},
1257 /* Lookup Controls */
1258 { &hf_pnrp_message_lookupControls_flags,
1259 { "Flags", "pnrp.lookupControls.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1260 NULL, HFILL }},
1261 { &hf_pnrp_message_lookupControls_flags_reserved,
1262 { "Reserved", "pnrp.lookupControls.flags.reserved", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_RESERVED,
1263 NULL, HFILL }},
1264 { &hf_pnrp_message_lookupControls_flags_Abit,
1265 { "A bit:", "pnrp.lookupControls.flags.Abit", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_A,
1266 "Sender is willing to accept returned nodes that are not closer to the target ID than the Validate PNRP ID", HFILL }},
1267 { &hf_pnrp_message_lookupControls_flags_0bit,
1268 { "0 bit - reserved:", "pnrp.lookupControls.flags.0bit", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_0,
1269 NULL, HFILL }},
1270 { &hf_pnrp_message_lookupControls_precision,
1271 { "Precision", "pnrp.lookupControls.precision", FT_UINT16, BASE_HEX, NULL, 0x0,
1272 "Precision - Number of significant bits to match", HFILL }},
1273 { &hf_pnrp_message_lookupControls_resolveCriteria,
1274 { "Resolve Criteria", "pnrp.lookupControls.resolveCriteria", FT_UINT8, BASE_HEX, VALS(resolveCriteria), 0x0,
1275 NULL, HFILL }},
1276 { &hf_pnrp_message_lookupControls_reasonCode,
1277 { "Reason Code", "pnrp.lookupControls.reasonCode", FT_UINT8, BASE_HEX, VALS(reasonCode), 0x0,
1278 NULL, HFILL }},
1279 /* Public Key Structure */
1280 { &hf_pnrp_publicKey_objID,
1281 { "Public Key Object Identifier", "pnrp.publicKey.objID", FT_STRING,BASE_NONE, NULL, 0x0,
1282 "An ASN.1-encoded object identifier (OID) indicating the public key format", HFILL }},
1283 { &hf_pnrp_publicKey_publicKeyData,
1284 { "Public Key Data", "pnrp.publicKey.publicKeyData", FT_STRING,BASE_NONE, NULL, 0x0,
1285 "An ASN.1-encoded 1024-bit RSA public key", HFILL }},
1286 /* Signature Structure */
1287 { &hf_pnrp_signature_signatureData,
1288 { "Signature", "pnrp.signature.data", FT_BYTES,BASE_NONE, NULL, 0x0,
1289 "Signature created when signing the CPA", HFILL }},
1291 /* Route Entry */
1292 { &hf_pnrp_message_routeEntry_portNumber,
1293 { "Port Number", "pnrp.segment.routeEntry.portNumber", FT_UINT16, BASE_DEC, NULL, 0x0,
1294 NULL, HFILL }},
1295 { &hf_pnrp_message_routeEntry_flags,
1296 { "Flags", "pnrp.segment.routeEntry.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
1297 NULL, HFILL }},
1298 { &hf_pnrp_message_routeEntry_addressCount,
1299 { "Address Count", "pnrp.segment.routeEntry.addressCount", FT_UINT8, BASE_DEC, NULL, 0x0,
1300 NULL, HFILL }},
1301 { &hf_pnrp_message_nonce,
1302 { "Nonce", "pnrp.segment.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1303 NULL, HFILL }},
1304 { &hf_pnrp_message_hashednonce,
1305 { "Hashed Nonce", "pnrp.segment.hashednonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1306 NULL, HFILL }},
1307 { &hf_pnrp_message_idArray_NumEntries,
1308 { "Number of Entries", "pnrp.segment.idArray.NumEnries", FT_UINT16, BASE_DEC, NULL, 0x0,
1309 NULL, HFILL }},
1310 { &hf_pnrp_message_idArray_Length,
1311 { "Length of Array", "pnrp.segment.idArray.Length", FT_UINT16, BASE_DEC, NULL, 0x0,
1312 NULL, HFILL }},
1313 { &hf_pnrp_message_ElementFieldType,
1314 { "Type of Array Entry", "pnrp.segment.ElementFieldType", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1315 NULL, HFILL }},
1316 { &hf_pnrp_message_idarray_Entrylength,
1317 { "Length of each Array Entry", "pnrp.segment.idArray.Entrylength", FT_UINT16, BASE_DEC, NULL, 0x0,
1318 NULL, HFILL }},
1319 { &hf_pnrp_message_certChain,
1320 { "Certificate Chain", "pnrp.segment.certChain", FT_BYTES,BASE_NONE, NULL, 0x0,
1321 "A Certificate Chain, containing the public key used to sign the CPA and its Certificate Chain", HFILL }},
1322 { &hf_pnrp_message_solicitType,
1323 { "Solicit Type", "pnrp.segment.solicitType", FT_UINT8, BASE_DEC, VALS(solicitType), 0x0,
1324 NULL, HFILL }},
1325 { &hf_pnrp_message_ipv6,
1326 { "IPv6 Address","pnrp.segment.ipv6Address",FT_IPv6, BASE_NONE, NULL, 0x0,NULL,HFILL}}
1329 /* Protocol subtree array */
1330 static gint *ett[] = {
1331 &ett_pnrp,
1332 &ett_pnrp_header,
1333 &ett_pnrp_message,
1334 &ett_pnrp_message_inquire_flags,
1335 &ett_pnrp_message_authority_flags,
1336 &ett_pnrp_message_encodedCPA,
1337 &ett_pnrp_message_encodedCPA_flags,
1338 &ett_pnrp_message_payloadStructure,
1339 &ett_pnrp_message_publicKeyStructure,
1340 &ett_pnrp_message_signatureStructure,
1341 &ett_pnrp_message_lookupControls_flags
1343 /* Register the Dissector with Wireshark */
1344 proto_pnrp = proto_register_protocol(PROTONAME,PROTOSHORTNAME,PROTOABBREV);
1346 proto_register_field_array(proto_pnrp,hf,array_length(hf));
1347 proto_register_subtree_array (ett, array_length(ett));
1350 /* Initialise the dissector */
1351 void proto_reg_handoff_pnrp(void)
1353 dissector_handle_t pnrp_handle;
1354 pnrp_handle = new_create_dissector_handle(dissect_pnrp, proto_pnrp);
1355 dissector_add_uint("udp.port",PNRP_PORT,pnrp_handle);