Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-pnrp.c
Line
Count
Source
1
/* packet-pnrp.c
2
 * Routines for Peer Name Resolution Protocol (PNRP) dissection
3
 *
4
 *  Copyright 2010, Jan Gerbecks <jan.gerbecks@stud.uni-due.de>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/* The official Documentation for the Peer Name Resolution Protocol
14
 * ([MS-PNRP]) can be found at
15
 *
16
 *    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pnrp
17
 *
18
 * This dissector is based on Revision 6.1.2
19
 */
20
21
#include "config.h"
22
23
#include <epan/packet.h>
24
#include <epan/exceptions.h>
25
#include <epan/reassemble.h>
26
27
15
#define PROTONAME "Peer Name Resolution Protocol"
28
15
#define PROTOSHORTNAME "PNRP"
29
30
#define PROTOABBREV "pnrp"
30
31
15
#define PNRP_PORT 3540
32
33
#define FIELDID_LENGTH = 2
34
#define LENGTH_FIELD = 2
35
36
/* Define all FieldIDs here, so we can use them later on in switch statement etc */
37
4
#define PNRP_HEADER         0x0010
38
0
#define PNRP_HEADER_ACKED   0x0018
39
#define PNRP_ID             0x0030
40
0
#define TARGET_PNRP_ID      0x0038
41
0
#define VALIDATE_PNRP_ID    0x0039
42
0
#define FLAGS_FIELD         0x0040
43
0
#define FLOOD_CONTROLS      0x0043
44
0
#define SOLICIT_CONTROLS    0x0044
45
0
#define LOOKUP_CONTROLS     0x0045
46
0
#define EXTENDED_PAYLOAD    0x005A
47
0
#define PNRP_ID_ARRAY       0x0060
48
0
#define CERT_CHAIN          0x0080
49
#define WCHAR               0x0084
50
0
#define CLASSIFIER          0x0085
51
0
#define HASHED_NONCE        0x0092
52
0
#define NONCE               0x0093
53
0
#define SPLIT_CONTROLS      0x0098
54
0
#define ROUTING_ENTRY       0x009A
55
0
#define VALIDATE_CPA        0x009B
56
#define REVOKE_CPA          0x009C
57
#define IPV6_ENDPOINT       0x009D
58
0
#define IPV6_ENDPOINT_ARRAY 0x009E
59
60
/* Define all message types */
61
#define SOLICIT             0x01
62
#define ADVERTISE           0x02
63
#define REQUEST             0x03
64
#define FLOOD               0x04
65
0
#define INQUIRE             0x07
66
0
#define AUTHORITY           0x08
67
0
#define ACK                 0x09
68
#define LOOKUP              0x0B
69
70
/* Define flags mask fields */
71
15
#define FLAGS_INQUIRE_RESERVED1       0xFFE0
72
15
#define FLAGS_INQUIRE_A               0x0010
73
15
#define FLAGS_INQUIRE_X               0x0008
74
15
#define FLAGS_INQUIRE_C               0x0004
75
15
#define FLAGS_INQUIRE_RESERVED2       0x0003
76
77
15
#define FLAGS_AUTHORITY_RESERVED1     0xFC00
78
15
#define FLAGS_AUTHORITY_L             0x0200
79
15
#define FLAGS_AUTHORITY_RESERVED2     0x01F0
80
15
#define FLAGS_AUTHORITY_B             0x0008
81
15
#define FLAGS_AUTHORITY_RESERVED3     0x0006
82
15
#define FLAGS_AUTHORITY_N             0x0001
83
84
15
#define FLAGS_LOOKUPCONTROLS_RESERVED 0xFFFC
85
15
#define FLAGS_LOOKUPCONTROLS_A        0x0002
86
15
#define FLAGS_LOOKUPCONTROLS_0        0x0001
87
88
15
#define FLAGS_ENCODED_CPA_RESERVED    0xC0
89
15
#define FLAGS_ENCODED_CPA_X           0x20
90
15
#define FLAGS_ENCODED_CPA_U           0x02
91
15
#define FLAGS_ENCODED_CPA_R           0x01
92
15
#define FLAGS_ENCODED_CPA_A           0x04
93
15
#define FLAGS_ENCODED_CPA_C           0x08
94
15
#define FLAGS_ENCODED_CPA_F           0x10
95
96
void proto_register_pnrp(void);
97
void proto_reg_handoff_pnrp(void);
98
99
static dissector_handle_t pnrp_handle;
100
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);
110
111
/* Define global variables
112
 ----------------------------*/
113
static int proto_pnrp;
114
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}
140
};
141
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}
153
};
154
/* Define Solicit Type */
155
static const value_string solicitType[] = {
156
    { 0x00,                "SOLICIT_TYPE_ANY" },
157
    { 0x01,                "SOLICIT_TYPE_LOCAL" },
158
    {0,                     NULL}
159
};
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}
168
};
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}
176
};
177
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;
200
201
static int hf_pnrp_padding;
202
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
210
};
211
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;
234
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
243
};
244
245
/* Flood Control Flags */
246
static int hf_pnrp_message_flood_flags_reserved1;
247
static int hf_pnrp_message_flood_flags_Dbit;
248
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;
254
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;
260
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
283
};
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;
289
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
300
};
301
static int hf_pnrp_message_lookupControls_precision;
302
static int hf_pnrp_message_lookupControls_resolveCriteria;
303
static int hf_pnrp_message_lookupControls_reasonCode;
304
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;
309
310
/* Public Key Structure */
311
static int hf_pnrp_publicKey_objID;
312
static int hf_pnrp_publicKey_publicKeyData;
313
314
/* Signature Structure */
315
static int hf_pnrp_signature_signatureData;
316
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;
341
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;
355
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;
370
371
static reassembly_table pnrp_reassembly_table;
372
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"
388
};
389
390
/* Do actual dissection work */
391
static int dissect_pnrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
392
5
{
393
    /* Variable declaration */
394
5
    int offset, start_offset;
395
5
    int padding_bytes;
396
5
    uint8_t message_type;
397
5
    char* str_message_type;
398
5
    uint16_t field_type;
399
5
    unsigned data_length;
400
5
    proto_item *ti;
401
5
    proto_tree *pnrp_tree;
402
5
    proto_item *pnrp_header_item;
403
5
    proto_tree *pnrp_header_tree;
404
5
    proto_item *pnrp_message_tree = NULL;
405
5
    uint32_t msg_id;
406
407
    /*----------------------------------------
408
     * Validate if it is really a PNRP Packet
409
     *----------------------------------------*/
410
    /* Check that there's enough data */
411
5
    data_length = tvb_captured_length(tvb);
412
413
    /* Shortest Message is ACK -> 12 Bytes for Header plus 8 Bytes for Data */
414
5
    if (data_length <  12+8 )
415
1
    {
416
1
        return 0;
417
1
    }
418
419
    /* Check some values from the packet header */
420
    /* First 2 bytes must be 0x0010 */
421
4
    if (tvb_get_ntohs(tvb,0) != PNRP_HEADER )
422
4
    {
423
4
        return 0;
424
4
    }
425
    /* Length of Header must be 0x000C = 12 */
426
0
    if (tvb_get_ntohs(tvb,2) != 0x000C) {
427
0
        return 0;
428
0
    }
429
    /* Identifier must 0x51 */
430
0
    if (tvb_get_uint8(tvb,4) != 0x51) {
431
0
        return 0;
432
0
    }
433
434
435
    /* Assign Values to Variables */
436
    /* Use to track data */
437
0
    offset= 0;
438
    /* Get the message Information beforehand */
439
0
    message_type = tvb_get_uint8(tvb,7);
440
0
    str_message_type = val_to_str(pinfo->pool, message_type, messageType, "Unknown (0x%02x)");
441
442
443
    /* Simply Display the Protocol Name in the INFO column */
444
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNRP");
445
    /* Clear out stuff in the info column */
446
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "PNRP %s Message ", str_message_type);
447
448
449
    /* Lets add a subtree to our dissection to display the info */
450
0
    ti = proto_tree_add_item(tree, proto_pnrp, tvb, 0, -1, ENC_NA);
451
0
    proto_item_append_text(ti, ", Message Type %s", str_message_type);
452
    /* Get a main tree for the whole protocol */
453
0
    pnrp_tree = proto_item_add_subtree(ti, ett_pnrp);
454
455
    /*-------------------------------
456
     *--Add all Header Fields
457
     *------------------------------*/
458
    /* Get a subtree for the Header */
459
0
    pnrp_header_item = proto_tree_add_item(pnrp_tree, hf_pnrp_header, tvb, offset,12,ENC_NA);
460
0
    pnrp_header_tree = proto_item_add_subtree(pnrp_header_item, ett_pnrp_header);
461
462
    /* Add Field ID should be 0c0010 */
463
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_fieldID,tvb,offset,2,ENC_BIG_ENDIAN);
464
0
    offset += 2;
465
    /* Add Length should be 0x000C */
466
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_length,tvb,offset,2,ENC_BIG_ENDIAN);
467
0
    offset += 2;
468
    /* Add Ident should be 0x51 */
469
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_ident,tvb,offset,1,ENC_BIG_ENDIAN);
470
0
    offset += 1;
471
    /* Add Major Version */
472
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMajor,tvb,offset,1,ENC_BIG_ENDIAN);
473
0
    offset += 1;
474
    /* Add Minor Version */
475
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_versionMinor,tvb,offset,1,ENC_BIG_ENDIAN);
476
0
    offset += 1;
477
    /* Add Message Type */
478
0
    proto_tree_add_item(pnrp_header_tree,hf_pnrp_header_messageType,tvb,offset,1,ENC_BIG_ENDIAN);
479
0
    offset += 1;
480
    /* Add Message ID */
481
0
    proto_tree_add_item_ret_uint(pnrp_header_tree,hf_pnrp_header_messageID,tvb,offset,4,ENC_BIG_ENDIAN,&msg_id);
482
0
    offset += 4;
483
484
485
    /*-------------------------------
486
     *--Add all Message Fields
487
     *------------------------------*/
488
489
    /* The following part has dynamic length depending on message type */
490
0
    start_offset = offset;
491
0
    while (tvb_reported_length_remaining(tvb, offset) > 0) {
492
        /* Determine the Field Type */
493
0
        field_type = tvb_get_ntohs(tvb,offset );
494
        /* Determine length of this message */
495
0
        data_length = tvb_get_ntohs(tvb,offset + 2);
496
497
        /* Length must be at least 4, because field_type and data_length are part of data_length information */
498
0
        if (data_length < 4) {
499
0
            pnrp_message_tree = proto_tree_add_subtree_format(pnrp_tree, tvb, offset, 4, ett_pnrp_message, NULL,
500
0
                                "Message with invalid length %u (< 4)", data_length);
501
0
            proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
502
0
            proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
503
0
            offset += 4;
504
            /* Don't continue parsing this message segment */
505
0
            break;
506
0
        }
507
        /* Actual Parsing of the message Type */
508
0
        switch (field_type) {
509
            /* First Field in ACK Message */
510
0
            case PNRP_HEADER_ACKED:
511
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
512
0
                                data_length, ett_pnrp_message, NULL, "Message ACK ID: ");
513
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
514
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
515
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_headerack, tvb, offset + 4, data_length -4, ENC_BIG_ENDIAN);
516
517
0
                offset += data_length;
518
0
                break;
519
520
                /* A validate pnrp id follows as found in FLOOD */
521
0
            case VALIDATE_PNRP_ID:
522
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
523
0
                                                        data_length, ett_pnrp_message, NULL, "Validate PNRP ID: ");
524
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
525
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
526
                /* We can have a large number of pnrp IDs here */
527
0
                dissect_pnrp_ids(tvb,offset+4,data_length-4,pnrp_message_tree);
528
529
0
                offset += data_length;
530
0
                break;
531
532
                /* The Flags have different meaning, depending on the message */
533
0
            case FLAGS_FIELD:
534
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
535
0
                                                        data_length, ett_pnrp_message, NULL, "Flags Field: ");
536
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
537
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
538
0
                switch (message_type) {
539
0
                    case INQUIRE:
540
0
                        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);
541
0
                        proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + 6, 2, ENC_NA);
542
0
                        offset += data_length+2;
543
544
0
                        break;
545
546
0
                    case ACK:
547
                        /* Reserved 0 - 14 bits */
548
0
                        proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_ack_flags_reserved, tvb, (offset + 4)*8, 15, ENC_BIG_ENDIAN);
549
                        /* N - Bit */
550
0
                        proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_ack_flags_Nbit, tvb,((offset + 4)*8)+15, 1, ENC_BIG_ENDIAN);
551
0
                        offset += data_length;
552
0
                        break;
553
0
                    case AUTHORITY:
554
0
                        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);
555
                        /* Check if the Flags Field is the last message part. If so, no padding of 2 bytes is added */
556
0
                        if(tvb_reported_length_remaining(tvb, offset+data_length)==0)
557
0
                        {
558
0
                            offset += data_length;
559
0
                        }
560
0
                        else {
561
0
                            padding_bytes = 2;
562
0
                            proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + 6, padding_bytes, ENC_NA);
563
0
                            offset += data_length+2;
564
0
                        }
565
0
                        break;
566
567
0
                    default:
568
0
                        proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_flags, tvb, offset + 4, data_length -4, ENC_BIG_ENDIAN);
569
0
                        offset += data_length;
570
0
                        break;
571
0
                }
572
0
                break;
573
574
                /* Flood controls found in FLOOD Message */
575
0
            case FLOOD_CONTROLS:
576
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
577
0
                                                        data_length, ett_pnrp_message, NULL, "Flood Control: ");
578
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
579
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
580
                /* Reserved 1 - 15 bits */
581
0
                proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_flood_flags_reserved1, tvb, (offset + 4)*8, 15, ENC_BIG_ENDIAN);
582
                /* D - Bit */
583
0
                proto_tree_add_bits_item(pnrp_message_tree, hf_pnrp_message_flood_flags_Dbit, tvb,((offset + 4)*8)+15, 1, ENC_BIG_ENDIAN);
584
                /* Reserved 2 */
585
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved8, tvb, offset + 6, 1, ENC_NA);
586
                /* Padding 1 */
587
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + 7, 1, ENC_NA);
588
589
0
                offset += data_length+1;
590
0
                break;
591
592
                /* Solicit Controls found in SOLICIT Message */
593
0
            case SOLICIT_CONTROLS:
594
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
595
0
                                                        data_length, ett_pnrp_message, NULL, "Solicit Controls: ");
596
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
597
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
598
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved8, tvb, offset + 4, 1, ENC_NA);
599
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_solicitType, tvb, offset + 5, 1, ENC_BIG_ENDIAN);
600
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved16, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN);
601
0
                offset += data_length +2;   /* Padding involved */
602
0
                break;
603
                /* Lookup controls found in LOOKUP Message */
604
0
            case LOOKUP_CONTROLS:
605
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
606
0
                                                        data_length, ett_pnrp_message, NULL, "Lookup Control: ");
607
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
608
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
609
                /* 2 Bytes of Flags */
610
0
                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);
611
                /* Precision Bytes */
612
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_precision, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
613
                /* Resolve Criteria */
614
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_resolveCriteria, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
615
                /* Reason Code */
616
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_lookupControls_reasonCode, tvb, offset + 9, 1, ENC_BIG_ENDIAN);
617
                /* Reserved */
618
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_reserved16, tvb, offset + 10, 2, ENC_LITTLE_ENDIAN);
619
620
0
                offset += data_length;
621
0
                break;
622
                /* Target PNRP ID found in Lookup Message */
623
0
            case TARGET_PNRP_ID:
624
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
625
0
                                                        data_length, ett_pnrp_message, NULL, "Target PNRP ID: ");
626
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
627
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
628
0
                dissect_pnrp_ids(tvb, offset+4, data_length-4, pnrp_message_tree);
629
630
0
                offset += data_length;
631
0
                break;
632
633
                /* Extended Payload found in AUTHORITY Message */
634
0
            case EXTENDED_PAYLOAD:
635
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
636
0
                                                        data_length, ett_pnrp_message, NULL, "Extended Payload: ");
637
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
638
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
639
                /* TODO: Do actual parsing */
640
641
0
                offset += data_length;
642
0
                break;
643
                /* Pnrp id Array as found in REQUEST & ADVERTISE Message */
644
0
            case PNRP_ID_ARRAY:
645
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
646
0
                                                        data_length, ett_pnrp_message, NULL, "PNRP ID Array: ");
647
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
648
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
649
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idArray_NumEntries, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
650
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idArray_Length, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
651
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ElementFieldType, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
652
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_idarray_Entrylength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
653
0
                dissect_pnrp_ids(tvb,offset+12,data_length-12,pnrp_message_tree);
654
655
0
                offset += data_length;
656
0
                break;
657
                /* Cert Chain follows as found in AUTHORITY */
658
0
            case CERT_CHAIN:
659
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
660
0
                                                        data_length, ett_pnrp_message, NULL, "CERT Chain: ");
661
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
662
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
663
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_certChain, tvb, offset + 4, data_length-4, ENC_NA);
664
665
                /* There might be padding, so fill up to the next byte */
666
0
                padding_bytes = 0;
667
0
                while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
668
0
                    data_length++;
669
0
                    padding_bytes++;
670
0
                }
671
                /* Check if we actually had some padding bytes */
672
0
                if (0<padding_bytes) {
673
0
                    proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + data_length-padding_bytes, padding_bytes, ENC_NA);
674
0
                }
675
0
                offset += data_length;
676
0
                break;
677
                /* classifier: A classifier string follows as found in AUTHORITY */
678
0
            case CLASSIFIER:
679
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
680
0
                                                        data_length, ett_pnrp_message, NULL, "Classifier: ");
681
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
682
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
683
                /* NumEntries */
684
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_unicodeCount, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
685
                /* Array Length: 8+(NumEntries*EntryLength */
686
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_arrayLength, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
687
                /* Element Field Type: WCHAR */
688
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset+8 , 2, ENC_BIG_ENDIAN);
689
                /* Entry Length: Must be 0x0002 */
690
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_classifier_entryLength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
691
                /* The actual classifier String */
692
0
                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);
693
694
                /* There might be padding, so fill up to the next byte */
695
0
                padding_bytes = 0;
696
0
                while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
697
0
                    data_length++;
698
0
                    padding_bytes++;
699
0
                }
700
                /* Check if we actually had some padding bytes */
701
0
                if (0<padding_bytes) {
702
0
                    proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + data_length-padding_bytes, padding_bytes, ENC_NA);
703
0
                }
704
0
                offset += data_length;
705
0
                break;
706
                /* A hashed nonce follows as found in ADVERTISE & SOLICIT */
707
0
            case HASHED_NONCE:
708
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
709
0
                                                        data_length, ett_pnrp_message, NULL, "Hashed Nonce: ");
710
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
711
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
712
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_hashednonce, tvb, offset + 4, data_length-4, ENC_NA);
713
714
0
                offset += data_length;
715
0
                break;
716
717
                /* A nonce follows as found in REQUEST & INQUIRE */
718
0
            case NONCE:
719
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
720
0
                                                        data_length, ett_pnrp_message, NULL, "Nonce: ");
721
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
722
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
723
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_nonce, tvb, offset + 4, data_length-4, ENC_NA);
724
725
0
                offset += data_length;
726
0
                break;
727
728
                /* split controls as found in AUTHORITY */
729
0
            case SPLIT_CONTROLS:
730
0
            {
731
0
                fragment_head *frag_data;
732
0
                tvbuff_t *frag_tvb;
733
0
                uint32_t buffer_len, frag_offset, remaining_len;
734
735
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
736
0
                                                        data_length, ett_pnrp_message, NULL, "Split controls: ");
737
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
738
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
739
                /* Size of Authority Buffer */
740
0
                proto_tree_add_item_ret_uint(pnrp_message_tree, hf_pnrp_message_splitControls_authorityBuffer,
741
0
                                             tvb, offset + 4, 2, ENC_BIG_ENDIAN, &buffer_len);
742
                /* Byte offset */
743
0
                proto_tree_add_item_ret_uint(pnrp_message_tree, hf_pnrp_message_offset,
744
0
                                             tvb, offset + 6, 2, ENC_BIG_ENDIAN, &frag_offset);
745
0
                offset += data_length;
746
0
                remaining_len = tvb_reported_length_remaining(tvb, offset);
747
748
0
                frag_data = fragment_add_check(&pnrp_reassembly_table, tvb, offset, pinfo,
749
0
                                               msg_id, NULL, frag_offset, remaining_len,
750
0
                                               (buffer_len != (frag_offset + remaining_len)));
751
0
                frag_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled PNRP message",
752
0
                                                    frag_data, &pnrp_frag_items, NULL, pnrp_message_tree);
753
0
                if (frag_tvb) {
754
0
                    tvb = frag_tvb;
755
0
                    offset = 0;
756
0
                } else {
757
0
                    proto_tree_add_item(pnrp_message_tree, hf_pnrp_fragmented_payload, tvb, offset, -1, ENC_NA);
758
0
                    col_append_str(pinfo->cinfo, COL_INFO, " [Fragmented message]");
759
0
                    return tvb_captured_length(tvb);
760
0
                }
761
0
                break;
762
0
            }
763
764
                /* routing entry: A route entry follows as found in ADVERTISE, INQUIRE, LOOKUP & AUTHORITY */
765
0
            case ROUTING_ENTRY:
766
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
767
0
                                                        data_length, ett_pnrp_message, NULL, "Routing Entry: ");
768
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
769
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
770
0
                dissect_route_entry(tvb,offset+4, tvb_get_ntohs(tvb,offset+2)-4, pnrp_message_tree);
771
772
                /* There might be padding, so fill up to the next byte */
773
0
                padding_bytes = 0;
774
0
                while (data_length%4 != 0 &&tvb_reported_length_remaining(tvb, offset+data_length)>0) {
775
0
                    data_length++;
776
0
                    padding_bytes++;
777
0
                }
778
                /* Check if we actually had some padding bytes */
779
0
                if (0<padding_bytes) {
780
0
                    proto_tree_add_item(pnrp_message_tree, hf_pnrp_padding, tvb, offset + data_length-padding_bytes, padding_bytes, ENC_NA);
781
0
                }
782
0
                offset += data_length;
783
0
                break;
784
785
                /* validate cpa: an encoded CPA structure follows as found in AUTHORITY */
786
0
            case VALIDATE_CPA:
787
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
788
0
                                                        data_length, ett_pnrp_message, NULL, "Validate CPA: ");
789
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
790
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
791
                /* Do the actual parsing in own method */
792
0
                dissect_encodedCPA_structure(tvb, offset+4, data_length-4, pnrp_message_tree);
793
794
0
                offset += data_length;
795
0
                break;
796
797
798
                /* IPV6 Endpoint: an ipv6 endpoint array structure follows as found in LOOKUP */
799
0
            case IPV6_ENDPOINT_ARRAY:
800
0
                pnrp_message_tree = proto_tree_add_subtree(pnrp_tree, tvb, offset,
801
0
                                                        data_length, ett_pnrp_message, NULL, "IPv6 Endpoint Array: ");
802
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
803
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
804
                /* Number of route entries */
805
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_NumberOfEntries, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
806
                /* Array length */
807
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_ArrayLength, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
808
                /* Element Field Type */
809
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset+8 , 2, ENC_BIG_ENDIAN);
810
                /* Entry Length: must be 0x0012 (18 bytes) */
811
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_ipv6EndpointArray_EntryLength, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
812
                /* Flagged Path */
813
0
                dissect_ipv6_endpoint_structure(tvb, offset+12, tvb_get_ntohs(tvb,offset+6)-8,pnrp_message_tree);
814
815
0
                offset += data_length;
816
0
                break;
817
818
0
            default:
819
0
                pnrp_message_tree = proto_tree_add_subtree_format(pnrp_tree, tvb, offset,
820
0
                                                        data_length, ett_pnrp_message, NULL, "Type: %s, length: %u",
821
0
                                                        val_to_str(pinfo->pool, field_type, fieldID, "Unknown (0x%04x)"), data_length);
822
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_type, tvb, offset , 2, ENC_BIG_ENDIAN);
823
0
                proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
824
0
                if(data_length > 4)
825
0
                {
826
0
                    proto_tree_add_item(pnrp_message_tree, hf_pnrp_message_data, tvb, offset + 4, data_length -4, ENC_NA);
827
0
                }
828
0
                else {
829
0
                    return 0;
830
0
                }
831
0
                offset += data_length;
832
0
                break;
833
0
        }
834
        // SPLIT_CONTROLS might reset our offset.
835
0
        if (start_offset <= offset) {
836
0
            THROW(ReportedBoundsError);
837
0
        }
838
0
    }
839
0
    return offset;
840
841
0
}
842
843
/*--------------------------------------------------------------*
844
 * Dissecting helper methods                                    *
845
 *--------------------------------------------------------------*/
846
847
static void dissect_pnrp_ids(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
848
0
{
849
0
    while (32 <=length) {
850
0
        proto_tree_add_item(tree, hf_pnrp_message_pnrpID, tvb, offset, 32, ENC_NA);
851
0
        length -= 32;
852
0
        offset += 32;
853
0
    }
854
855
0
}
856
857
static void dissect_route_entry(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
858
0
{
859
0
    int tmp_offset;
860
0
    tmp_offset = 0;
861
    /* First, we have a 32 Bit long PNRP ID */
862
0
    proto_tree_add_item(tree, hf_pnrp_message_pnrpID, tvb, offset+tmp_offset, 32, ENC_NA);
863
0
    tmp_offset +=32;
864
    /* Add PNRP Major Version */
865
0
    proto_tree_add_item(tree,hf_pnrp_header_versionMajor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
866
0
    tmp_offset += 1;
867
    /* Add Minor Version */
868
0
    proto_tree_add_item(tree,hf_pnrp_header_versionMinor,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
869
0
    tmp_offset +=1;
870
    /* Port Number */
871
0
    proto_tree_add_item(tree,hf_pnrp_message_routeEntry_portNumber,tvb,offset+tmp_offset,2,ENC_BIG_ENDIAN);
872
0
    tmp_offset +=2;
873
    /* Flags */
874
0
    proto_tree_add_item(tree,hf_pnrp_message_routeEntry_flags,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
875
0
    tmp_offset +=1;
876
    /* Address count */
877
0
    proto_tree_add_item(tree,hf_pnrp_message_routeEntry_addressCount,tvb,offset+tmp_offset,1,ENC_BIG_ENDIAN);
878
0
    tmp_offset +=1;
879
    /* IPv6 Addresses */
880
0
    dissect_ipv6_address(tvb, offset+tmp_offset, length -tmp_offset, tree);
881
0
}
882
883
static void dissect_ipv6_endpoint_structure(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
884
0
{
885
    /* Check if we don't run out of data */
886
0
    while (18 <= length) {
887
        /* Port Number */
888
0
        proto_tree_add_item(tree, hf_pnrp_message_port_number, tvb, offset, 2, ENC_BIG_ENDIAN);
889
        /* IPv6 Addresses */
890
0
        dissect_ipv6_address(tvb, offset+2,16,tree);
891
0
        offset += 18;
892
0
        length -= 18;
893
0
    }
894
0
}
895
896
static void dissect_ipv6_address(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
897
0
{
898
0
    while (16 <= length) {
899
0
        proto_tree_add_item(tree, hf_pnrp_message_ipv6, tvb, offset, 16, ENC_NA);
900
0
        offset += 16;
901
0
        length -= 16;
902
0
    }
903
0
}
904
905
static void dissect_encodedCPA_structure(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
906
0
{
907
0
    uint8_t flagsField;
908
    /* Add a new subtree */
909
0
    proto_item *pnrp_encodedCPA_tree = NULL;
910
0
    proto_item *pnrp_encodedCPA_item = NULL;
911
0
    pnrp_encodedCPA_item = proto_tree_add_item(tree, hf_pnrp_encodedCPA, tvb, offset,length,ENC_NA);
912
0
    pnrp_encodedCPA_tree = proto_item_add_subtree(pnrp_encodedCPA_item, ett_pnrp_message_encodedCPA);
913
914
    /* Length information */
915
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_length, tvb, offset, 2, ENC_BIG_ENDIAN);
916
    /* CPA Minor Version */
917
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_minorVersion, tvb, offset+2, 1, ENC_BIG_ENDIAN);
918
    /* CPA Major Version */
919
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_majorVersion, tvb, offset+3, 1, ENC_BIG_ENDIAN);
920
    /* PNRP Minor Version */
921
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_header_versionMinor, tvb, offset+4, 1, ENC_BIG_ENDIAN);
922
    /* PNRP Major Version */
923
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_header_versionMajor, tvb, offset+5, 1, ENC_BIG_ENDIAN);
924
    /* Flags Field */
925
0
    proto_tree_add_bitmask(pnrp_encodedCPA_tree, tvb, offset+6, hf_pnrp_encodedCPA_flags, ett_pnrp_message_encodedCPA_flags, encodedCPA_flags, ENC_BIG_ENDIAN);
926
0
    flagsField = tvb_get_uint8(tvb,offset+6);
927
    /* Reserved */
928
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_reserved8, tvb, offset + 7, 1, ENC_NA);
929
    /* Not After */
930
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_notAfter, tvb, offset+8, 8, ENC_BIG_ENDIAN);
931
    /* Service Location */
932
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_serviceLocation, tvb, offset+16, 16, ENC_NA);
933
934
    /* now, the structure is variable, so add bytes to offset */
935
0
    offset +=32;
936
937
    /* Check if R Flag is set */
938
0
    if ((flagsField & FLAGS_ENCODED_CPA_R)==0x00) {
939
        /* Nonce follows */
940
0
        proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_message_nonce, tvb, offset, 16, ENC_NA);
941
0
        offset +=16;
942
0
    }
943
    /* Check if A Flag is set */
944
0
    if (flagsField & FLAGS_ENCODED_CPA_A) {
945
        /* Binary authority */
946
0
        proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_binaryAuthority, tvb, offset, 20, ENC_NA);
947
0
        offset +=20;
948
0
    }
949
    /* Check if C Flag is set */
950
0
    if (flagsField & FLAGS_ENCODED_CPA_C) {
951
        /* Classifier Hash */
952
0
        proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_classifierHash, tvb, offset, 20, ENC_NA);
953
0
        offset +=20;
954
0
    }
955
    /* Check if F Flag is set */
956
0
    if (flagsField & FLAGS_ENCODED_CPA_F) {
957
        /* Friendly Name Length */
958
0
        proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_friendlyName_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
959
        /* Friendly Name */
960
0
        proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_friendlyName, tvb, offset+2, tvb_get_letohs(tvb,offset), ENC_ASCII);
961
0
        offset +=tvb_get_letohs(tvb,offset)+2;
962
0
    }
963
    /* Service Address List */
964
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_number_of_service_addresses, tvb, offset, 2, ENC_LITTLE_ENDIAN);
965
0
    offset += 2;
966
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_service_address_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
967
0
    offset += 2;
968
    /* A list of IPV6_Endpoint Structures follows */
969
0
    dissect_ipv6_endpoint_structure(tvb, offset,tvb_get_letohs(tvb,offset-4)*tvb_get_letohs(tvb,offset-2) , pnrp_encodedCPA_tree);
970
0
    offset += tvb_get_letohs(tvb,offset-4)*tvb_get_letohs(tvb,offset-2);
971
    /* A number of Payload Structures */
972
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_number_of_payload_structures, tvb, offset, 2, ENC_LITTLE_ENDIAN);
973
0
    offset += 2;
974
0
    proto_tree_add_item(pnrp_encodedCPA_tree, hf_pnrp_encodedCPA_total_bytes_of_payload, tvb, offset, 2, ENC_LITTLE_ENDIAN);
975
0
    offset += 2;
976
0
    dissect_payload_structure(tvb,offset, tvb_get_letohs(tvb,offset-2)-4,pnrp_encodedCPA_tree);
977
0
    offset += tvb_get_letohs(tvb,offset-2)-4;
978
    /* Public Key */
979
0
    dissect_publicKey_structure(tvb, offset,tvb_get_letohs(tvb,offset),pnrp_encodedCPA_tree);
980
0
    offset += tvb_get_letohs(tvb,offset);
981
    /* Signature */
982
0
    dissect_signature_structure(tvb, offset,tvb_get_letohs(tvb,offset),pnrp_encodedCPA_tree);
983
    /*offset += tvb_get_letohs(tvb,offset);*/
984
0
}
985
static void dissect_payload_structure(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
986
0
{
987
0
    uint16_t lengthOfData;
988
    /* Add a new Subtree */
989
0
    proto_item *pnrp_payload_tree;
990
    /* Check if we actually should display something */
991
0
    if (0>=length )
992
0
        return;
993
994
0
    pnrp_payload_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_pnrp_message_payloadStructure, NULL, "Payload Structure");
995
996
    /* Dissect the Payload Structure */
997
    /* Payload Type */
998
0
    proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
999
0
    offset += 4;
1000
    /* Data Length */
1001
0
    lengthOfData = tvb_get_letohs(tvb,offset);
1002
0
    proto_tree_add_item(pnrp_payload_tree, hf_pnrp_length_of_data, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1003
0
    offset += 2;
1004
    /* IPV6_APP_ENDPOINT Structure */
1005
0
    while (20 <= lengthOfData) {
1006
0
        dissect_ipv6_address(tvb, offset, 16, pnrp_payload_tree);
1007
0
        offset += 16;
1008
0
        proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1009
0
        offset += 2;
1010
0
        proto_tree_add_item(pnrp_payload_tree, hf_pnrp_payload_iana_proto, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1011
0
        offset += 2;
1012
0
        lengthOfData -=20;
1013
0
    }
1014
0
}
1015
1016
static void dissect_publicKey_structure(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
1017
0
{
1018
0
    uint16_t objIDLength;
1019
0
    uint16_t cbDataLength;
1020
    /* Add a new Subtree */
1021
0
    proto_tree *pnrp_publicKey_tree;
1022
    /* Check if we can safely parse Data */
1023
0
    if (0 < length) {
1024
0
        pnrp_publicKey_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_pnrp_message_publicKeyStructure, NULL, "CPA Public Key Structure");
1025
        /* Parsing of Data */
1026
        /* Field Length of Structure */
1027
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_length_of_structure, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1028
0
        offset += 2;
1029
        /* ObjID length */
1030
0
        objIDLength = tvb_get_letohs(tvb,offset);
1031
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_size_of_algorithm_oid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1032
0
        offset += 2;
1033
        /* Reserved */
1034
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1035
0
        offset +=2;
1036
        /* Public Key cbData Length */
1037
0
        cbDataLength = tvb_get_letohs(tvb,offset);
1038
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_size_of_cbdata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1039
0
        offset += 2;
1040
        /* Unused Bits, actually only 7... */
1041
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_unused_bits, tvb, offset, 1, ENC_NA);
1042
0
        offset +=1;
1043
        /* Algorithm ObjID */
1044
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_objID, tvb, offset, objIDLength, ENC_ASCII);
1045
0
        offset += objIDLength;
1046
        /*  Public Key Data */
1047
0
        proto_tree_add_item(pnrp_publicKey_tree, hf_pnrp_publicKey_publicKeyData, tvb, offset, cbDataLength, ENC_ASCII);
1048
0
    }
1049
0
}
1050
static void dissect_signature_structure(tvbuff_t *tvb, int offset, int length, proto_tree *tree)
1051
0
{
1052
0
    uint16_t signatureLength;
1053
    /* Add a new Subtree */
1054
0
    proto_tree *pnrp_signature_tree;
1055
1056
    /* Check if we can safely parse Data */
1057
0
    if (0 < length) {
1058
0
        pnrp_signature_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_pnrp_message_signatureStructure, NULL, "Signature Structure");
1059
        /* Parsing of Data */
1060
        /* Field Length of Structure */
1061
0
        proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_structure_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1062
0
        offset +=2;
1063
        /* Signature Length */
1064
0
        signatureLength = tvb_get_letohs(tvb,offset);
1065
0
        proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1066
0
        offset += 2;
1067
        /* Hash Algorithm Identifier */
1068
0
        proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_hash_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1069
0
        offset += 4;
1070
        /* Signature Data */
1071
0
        proto_tree_add_item(pnrp_signature_tree, hf_pnrp_signature_signatureData, tvb, offset, signatureLength, ENC_NA);
1072
0
    }
1073
0
}
1074
1075
/* Register the protocol */
1076
void proto_register_pnrp(void)
1077
15
{
1078
    /* A header field is something you can search/filter on.
1079
     *
1080
     * We create a structure to register our fields. It consists of an
1081
     * array of hf_register_info structures, each of which are of the format
1082
     * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1083
     */
1084
15
    static hf_register_info hf[] = {
1085
15
        { &hf_pnrp_header,
1086
15
            { "Header", "pnrp.header", FT_NONE, BASE_NONE, NULL, 0x0,
1087
15
                "PNRP Header", HFILL }},
1088
15
        { &hf_pnrp_header_fieldID,
1089
15
            { "Header FieldID", "pnrp.header.fieldID", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1090
15
                NULL, HFILL }},
1091
15
        { &hf_pnrp_header_length,
1092
15
            { "Header length", "pnrp.header.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1093
15
                NULL, HFILL }},
1094
15
        { &hf_pnrp_header_ident,
1095
15
            { "Ident", "pnrp.ident", FT_UINT8, BASE_HEX, NULL, 0x0,
1096
15
                NULL, HFILL }},
1097
15
        { &hf_pnrp_header_versionMajor,
1098
15
            { "Version Major", "pnrp.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1099
15
                NULL, HFILL }},
1100
15
        { &hf_pnrp_header_versionMinor,
1101
15
            { "Version Minor", "pnrp.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1102
15
                NULL, HFILL }},
1103
15
        { &hf_pnrp_header_messageType,
1104
15
            { "Message Type", "pnrp.messageType", FT_UINT8, BASE_DEC, VALS(messageType), 0x0,
1105
15
                NULL, HFILL }},
1106
15
        { &hf_pnrp_header_messageID,
1107
15
            { "Message ID", "pnrp.header.messageID", FT_UINT32, BASE_HEX, NULL, 0x0,
1108
15
                NULL, HFILL }},
1109
15
        { &hf_pnrp_message_type,
1110
15
            { "Segment Type", "pnrp.segment.type", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1111
15
                NULL, HFILL }},
1112
15
        { &hf_pnrp_message_length,
1113
15
            { "Segment length", "pnrp.segment.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1114
15
                "Message length", HFILL }},
1115
15
        { &hf_pnrp_message_headerack,
1116
15
            { "ACKed Header ID", "pnrp.segment.headerAck", FT_UINT32, BASE_HEX, NULL, 0x0,
1117
15
                NULL, HFILL }},
1118
15
        { &hf_pnrp_message_pnrpID,
1119
15
            { "PNRP ID", "pnrp.segment.pnrpID", FT_BYTES, BASE_NONE, NULL, 0x0,
1120
15
                NULL, HFILL }},
1121
        /* Inquire Flags */
1122
15
        { &hf_pnrp_message_inquire_flags,
1123
15
            { "Flags", "pnrp.segment.inquire.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1124
15
                NULL, HFILL }},
1125
15
        { &hf_pnrp_message_inquire_flags_reserved1,
1126
15
            { "Reserved 1", "pnrp.segment.inquire.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED1,
1127
15
                NULL, HFILL }},
1128
15
        { &hf_pnrp_message_inquire_flags_Abit,
1129
15
            { "CPA should (a)ppear in response", "pnrp.segment.inquire.flags.Abit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_A,
1130
15
                NULL, HFILL }},
1131
15
        { &hf_pnrp_message_inquire_flags_Xbit,
1132
15
            { "E(X)tended Payload sent in Authority response", "pnrp.segment.inquire.flags.Xbit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_X,
1133
15
                NULL, HFILL }},
1134
15
        { &hf_pnrp_message_inquire_flags_Cbit,
1135
15
            { "(C)ertificate Chain sent in Authority response", "pnrp.segment.inquire.flags.Cbit", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_C,
1136
15
                NULL, HFILL }},
1137
15
        { &hf_pnrp_message_inquire_flags_reserved2,
1138
15
            { "Reserved 2", "pnrp.segment.inquire.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_INQUIRE_RESERVED2,
1139
15
                NULL, HFILL }},
1140
15
        { &hf_pnrp_padding,
1141
15
            { "Padding", "pnrp.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
1142
15
                NULL, HFILL }},
1143
        /* Classifier */
1144
15
        { &hf_pnrp_message_classifier_unicodeCount,
1145
15
            { "Number of Unicode Characters", "pnrp.segment.classifier.unicodeCount", FT_UINT16, BASE_DEC, NULL, 0x0,
1146
15
                NULL, HFILL }},
1147
15
        { &hf_pnrp_message_classifier_arrayLength,
1148
15
            { "Array Length", "pnrp.segment.classifier.arrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1149
15
                NULL, HFILL }},
1150
15
        { &hf_pnrp_message_classifier_entryLength,
1151
15
            { "Entry Length", "pnrp.segment.classifier.entryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1152
15
                NULL, HFILL }},
1153
15
        { &hf_pnrp_message_classifier_string,
1154
15
            { "Classifier", "pnrp.segment.classifier.string", FT_STRING, BASE_NONE, NULL, 0x0,
1155
15
                NULL, HFILL }},
1156
        /* Ack Flags */
1157
15
        { &hf_pnrp_message_ack_flags_reserved,
1158
15
            { "Reserved", "pnrp.segment.ack.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1159
15
                NULL, HFILL }},
1160
15
        { &hf_pnrp_message_ack_flags_Nbit,
1161
15
            { "(N)ot found Bit", "pnrp.segment.ack.flags.Nbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1162
15
                NULL, HFILL }},
1163
        /* Authority Flags */
1164
15
        { &hf_pnrp_message_authority_flags,
1165
15
            { "Flags", "pnrp.segment.authority.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1166
15
                NULL, HFILL }},
1167
15
        { &hf_pnrp_message_authority_flags_reserved1,
1168
15
            { "Reserved 1", "pnrp.segment.authority.flags.reserved1", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED1,
1169
15
                NULL, HFILL }},
1170
15
        { &hf_pnrp_message_authority_flags_Lbit,
1171
15
            { "(L)eaf Set", "pnrp.segment.authority.flags.Lbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_L,
1172
15
                NULL, HFILL }},
1173
15
        { &hf_pnrp_message_authority_flags_reserved2,
1174
15
            { "Reserved 2", "pnrp.segment.authority.flags.reserved2", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED2,
1175
15
                NULL, HFILL }},
1176
15
        { &hf_pnrp_message_authority_flags_Bbit,
1177
15
            { "(B)usy", "pnrp.segment.authority.flags.Bbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_B,
1178
15
                NULL, HFILL }},
1179
15
        { &hf_pnrp_message_authority_flags_reserved3,
1180
15
            { "Reserved 3", "pnrp.segment.authority.flags.reserved3", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_RESERVED3,
1181
15
                NULL, HFILL }},
1182
15
        { &hf_pnrp_message_authority_flags_Nbit,
1183
15
            { "(N)ot found", "pnrp.segment.authority.flags.Nbit", FT_UINT16, BASE_HEX, NULL, FLAGS_AUTHORITY_N,
1184
15
                NULL, HFILL }},
1185
        /* Flood Control Flags */
1186
15
        { &hf_pnrp_message_flood_flags_reserved1,
1187
15
            { "Reserved", "pnrp.segment.flood.flags.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1188
15
                NULL, HFILL }},
1189
15
        { &hf_pnrp_message_flood_flags_Dbit,
1190
15
            { "(D)on't send ACK", "pnrp.segment.flood.flags.Dbit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1191
15
                NULL, HFILL }},
1192
        /* Split Controls */
1193
15
        { &hf_pnrp_message_splitControls_authorityBuffer,
1194
15
            { "Authority Buffer Size", "pnrp.segment.splitControls.authorityBuffer", FT_UINT16, BASE_DEC, NULL, 0x0,
1195
15
                NULL, HFILL }},
1196
        /* IPv6 Endpoint Array */
1197
15
        { &hf_pnrp_message_ipv6EndpointArray_NumberOfEntries,
1198
15
            { "Number of Entries", "pnrp.segment.ipv6EndpointArray.NumberOfEntries", FT_UINT16, BASE_DEC, NULL, 0x0,
1199
15
                NULL, HFILL }},
1200
15
        { &hf_pnrp_message_ipv6EndpointArray_ArrayLength,
1201
15
            { "Array Length", "pnrp.segment.ipv6EndpointArray.ArrayLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1202
15
                NULL, HFILL }},
1203
15
        { &hf_pnrp_message_ipv6EndpointArray_EntryLength,
1204
15
            { "Entry Length", "pnrp.segment.ipv6EndpointArray.EntryLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1205
15
                NULL, HFILL }},
1206
        /* Encoded CPA structure */
1207
15
        { &hf_pnrp_encodedCPA,
1208
15
            { "Encoded CPA structure", "pnrp.encodedCPA", FT_NONE, BASE_NONE, NULL, 0x0,
1209
15
                NULL, HFILL }},
1210
15
        { &hf_pnrp_encodedCPA_length,
1211
15
            { "Length", "pnrp.encodedCPA.length", FT_UINT16, BASE_DEC, NULL, 0x0,
1212
15
                NULL, HFILL }},
1213
15
        { &hf_pnrp_encodedCPA_majorVersion,
1214
15
            { "CPA Major Version", "pnrp.encodedCPA.vMajor", FT_UINT8, BASE_DEC, NULL, 0x0,
1215
15
                NULL, HFILL }},
1216
15
        { &hf_pnrp_encodedCPA_minorVersion,
1217
15
            { "CPA Minor Version", "pnrp.encodedCPA.vMinor", FT_UINT8, BASE_DEC, NULL, 0x0,
1218
15
                NULL, HFILL }},
1219
            /* Encoded CPA flags */
1220
15
        { &hf_pnrp_encodedCPA_flags,
1221
15
            { "Flags", "pnrp.encodedCPA.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1222
15
                NULL, HFILL }},
1223
15
        { &hf_pnrp_encodedCPA_flags_reserved,
1224
15
            { "Reserved", "pnrp.encodedCPA.flags.reserved", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_RESERVED,
1225
15
                NULL, HFILL }},
1226
15
        { &hf_pnrp_encodedCPA_flags_Xbit,
1227
15
            { "CPA has E(X)tended Payload", "pnrp.encodedCPA.flags.xbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_X,
1228
15
                NULL, HFILL }},
1229
15
        { &hf_pnrp_encodedCPA_flags_Fbit,
1230
15
            { "CPA contains (F)riendly Name", "pnrp.encodedCPA.flags.fbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_F,
1231
15
                NULL, HFILL }},
1232
15
        { &hf_pnrp_encodedCPA_flags_Cbit,
1233
15
            { "CPA contains (C)lassifier Hash", "pnrp.encodedCPA.flags.cbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_C,
1234
15
                NULL, HFILL }},
1235
15
        { &hf_pnrp_encodedCPA_flags_Abit,
1236
15
            { "CPA contains Binary (A)uthority field", "pnrp.encodedCPA.flags.abit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_A,
1237
15
                NULL, HFILL }},
1238
15
        { &hf_pnrp_encodedCPA_flags_Ubit,
1239
15
            { "Friendly Name in (U)TF-8", "pnrp.encodedCPA.flags.ubit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_U,
1240
15
                NULL, HFILL }},
1241
15
        { &hf_pnrp_encodedCPA_flags_Rbit,
1242
15
            { "This is a (r)evoke CPA", "pnrp.encodedCPA.flags.rbit", FT_UINT8, BASE_HEX, NULL, FLAGS_ENCODED_CPA_R,
1243
15
                NULL, HFILL }},
1244
        /* TODO: Find correct way to Display Time */
1245
15
        { &hf_pnrp_encodedCPA_notAfter,
1246
15
            { "CPA expiration Date", "pnrp.encodedCPA.expirationDate", FT_UINT64,BASE_DEC, NULL, 0x0,
1247
15
                "CPA expiration Date since January 1, 1601 UTC", HFILL }},
1248
15
        { &hf_pnrp_encodedCPA_serviceLocation,
1249
15
            { "Service Location", "pnrp.encodedCPA.serviceLocation", FT_BYTES,BASE_NONE, NULL, 0x0,
1250
15
                NULL, HFILL }},
1251
15
        { &hf_pnrp_encodedCPA_binaryAuthority,
1252
15
            { "Binary Authority", "pnrp.encodedCPA.binaryAuthority", FT_BYTES,BASE_NONE, NULL, 0x0,
1253
15
                "SHA-1 Hash of PublicKey Data field", HFILL }},
1254
15
        { &hf_pnrp_encodedCPA_classifierHash,
1255
15
            { "Classifier Hash", "pnrp.encodedCPA.classifierHash", FT_BYTES,BASE_NONE, NULL, 0x0,
1256
15
                "SHA-1 Hash of the classifier text", HFILL }},
1257
15
        { &hf_pnrp_encodedCPA_friendlyName,
1258
15
            { "Friendly Name of PNRP ID", "pnrp.encodedCPA.friendlyName", FT_STRING,BASE_NONE, NULL, 0x0,
1259
15
                "A human-readable label identifying the PNRP ID", HFILL }},
1260
        /* Lookup Controls */
1261
15
        { &hf_pnrp_message_lookupControls_flags,
1262
15
            { "Flags", "pnrp.lookupControls.flags", FT_UINT16, BASE_HEX, NULL, 0x0,
1263
15
                NULL, HFILL }},
1264
15
        { &hf_pnrp_message_lookupControls_flags_reserved,
1265
15
            { "Reserved", "pnrp.lookupControls.flags.reserved", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_RESERVED,
1266
15
                NULL, HFILL }},
1267
15
        { &hf_pnrp_message_lookupControls_flags_Abit,
1268
15
            { "A bit", "pnrp.lookupControls.flags.Abit", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_A,
1269
15
                "Sender is willing to accept returned nodes that are not closer to the target ID than the Validate PNRP ID", HFILL }},
1270
15
        { &hf_pnrp_message_lookupControls_flags_0bit,
1271
15
            { "0 bit - reserved", "pnrp.lookupControls.flags.0bit", FT_UINT16, BASE_HEX, NULL, FLAGS_LOOKUPCONTROLS_0,
1272
15
                NULL, HFILL }},
1273
15
        { &hf_pnrp_message_lookupControls_precision,
1274
15
            { "Precision", "pnrp.lookupControls.precision", FT_UINT16, BASE_HEX, NULL, 0x0,
1275
15
                "Precision - Number of significant bits to match", HFILL }},
1276
15
        { &hf_pnrp_message_lookupControls_resolveCriteria,
1277
15
            { "Resolve Criteria", "pnrp.lookupControls.resolveCriteria", FT_UINT8, BASE_HEX, VALS(resolveCriteria), 0x0,
1278
15
                NULL, HFILL }},
1279
15
        { &hf_pnrp_message_lookupControls_reasonCode,
1280
15
            { "Reason Code", "pnrp.lookupControls.reasonCode", FT_UINT8, BASE_HEX, VALS(reasonCode), 0x0,
1281
15
                NULL, HFILL }},
1282
        /* Public Key Structure */
1283
15
        { &hf_pnrp_publicKey_objID,
1284
15
            { "Public Key Object Identifier", "pnrp.publicKey.objID", FT_STRING,BASE_NONE, NULL, 0x0,
1285
15
                "An ASN.1-encoded object identifier (OID) indicating the public key format", HFILL }},
1286
15
        { &hf_pnrp_publicKey_publicKeyData,
1287
15
            { "Public Key Data", "pnrp.publicKey.publicKeyData", FT_STRING,BASE_NONE, NULL, 0x0,
1288
15
                "An ASN.1-encoded 1024-bit RSA public key", HFILL }},
1289
        /* Signature Structure */
1290
15
        { &hf_pnrp_signature_signatureData,
1291
15
            { "Signature", "pnrp.signature.data", FT_BYTES,BASE_NONE, NULL, 0x0,
1292
15
                "Signature created when signing the CPA", HFILL }},
1293
1294
        /* Route Entry */
1295
15
        { &hf_pnrp_message_routeEntry_portNumber,
1296
15
            { "Port Number", "pnrp.segment.routeEntry.portNumber", FT_UINT16, BASE_DEC, NULL, 0x0,
1297
15
                NULL, HFILL }},
1298
15
        { &hf_pnrp_message_routeEntry_flags,
1299
15
            { "Flags", "pnrp.segment.routeEntry.flags", FT_UINT8, BASE_DEC, NULL, 0x0,
1300
15
                NULL, HFILL }},
1301
15
        { &hf_pnrp_message_routeEntry_addressCount,
1302
15
            { "Address Count", "pnrp.segment.routeEntry.addressCount", FT_UINT8, BASE_DEC, NULL, 0x0,
1303
15
                NULL, HFILL }},
1304
15
        { &hf_pnrp_message_nonce,
1305
15
            { "Nonce", "pnrp.segment.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1306
15
                NULL, HFILL }},
1307
15
        { &hf_pnrp_message_hashednonce,
1308
15
            { "Hashed Nonce", "pnrp.segment.hashednonce", FT_BYTES, BASE_NONE, NULL, 0x0,
1309
15
                NULL, HFILL }},
1310
15
        { &hf_pnrp_message_idArray_NumEntries,
1311
15
            { "Number of Entries", "pnrp.segment.idArray.NumEntries", FT_UINT16, BASE_DEC, NULL, 0x0,
1312
15
                NULL, HFILL }},
1313
15
        { &hf_pnrp_message_idArray_Length,
1314
15
            { "Length of Array", "pnrp.segment.idArray.Length", FT_UINT16, BASE_DEC, NULL, 0x0,
1315
15
                NULL, HFILL }},
1316
15
        { &hf_pnrp_message_ElementFieldType,
1317
15
            { "Type of Array Entry", "pnrp.segment.ElementFieldType", FT_UINT16, BASE_HEX, VALS(fieldID), 0x0,
1318
15
                NULL, HFILL }},
1319
15
        { &hf_pnrp_message_idarray_Entrylength,
1320
15
            { "Length of each Array Entry", "pnrp.segment.idArray.Entrylength", FT_UINT16, BASE_DEC, NULL, 0x0,
1321
15
                NULL, HFILL }},
1322
15
        { &hf_pnrp_message_certChain,
1323
15
            { "Certificate Chain", "pnrp.segment.certChain", FT_BYTES,BASE_NONE, NULL, 0x0,
1324
15
                "A Certificate Chain, containing the public key used to sign the CPA and its Certificate Chain", HFILL }},
1325
15
        { &hf_pnrp_message_solicitType,
1326
15
            { "Solicit Type", "pnrp.segment.solicitType", FT_UINT8, BASE_DEC, VALS(solicitType), 0x0,
1327
15
                NULL, HFILL }},
1328
15
        { &hf_pnrp_message_ipv6,
1329
15
            { "IPv6 Address","pnrp.segment.ipv6Address",FT_IPv6, BASE_NONE, NULL, 0x0,NULL,HFILL}},
1330
1331
15
        { &hf_pnrp_fragments,
1332
15
            { "Fragments", "pnrp.segment.splitControls.fragments", FT_NONE, BASE_NONE, NULL, 0,
1333
15
                NULL, HFILL }},
1334
15
        { &hf_pnrp_fragment,
1335
15
            { "Fragment", "pnrp.segment.splitControls.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0,
1336
15
                NULL, HFILL }},
1337
15
        { &hf_pnrp_fragment_overlap,
1338
15
            { "Fragment Overlap", "pnrp.segment.splitControls.fragment_overlap", FT_BOOLEAN, BASE_NONE, NULL, 0,
1339
15
                NULL, HFILL }},
1340
15
        { &hf_pnrp_fragment_overlap_conflict,
1341
15
            { "Fragment Overlap Conflict", "pnrp.segment.splitControls.fragment_overlap_conflict", FT_BOOLEAN, BASE_NONE, NULL, 0,
1342
15
                NULL, HFILL }},
1343
15
        { &hf_pnrp_fragment_multiple_tails,
1344
15
            { "Fragment Multiple Tails", "pnrp.segment.splitControls.fragment_multiple_tails", FT_BOOLEAN, BASE_NONE, NULL, 0,
1345
15
                NULL, HFILL }},
1346
15
        { &hf_pnrp_fragment_too_long_fragment,
1347
15
            { "Too Long Fragment", "pnrp.segment.splitControls.fragment_too_long_fragment", FT_BOOLEAN, BASE_NONE, NULL, 0,
1348
15
                NULL, HFILL }},
1349
15
        { &hf_pnrp_fragment_error,
1350
15
            { "Fragment Error", "pnrp.segment.splitControls.fragment_error", FT_FRAMENUM, BASE_NONE, NULL, 0,
1351
15
                NULL, HFILL }},
1352
15
        { &hf_pnrp_fragment_count,
1353
15
            { "Fragment Count", "pnrp.segment.splitControls.fragment_count", FT_UINT32, BASE_DEC, NULL, 0,
1354
15
                NULL, HFILL }},
1355
15
        { &hf_pnrp_reassembled_in,
1356
15
            { "Reassembled In", "pnrp.segment.splitControls.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0,
1357
15
                NULL, HFILL }},
1358
15
        { &hf_pnrp_reassembled_length,
1359
15
            { "Reassembled Length", "pnrp.segment.splitControls.reassembled_length", FT_UINT32, BASE_DEC, NULL, 0,
1360
15
                NULL, HFILL }},
1361
15
        { &hf_pnrp_reassembled_data,
1362
15
            { "Reassembled Data", "pnrp.segment.splitControls.reassembled_data", FT_BYTES, BASE_NONE, NULL, 0,
1363
15
                NULL, HFILL }},
1364
15
        { &hf_pnrp_fragmented_payload,
1365
15
            { "Fragmented Payload", "pnrp.segment.splitControls.fragmented_payload", FT_BYTES, BASE_NONE, NULL, 0,
1366
15
                NULL, HFILL }},
1367
1368
      /* Generated from convert_proto_tree_add_text.pl */
1369
15
      { &hf_pnrp_message_flags, { "Flags", "pnrp.segment.flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1370
15
      { &hf_pnrp_reserved8, { "Reserved", "pnrp.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1371
15
      { &hf_pnrp_reserved16, { "Reserved", "pnrp.reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1372
15
      { &hf_pnrp_message_offset, { "Offset", "pnrp.segment.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1373
15
      { &hf_pnrp_message_data, { "Data", "pnrp.segment.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1374
15
      { &hf_pnrp_message_port_number, { "Port Number", "pnrp.segment.port_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1375
15
      { &hf_pnrp_encodedCPA_friendlyName_length, { "Length of Friendly name", "pnrp.encodedCPA.friendlyName.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1376
15
      { &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 }},
1377
15
      { &hf_pnrp_encodedCPA_service_address_length, { "Service Address Length", "pnrp.encodedCPA.service_address_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1378
15
      { &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 }},
1379
15
      { &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 }},
1380
15
      { &hf_pnrp_payload_type, { "Payload Type", "pnrp.payload.type", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1381
15
      { &hf_pnrp_length_of_data, { "Length of Data", "pnrp.payload.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1382
15
      { &hf_pnrp_payload_port, { "Port Number", "pnrp.payload.port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1383
15
      { &hf_pnrp_payload_iana_proto, { "IANA Protocol Number", "pnrp.payload.iana_proto", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1384
15
      { &hf_pnrp_publicKey_length_of_structure, { "Length of Structure", "pnrp.publicKey.structure_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1385
15
      { &hf_pnrp_publicKey_size_of_algorithm_oid, { "Size of Algorithm OID", "pnrp.publicKey.algorithm_oid_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1386
15
      { &hf_pnrp_publicKey_reserved, { "Reserved", "pnrp.publicKey.reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1387
15
      { &hf_pnrp_publicKey_size_of_cbdata, { "Size of cbData", "pnrp.publicKey.cbdata_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1388
15
      { &hf_pnrp_publicKey_unused_bits, { "Unused Bits", "pnrp.publicKey.unused_bits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1389
15
      { &hf_pnrp_signature_structure_length, { "Length of Structure", "pnrp.signature.structure_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1390
15
      { &hf_pnrp_signature_length, { "Length of Signature", "pnrp.signature.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1391
15
      { &hf_pnrp_signature_hash_id, { "Hash Algorithm Identifier", "pnrp.signature.hash_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1392
1393
15
    };
1394
1395
    /* Protocol subtree array */
1396
15
    static int *ett[] = {
1397
15
        &ett_pnrp,
1398
15
        &ett_pnrp_header,
1399
15
        &ett_pnrp_message,
1400
15
        &ett_pnrp_message_inquire_flags,
1401
15
        &ett_pnrp_message_authority_flags,
1402
15
        &ett_pnrp_message_encodedCPA,
1403
15
        &ett_pnrp_message_encodedCPA_flags,
1404
15
        &ett_pnrp_message_payloadStructure,
1405
15
        &ett_pnrp_message_publicKeyStructure,
1406
15
        &ett_pnrp_message_signatureStructure,
1407
15
        &ett_pnrp_message_lookupControls_flags,
1408
15
        &ett_pnrp_fragment,
1409
15
        &ett_pnrp_fragments
1410
15
    };
1411
    /* Register the Dissector with Wireshark */
1412
15
    proto_pnrp = proto_register_protocol(PROTONAME,PROTOSHORTNAME,PROTOABBREV);
1413
1414
15
    proto_register_field_array(proto_pnrp,hf,array_length(hf));
1415
15
    proto_register_subtree_array (ett, array_length(ett));
1416
1417
15
    pnrp_handle = register_dissector(PROTOABBREV, dissect_pnrp, proto_pnrp);
1418
1419
15
    reassembly_table_register(&pnrp_reassembly_table,
1420
15
                          &addresses_reassembly_table_functions);
1421
15
}
1422
1423
/* Initialise the dissector */
1424
void proto_reg_handoff_pnrp(void)
1425
15
{
1426
15
    dissector_add_uint_with_preference("udp.port",PNRP_PORT,pnrp_handle);
1427
15
}
1428
1429
/*
1430
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1431
 *
1432
 * Local variables:
1433
 * c-basic-offset: 4
1434
 * tab-width: 8
1435
 * indent-tabs-mode: nil
1436
 * End:
1437
 *
1438
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1439
 * :indentSize=4:tabSize=8:noTabs=true:
1440
 */