Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-pcp.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-pcp.c
2
 * Routines for Performace Co-Pilot protocol dissection
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
13
#include <epan/packet.h>
14
#include <epan/expert.h>
15
#include <epan/tfs.h>
16
#include <wsutil/array.h>
17
#include "packet-tcp.h"
18
#include "packet-tls-utils.h"
19
20
void proto_register_pcp(void);
21
void proto_reg_handoff_pcp(void);
22
23
14
#define PCP_PORT 44321
24
0
#define PMPROXY_PORT 44322
25
0
#define PCP_HEADER_LEN 12
26
27
0
#define PM_ERR_NAME -12357
28
29
static dissector_handle_t pcp_handle;
30
31
static int proto_pcp;
32
static int hf_pcp_pdu_length;
33
static int hf_pcp_pdu_type;
34
static int hf_pcp_pdu_pid;
35
static int hf_pcp_pdu_error;
36
static int hf_pcp_pdu_padding;
37
static int hf_pcp_creds_number_of;
38
static int hf_pcp_creds_type;
39
static int hf_pcp_creds_version;
40
static int hf_pcp_start;
41
static int hf_pcp_start_status;
42
static int hf_pcp_start_zero;
43
static int hf_pcp_start_version;
44
static int hf_pcp_start_licensed;
45
static int hf_pcp_features_flags;
46
static int hf_pcp_features_flags_secure;
47
static int hf_pcp_features_flags_compress;
48
static int hf_pcp_features_flags_auth;
49
static int hf_pcp_features_flags_creds_reqd;
50
static int hf_pcp_features_flags_secure_ack;
51
static int hf_pcp_features_flags_no_nss_init;
52
static int hf_pcp_features_flags_container;
53
static int hf_pcp_features_flags_cert_reqd;
54
static int hf_pcp_features_flags_bad_label;
55
static int hf_pcp_features_flags_labels;
56
static int hf_pcp_pmns_traverse;
57
static int hf_pcp_pmns_subtype;
58
static int hf_pcp_pmns_namelen;
59
static int hf_pcp_pmns_name;
60
static int hf_pcp_pmns_names;
61
static int hf_pcp_pmns_names_nstrbytes;
62
static int hf_pcp_pmns_names_numstatus;
63
static int hf_pcp_pmns_names_numnames;
64
static int hf_pcp_pmns_names_nametree;
65
static int hf_pcp_pmns_names_nametree_status;
66
static int hf_pcp_pmns_names_nametree_namelen;
67
static int hf_pcp_pmns_names_nametree_name;
68
static int hf_pcp_pmns_ids;
69
static int hf_pcp_pmns_ids_status;
70
static int hf_pcp_pmns_ids_numids;
71
static int hf_pcp_pmns_child;
72
static int hf_pcp_pmid;
73
static int hf_pcp_pmid_flag;
74
static int hf_pcp_pmid_domain;
75
static int hf_pcp_pmid_cluster;
76
static int hf_pcp_pmid_item;
77
static int hf_pcp_pmid_type;
78
static int hf_pcp_pmid_sem;
79
static int hf_pcp_pmid_inst;
80
static int hf_pcp_profile;
81
static int hf_pcp_ctxnum;
82
static int hf_pcp_profile_g_state;
83
static int hf_pcp_profile_numprof;
84
static int hf_pcp_profile_profile;
85
static int hf_pcp_profile_profile_state;
86
static int hf_pcp_profile_profile_numinst;
87
static int hf_pcp_fetch;
88
static int hf_pcp_fetch_numpmid;
89
static int hf_pcp_when;
90
static int hf_pcp_when_sec;
91
static int hf_pcp_when_usec;
92
static int hf_pcp_desc;
93
static int hf_pcp_desc_req;
94
static int hf_pcp_units;
95
static int hf_pcp_units_dimspace;
96
static int hf_pcp_units_dimtime;
97
static int hf_pcp_units_dimcount;
98
static int hf_pcp_units_scalespace;
99
static int hf_pcp_units_scaletime;
100
static int hf_pcp_units_scalecount;
101
static int hf_pcp_instance;
102
static int hf_pcp_instance_req;
103
static int hf_pcp_instance_namelen;
104
static int hf_pcp_instance_name;
105
static int hf_pcp_instance_indom;
106
static int hf_pcp_instance_valoffset;
107
static int hf_pcp_instance_vallength;
108
static int hf_pcp_instance_value_insitu;
109
static int hf_pcp_instance_value_ptr;
110
static int hf_pcp_instance_value_int;
111
static int hf_pcp_instance_value_uint;
112
static int hf_pcp_instance_value_int64;
113
static int hf_pcp_instance_value_uint64;
114
static int hf_pcp_instance_value_float;
115
static int hf_pcp_instance_value_double;
116
static int hf_pcp_instance_value_aggr;
117
static int hf_pcp_instances;
118
static int hf_pcp_instances_numinst;
119
static int hf_pcp_results;
120
static int hf_pcp_results_numpmid;
121
static int hf_pcp_result;
122
static int hf_pcp_result_numval;
123
static int hf_pcp_result_valfmt;
124
static int hf_pcp_text_req;
125
static int hf_pcp_text_type;
126
static int hf_pcp_text_type_format;
127
static int hf_pcp_text_type_ident;
128
static int hf_pcp_text;
129
static int hf_pcp_text_ident;
130
static int hf_pcp_text_buflen;
131
static int hf_pcp_text_buffer;
132
static int hf_pcp_user_auth_payload;
133
static int hf_pcp_label_req;
134
static int hf_pcp_label;
135
static int hf_pcp_label_ident;
136
static int hf_pcp_label_type;
137
static int hf_pcp_label_padding;
138
static int hf_pcp_label_nsets;
139
static int hf_pcp_label_sets;
140
static int hf_pcp_label_sets_inst;
141
static int hf_pcp_label_sets_nlabels;
142
static int hf_pcp_label_sets_json;
143
static int hf_pcp_label_sets_jsonlen;
144
static int hf_pcp_label_sets_labels;
145
static int hf_pcp_label_sets_labels_nameoffset;
146
static int hf_pcp_label_sets_labels_namelen;
147
static int hf_pcp_label_sets_labels_flags;
148
static int hf_pcp_label_sets_labels_valueoffset;
149
static int hf_pcp_label_sets_labels_valuelen;
150
static int hf_pcp_label_sets_labels_name;
151
static int hf_pcp_label_sets_labels_value;
152
153
static int ett_pcp;
154
static int ett_pcp_pdu_length;
155
static int ett_pcp_pdu_type;
156
static int ett_pcp_pdu_pid;
157
static int ett_pcp_pdu_error;
158
static int ett_pcp_pdu_padding;
159
static int ett_pcp_creds_number_of;
160
static int ett_pcp_creds_type;
161
static int ett_pcp_creds_vala;
162
static int ett_pcp_creds_valb;
163
static int ett_pcp_creds_valc;
164
static int ett_pcp_start;
165
static int ett_pcp_start_status;
166
static int ett_pcp_start_zero;
167
static int ett_pcp_start_version;
168
static int ett_pcp_start_licensed;
169
static int ett_pcp_start_features;
170
static int ett_pcp_pmns_traverse;
171
static int ett_pcp_pmns_subtype;
172
static int ett_pcp_pmns_namelen;
173
static int ett_pcp_pmns_name;
174
static int ett_pcp_pmns_names;
175
static int ett_pcp_pmns_names_nstrbytes;
176
static int ett_pcp_pmns_names_numstatus;
177
static int ett_pcp_pmns_names_numnames;
178
static int ett_pcp_pmns_names_nametree;
179
static int ett_pcp_pmns_names_nametree_status;
180
static int ett_pcp_pmns_names_nametree_namelen;
181
static int ett_pcp_pmns_names_nametree_name;
182
static int ett_pcp_pmns_ids;
183
static int ett_pcp_pmns_ids_status;
184
static int ett_pcp_pmns_ids_numids;
185
static int ett_pcp_pmns_child;
186
static int ett_pcp_pmid;
187
static int ett_pcp_pmid_flag;
188
static int ett_pcp_pmid_domain;
189
static int ett_pcp_pmid_cluster;
190
static int ett_pcp_pmid_item;
191
static int ett_pcp_pmid_type;
192
static int ett_pcp_pmid_sem;
193
static int ett_pcp_profile;
194
static int ett_pcp_ctxnum;
195
static int ett_pcp_profile_g_state;
196
static int ett_pcp_profile_numprof;
197
static int ett_pcp_profile_profile;
198
static int ett_pcp_profile_profile_state;
199
static int ett_pcp_profile_profile_numinst;
200
static int ett_pcp_fetch;
201
static int ett_pcp_fetch_numpmid;
202
static int ett_pcp_when;
203
static int ett_pcp_when_sec;
204
static int ett_pcp_when_usec;
205
static int ett_pcp_desc_req;
206
static int ett_pcp_units;
207
static int ett_pcp_units_dimspace;
208
static int ett_pcp_units_dimtime;
209
static int ett_pcp_units_dimcount;
210
static int ett_pcp_units_scalespace;
211
static int ett_pcp_units_scaletime;
212
static int ett_pcp_units_scalecount;
213
static int ett_pcp_instance;
214
static int ett_pcp_instance_req;
215
static int ett_pcp_instance_namelen;
216
static int ett_pcp_instance_name;
217
static int ett_pcp_instance_inst;
218
static int ett_pcp_instance_indom;
219
static int ett_pcp_instance_valoffset;
220
static int ett_pcp_instance_vallength;
221
static int ett_pcp_instance_value_insitu;
222
static int ett_pcp_instance_value_ptr;
223
static int ett_pcp_instance_value_int;
224
static int ett_pcp_instance_value_uint;
225
static int ett_pcp_instance_value_int64;
226
static int ett_pcp_instance_value_uint64;
227
static int ett_pcp_instance_value_float;
228
static int ett_pcp_instance_value_double;
229
static int ett_pcp_instance_value_aggr;
230
static int ett_pcp_instances;
231
static int ett_pcp_instances_numinst;
232
static int ett_pcp_results;
233
static int ett_pcp_results_numpmid;
234
static int ett_pcp_result;
235
static int ett_pcp_result_numval;
236
static int ett_pcp_result_valfmt;
237
static int ett_pcp_text_req;
238
static int ett_pcp_text_type;
239
static int ett_pcp_text_type_format;
240
static int ett_pcp_text_type_ident;
241
static int ett_pcp_text;
242
static int ett_pcp_text_ident;
243
static int ett_pcp_text_buflen;
244
static int ett_pcp_text_buffer;
245
246
static expert_field ei_pcp_type_event_unimplemented;
247
static expert_field ei_pcp_type_nosupport_unsupported;
248
static expert_field ei_pcp_type_unknown_unknown_value;
249
static expert_field ei_pcp_unimplemented_value;
250
static expert_field ei_pcp_unimplemented_packet_type;
251
static expert_field ei_pcp_ssl_upgrade;
252
static expert_field ei_pcp_ssl_upgrade_failed;
253
static expert_field ei_pcp_label_error;
254
static expert_field ei_pcp_label_error_endianness;
255
256
/* Magic numbers */
257
0
#define PCP_SECURE_ACK_SUCCESSFUL 0
258
259
static const value_string pcp_feature_flags[] = {
260
14
#define PCP_PDU_FLAG_SECURE         0x0001
261
      { PCP_PDU_FLAG_SECURE,        "SECURE" },
262
14
#define PCP_PDU_FLAG_COMPRESS       0x0002
263
      { PCP_PDU_FLAG_COMPRESS,      "COMPRESS" },
264
14
#define PCP_PDU_FLAG_AUTH           0x0004
265
      { PCP_PDU_FLAG_AUTH,          "AUTH"},
266
14
#define PCP_PDU_FLAG_CREDS_REQD     0x0008
267
      { PCP_PDU_FLAG_CREDS_REQD,    "CREDS_REQD" },
268
14
#define PCP_PDU_FLAG_SECURE_ACK     0x0010
269
      { PCP_PDU_FLAG_SECURE_ACK,    "SECURE_ACK" },
270
14
#define PCP_PDU_FLAG_NO_NSS_INIT    0x0020
271
      { PCP_PDU_FLAG_NO_NSS_INIT,   "NO_NSS_INIT" },
272
14
#define PCP_PDU_FLAG_CONTAINER      0x0040
273
      { PCP_PDU_FLAG_CONTAINER,     "CONTAINER" },
274
14
#define PCP_PDU_FLAG_CERT_REQD      0x0080
275
      { PCP_PDU_FLAG_CERT_REQD,     "CERT_REQD" },
276
14
#define PCP_PDU_FLAG_BAD_LABEL      0x0100
277
      { PCP_PDU_FLAG_BAD_LABEL,     "BAD_LABEL" },
278
14
#define PCP_PDU_FLAG_LABELS         0x0200
279
      { PCP_PDU_FLAG_LABELS,        "LABELS" },
280
      { 0, NULL }
281
};
282
283
/* packet types */
284
static const value_string packettypenames[] = {
285
0
#define PCP_PDU_START_OR_ERROR  0x7000
286
       {PCP_PDU_START_OR_ERROR, "START/ERROR" },
287
0
#define PCP_PDU_RESULT          0x7001
288
       {PCP_PDU_RESULT,         "RESULT" },
289
0
#define PCP_PDU_PROFILE         0x7002
290
       {PCP_PDU_PROFILE,        "PROFILE"},
291
0
#define PCP_PDU_FETCH           0x7003
292
       {PCP_PDU_FETCH,          "FETCH"},
293
0
#define PCP_PDU_DESC_REQ        0x7004
294
       {PCP_PDU_DESC_REQ,       "DESC_REQ"},
295
0
#define PCP_PDU_DESC            0x7005
296
       {PCP_PDU_DESC,           "DESC"},
297
0
#define PCP_PDU_INSTANCE_REQ    0x7006
298
       {PCP_PDU_INSTANCE_REQ,   "INSTANCE_REQ" },
299
0
#define PCP_PDU_INSTANCE        0x7007
300
       {PCP_PDU_INSTANCE,       "INSTANCE" },
301
0
#define PCP_PDU_TEXT_REQ        0x7008
302
       {PCP_PDU_TEXT_REQ,       "TEXT_REQ" },
303
0
#define PCP_PDU_TEXT            0x7009
304
       {PCP_PDU_TEXT,           "TEXT" },
305
#define PCP_PDU_CONTROL_REQ     0x700a
306
       {PCP_PDU_CONTROL_REQ,    "CONTROL_REQ" },  /* unimplemented (pmlc/pmlogger only) */
307
#define PCP_PDU_DATA_X          0x700b
308
       {PCP_PDU_DATA_X,         "DATA_X" },       /* unimplemented (pmlc/pmlogger only) */
309
0
#define PCP_PDU_CREDS           0x700c
310
       {PCP_PDU_CREDS,          "CREDS" },
311
0
#define PCP_PDU_PMNS_IDS        0x700d
312
       {PCP_PDU_PMNS_IDS,       "PMNS_IDS" },
313
0
#define PCP_PDU_PMNS_NAMES      0x700e
314
       {PCP_PDU_PMNS_NAMES,     "PMNS_NAMES" },
315
0
#define PCP_PDU_PMNS_CHILD      0x700f
316
       {PCP_PDU_PMNS_CHILD,     "PMNS_CHILD" },
317
0
#define PCP_PDU_PMNS_TRAVERSE   0x7010 /*also type FINISH as per pcp headers, but I can not see it used */
318
       {PCP_PDU_PMNS_TRAVERSE,  "PMNS_TRAVERSE" },
319
0
#define PCP_PDU_USER_AUTH       0x7011
320
       {PCP_PDU_USER_AUTH,      "USER_AUTH" },
321
0
#define PCP_PDU_LABEL_REQ       0x7012
322
       {PCP_PDU_LABEL_REQ,      "LABEL_REQ" },
323
0
#define PCP_PDU_LABEL           0x7013
324
       {PCP_PDU_LABEL,          "LABEL" },
325
       { 0, NULL }
326
};
327
328
static const value_string packettypenames_pm_units_space[] = {
329
    { 0, "PM_SPACE_BYTE" },
330
    { 1, "PM_SPACE_KBYTE" },
331
    { 2, "PM_SPACE_MBYTE" },
332
    { 3, "PM_SPACE_GBYTE" },
333
    { 4, "PM_SPACE_TBYTE" },
334
    { 5, "PM_SPACE_PBYTE" },
335
    { 6, "PM_SPACE_EBYTE" },
336
    { 0, NULL }
337
};
338
339
static const value_string packettypenames_pm_units_time[] = {
340
    { 0, "PM_TIME_NSEC" },
341
    { 1, "PM_TIME_USEC" },
342
    { 2, "PM_TIME_MSEC" },
343
    { 3, "PM_TIME_SEC" },
344
    { 4, "PM_TIME_MIN" },
345
    { 5, "PM_TIME_HOUR" },
346
    { 0, NULL }
347
};
348
349
static const value_string packettypenames_pm_types[] = {
350
0
    #define PM_TYPE_NOSUPPORT    -1
351
    {  -1, "PM_TYPE_NOSUPPORT" },
352
0
    #define PM_TYPE_32       0
353
    {   0, "PM_TYPE_32" },
354
0
    #define PM_TYPE_U32      1
355
    {   1, "PM_TYPE_U32" },
356
0
    #define PM_TYPE_64       2
357
    {   2, "PM_TYPE_64" },
358
0
    #define PM_TYPE_U64      3
359
    {   3, "PM_TYPE_U64" },
360
0
    #define PM_TYPE_FLOAT    4
361
    {   4, "PM_TYPE_FLOAT" },
362
0
    #define PM_TYPE_DOUBLE   5
363
    {   5, "PM_TYPE_DOUBLE" },
364
0
    #define PM_TYPE_STRING   6
365
    {   6, "PM_TYPE_STRING" },
366
0
    #define PM_TYPE_AGGREGATE 7
367
    {   7, "PM_TYPE_AGGREGATE" },
368
0
    #define PM_TYPE_AGGREGATE_STATIC 8
369
    {   8, "PM_TYPE_AGGREGATE_STATIC" },
370
0
    #define PM_TYPE_EVENT    9
371
    {   9, "PM_TYPE_EVENT" },
372
0
    #define PM_TYPE_UNKNOWN  255
373
    { 255, "PM_TYPE_UNKNOWN" },
374
    {   0, NULL }
375
};
376
377
static const value_string packettypenames_pm_types_sem[] = {
378
    {  1, "PM_SEM_COUNTER" },
379
    {  3, "PM_SEM_INSTANT" },
380
    {  4, "PM_SEM_DISCRETE" },
381
    {  0, NULL }
382
};
383
384
static const value_string packettypenames_text_type_format[] = {
385
    #define PM_TEXT_ONELINE 1
386
    { 1, "PM_TEXT_ONELINE" },
387
    #define PM_TEXT_HELP    2
388
    { 2, "PM_TEXT_HELP" },
389
    { 0, NULL }
390
};
391
392
static const value_string packettypenames_text_type_ident[] = {
393
0
    #define PM_TEXT_PMID    4
394
    { 1, "PM_TEXT_PMID" },
395
0
    #define PM_TEXT_INDOM   8
396
    { 2, "PM_TEXT_INDOM" },
397
    { 0, NULL }
398
};
399
400
static const value_string packettypenames_valfmt[] = {
401
0
    #define PM_VAL_INSITU   0
402
    { 0, "PM_VAL_INSITU" },
403
    #define PM_VAL_DPTR 1
404
    { 1, "PM_VAL_DPTR" },
405
    #define PM_VAL_SPTR 2
406
    { 2, "PM_VAL_SPTR" },
407
    { 0, NULL }
408
};
409
410
static const value_string packettypenames_errors[] = {
411
    { -12345, "PM_ERR_GENERIC" },
412
    { -12346, "PM_ERR_PMNS" },
413
    { -12347, "PM_ERR_NOPMNS" },
414
    { -12348, "PM_ERR_DUPPMNS" },
415
    { -12349, "PM_ERR_TEXT" },
416
    { -12350, "PM_ERR_APPVERSION" },
417
    { -12351, "PM_ERR_VALUE" },
418
    { -12352, "PM_ERR_LICENSE" },
419
    { -12353, "PM_ERR_TIMEOUT" },
420
    { -12354, "PM_ERR_NODATA" },
421
    { -12355, "PM_ERR_RESET" },
422
    { -12356, "PM_ERR_FILE" },
423
    { PM_ERR_NAME, "PM_ERR_NAME" },
424
    { -12358, "PM_ERR_PMID" },
425
    { -12359, "PM_ERR_INDOM" },
426
    { -12360, "PM_ERR_INST" },
427
    { -12361, "PM_ERR_UNIT" },
428
    { -12362, "PM_ERR_CONV" },
429
    { -12363, "PM_ERR_TRUNC" },
430
    { -12364, "PM_ERR_SIGN" },
431
    { -12365, "PM_ERR_PROFILE" },
432
    { -12366, "PM_ERR_IPC" },
433
    { -12367, "PM_ERR_NOASCII" },
434
    { -12368, "PM_ERR_EOF" },
435
    { -12369, "PM_ERR_NOTHOST" },
436
    { -12370, "PM_ERR_EOL" },
437
    { -12371, "PM_ERR_MODE" },
438
    { -12372, "PM_ERR_LABEL" },
439
    { -12373, "PM_ERR_LOGREC" },
440
    { -12374, "PM_ERR_NOTARCHIVE" },
441
    { -12375, "PM_ERR_LOGFILE" },
442
    { -12376, "PM_ERR_NOCONTEXT" },
443
    { -12377, "PM_ERR_PROFILESPEC" },
444
    { -12378, "PM_ERR_PMID_LOG" },
445
    { -12379, "PM_ERR_INDOM_LOG" },
446
    { -12380, "PM_ERR_INST_LOG" },
447
    { -12381, "PM_ERR_NOPROFILE" },
448
    { -12386, "PM_ERR_NOAGENT" },
449
    { -12387, "PM_ERR_PERMISSION" },
450
    { -12388, "PM_ERR_CONNLIMIT" },
451
    { -12389, "PM_ERR_AGAIN" },
452
    { -12390, "PM_ERR_ISCONN" },
453
    { -12391, "PM_ERR_NOTCONN" },
454
    { -12392, "PM_ERR_NEEDPORT" },
455
    { -12393, "PM_ERR_WANTACK" },
456
    { -12394, "PM_ERR_NONLEAF" },
457
    { -12395, "PM_ERR_OBJSTYLE" },
458
    { -12396, "PM_ERR_PMCDLICENSE" },
459
    { -12397, "PM_ERR_TYPE" },
460
    { -12442, "PM_ERR_CTXBUSY" },
461
    { -12443, "PM_ERR_TOOSMALL" },
462
    { -12444, "PM_ERR_TOOBIG" },
463
    { -13393, "PM_ERR_PMDAREADY" },
464
    { -13394, "PM_ERR_PMDANOTREADY" },
465
    { -21344, "PM_ERR_NYI" },
466
    {      0, NULL }
467
};
468
469
static const value_string packettypenames_creds[]= {
470
    { 1, "CVERSION" },
471
    { 2, "CAUTH" },
472
    { 0, NULL }
473
};
474
475
static const value_string packettypenames_label_req_type[]= {
476
    { 1,  "PM_LABEL_CONTEXT" },
477
    { 2,  "PM_LABEL_DOMAIN" },
478
    { 4,  "PM_LABEL_INDOM" },
479
    { 8,  "PM_LABEL_CLUSTER" },
480
    { 16, "PM_LABEL_ITEM" },
481
    { 32, "PM_LABEL_INSTANCES" },
482
    { 0,  NULL }
483
};
484
485
typedef struct pcp_conv_info_t {
486
    wmem_array_t *pmid_name_candidates;
487
    wmem_map_t *pmid_to_name;
488
    uint32_t last_pmns_names_frame;
489
    uint32_t last_processed_pmns_names_frame;
490
    bool using_good_labels;
491
} pcp_conv_info_t;
492
493
/* function prototypes */
494
static pcp_conv_info_t* get_pcp_conversation_info(packet_info *pinfo);
495
static int is_unvisited_pmns_names_frame(packet_info *pinfo);
496
static bool is_using_good_labels(packet_info *pinfo);
497
static bool label_value_length_looks_like_wrong_endianness(tvbuff_t *tvb, uint16_t value_offset, uint16_t value_length);
498
static void add_candidate_name_for_pmid_resolution(packet_info *pinfo, tvbuff_t *tvb, int offset, int name_len);
499
static void mark_this_frame_as_last_pmns_names_frame(packet_info *pinfo);
500
static inline int has_unprocessed_pmns_names_frame(pcp_conv_info_t *pcp_conv_info);
501
static void create_pmid_to_name_map_from_candidates(pcp_conv_info_t *pcp_conv_info, tvbuff_t *tvb, int offset, uint32_t num_ids);
502
static void populate_pmids_to_names(packet_info *pinfo, tvbuff_t *tvb, int offset, uint32_t num_ids);
503
static inline int client_to_server(packet_info *pinfo);
504
static inline int server_to_client(packet_info *pinfo);
505
static uint8_t* get_name_from_pmid(uint32_t pmid, packet_info *pinfo);
506
static unsigned get_pcp_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data);
507
static const char *get_pcp_features_to_string(wmem_allocator_t *pool, uint16_t feature_flags);
508
static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
509
static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
510
static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
511
static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
512
static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
513
static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
514
static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
515
static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
516
static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
517
static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
518
static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
519
static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
520
static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
521
static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
522
static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
523
static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
524
static int dissect_pcp_message_user_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
525
static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
526
static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
527
static int dissect_pcp_partial_features(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
528
static int dissect_pcp_partial_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint32_t json_start_offset);
529
static int dissect_pcp_partial_labelset(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset);
530
531
/* message length for dissect_tcp */
532
static unsigned get_pcp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
533
                                 int offset, void *data _U_)
534
0
{
535
    /* length is at the very start of the packet, after tcp header */
536
0
    return (unsigned)tvb_get_ntohl(tvb, offset);
537
0
}
538
539
0
static void mark_this_frame_as_last_pmns_names_frame(packet_info *pinfo) {
540
0
    pcp_conv_info_t *pcp_conv_info;
541
0
    pcp_conv_info = get_pcp_conversation_info(pinfo);
542
543
0
    if(pinfo->num > pcp_conv_info->last_pmns_names_frame) {
544
0
        pcp_conv_info->last_pmns_names_frame = pinfo->num;
545
0
    }
546
0
}
547
548
0
static inline int has_unprocessed_pmns_names_frame(pcp_conv_info_t *pcp_conv_info) {
549
0
    return pcp_conv_info->last_pmns_names_frame > pcp_conv_info->last_processed_pmns_names_frame;
550
0
}
551
552
0
static inline int client_to_server(packet_info *pinfo) {
553
0
    return pinfo->destport == PCP_PORT || pinfo->destport == PMPROXY_PORT;
554
0
}
555
556
0
static inline int server_to_client(packet_info *pinfo) {
557
0
    return !client_to_server(pinfo);
558
0
}
559
560
0
static uint8_t* get_name_from_pmid(uint32_t pmid, packet_info *pinfo) {
561
0
    uint8_t *name;
562
0
    wmem_map_t *pmid_to_name;
563
564
0
    pmid_to_name = get_pcp_conversation_info(pinfo)->pmid_to_name;
565
566
0
    name = (uint8_t*)wmem_map_lookup(pmid_to_name, GINT_TO_POINTER(pmid));
567
0
    if(!name) {
568
0
        name = (uint8_t*)wmem_strdup(pinfo->pool, "Metric name unknown");
569
0
    }
570
571
0
    return name;
572
0
}
573
574
static const char *get_pcp_features_to_string(wmem_allocator_t *pool, uint16_t feature_flags)
575
0
{
576
0
    const value_string *flag_under_test;
577
0
    wmem_strbuf_t *string_buffer;
578
0
    size_t string_length;
579
580
0
    string_buffer = wmem_strbuf_new(pool, "");
581
582
    /* Build the comma-separated list of feature flags as a string. EG 'SECURE, COMPRESS, AUTH, ' */
583
0
    flag_under_test = &pcp_feature_flags[0];
584
0
    while (flag_under_test->value) {
585
0
        if (feature_flags & flag_under_test->value) {
586
0
            wmem_strbuf_append_printf(string_buffer, "%s, ", flag_under_test->strptr);
587
0
        }
588
0
        flag_under_test++;
589
0
    }
590
591
    /* Cleanup the last remaining ', ' from the string */
592
0
    string_length = wmem_strbuf_get_len(string_buffer);
593
0
    if (string_length > 2) {
594
0
        wmem_strbuf_truncate(string_buffer, string_length - 2);
595
0
    }
596
597
0
    return wmem_strbuf_get_str(string_buffer);
598
0
}
599
600
0
static pcp_conv_info_t* get_pcp_conversation_info(packet_info *pinfo) {
601
0
    conversation_t  *conversation;
602
0
    pcp_conv_info_t *pcp_conv_info;
603
604
0
    conversation = find_conversation_pinfo(pinfo, 0);
605
606
    /* Conversation setup is done in the main dissecting routine so it should never be null */
607
0
    DISSECTOR_ASSERT(conversation);
608
609
0
    pcp_conv_info = (pcp_conv_info_t *)conversation_get_proto_data(conversation, proto_pcp);
610
611
    /* Conversation data is initialized when creating the conversation so should never be null */
612
0
    DISSECTOR_ASSERT(pcp_conv_info);
613
614
0
    return pcp_conv_info;
615
0
}
616
617
0
static void add_candidate_name_for_pmid_resolution(packet_info *pinfo, tvbuff_t *tvb, int offset, int name_len) {
618
0
    pcp_conv_info_t *pcp_conv_info;
619
0
    uint8_t *name;
620
621
0
    pcp_conv_info = get_pcp_conversation_info(pinfo);
622
623
0
    if(is_unvisited_pmns_names_frame(pinfo)) {
624
0
        name = tvb_get_string_enc(wmem_file_scope(), tvb, offset, name_len, ENC_ASCII);
625
0
        wmem_array_append_one(pcp_conv_info->pmid_name_candidates, name);
626
0
    }
627
0
}
628
629
0
static int is_unvisited_pmns_names_frame(packet_info *pinfo) {
630
0
    pcp_conv_info_t *pcp_conv_info;
631
632
0
    pcp_conv_info = get_pcp_conversation_info(pinfo);
633
634
0
    return pinfo->num > pcp_conv_info->last_processed_pmns_names_frame && pinfo->num > pcp_conv_info->last_pmns_names_frame;
635
0
}
636
637
0
static void populate_pmids_to_names(packet_info *pinfo, tvbuff_t *tvb, int offset, uint32_t num_ids) {
638
0
    pcp_conv_info_t *pcp_conv_info;
639
0
    unsigned number_of_name_candidates;
640
641
0
    pcp_conv_info = get_pcp_conversation_info(pinfo);
642
0
    number_of_name_candidates = wmem_array_get_count(pcp_conv_info->pmid_name_candidates);
643
644
0
    if(number_of_name_candidates == num_ids && has_unprocessed_pmns_names_frame(pcp_conv_info)) {
645
0
        create_pmid_to_name_map_from_candidates(pcp_conv_info, tvb, offset, num_ids);
646
        /* Set this frame to the one that we processed */
647
0
        pcp_conv_info->last_processed_pmns_names_frame = pcp_conv_info->last_pmns_names_frame;
648
0
    }
649
650
0
    pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
651
0
}
652
653
0
static void create_pmid_to_name_map_from_candidates(pcp_conv_info_t *pcp_conv_info, tvbuff_t *tvb, int offset, uint32_t num_ids) {
654
0
    uint32_t i;
655
656
0
    for(i=0; i<num_ids; i++) {
657
0
        uint32_t pmid;
658
0
        uint8_t *pmid_name;
659
660
0
        pmid = tvb_get_ntohl(tvb, offset);
661
0
        pmid_name = *(uint8_t **)wmem_array_index(pcp_conv_info->pmid_name_candidates, i);
662
663
0
        if(wmem_map_lookup(pcp_conv_info->pmid_to_name, GINT_TO_POINTER(pmid)) == NULL) {
664
0
            wmem_map_insert(pcp_conv_info->pmid_to_name, GINT_TO_POINTER(pmid), pmid_name);
665
0
        }
666
0
        offset += 4;
667
0
    }
668
0
}
669
670
static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
671
0
{
672
0
    uint32_t creds_length;
673
0
    uint32_t i;
674
675
    /* append the type of packet */
676
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
677
0
                    val_to_str(PCP_PDU_CREDS, packettypenames, "Unknown Type:0x%02x"));
678
679
    /* first is the number of creds */
680
0
    proto_tree_add_item(tree, hf_pcp_creds_number_of, tvb, offset, 4, ENC_BIG_ENDIAN);
681
    /* store the number of creds so we know how long to interate for */
682
0
    creds_length = tvb_get_ntohl(tvb, offset);
683
0
    offset += 4;
684
    /* go through each __pmVersionCred struct */
685
0
    for (i = 0; i < creds_length; i++) {
686
        /* __pmVersionCred.c_type */
687
0
        proto_tree_add_item(tree, hf_pcp_creds_type, tvb, offset, 1, ENC_BIG_ENDIAN);
688
0
        offset += 1;
689
        /* __pmVersionCred.c_version */
690
0
        proto_tree_add_item(tree, hf_pcp_creds_version, tvb, offset, 1, ENC_BIG_ENDIAN);
691
0
        offset += 1;
692
        /* __pmVersionCred.c_flags */
693
0
        offset = dissect_pcp_partial_features(tvb, pinfo, tree, offset);
694
0
    }
695
0
    return offset;
696
0
}
697
698
/* ERROR packet format:
699
    signed int error
700
 */
701
static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
702
0
{
703
0
    int32_t error_num;
704
0
    pcp_conv_info_t *pcp_conv_info;
705
706
    /* append the type of packet, we can't look this up as it clashes with START */
707
0
    col_append_str(pinfo->cinfo, COL_INFO, "[ERROR] ");
708
709
    /* add the error item to the tree and column */
710
0
    proto_tree_add_item(tree, hf_pcp_pdu_error, tvb, offset, 4, ENC_BIG_ENDIAN);
711
0
    error_num = tvb_get_ntohl(tvb, offset);
712
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "error=%s ",
713
0
                    val_to_str(error_num, packettypenames_errors, "Unknown Error:%i"));
714
0
    offset += 4;
715
716
    /* Clean out candidate names if we got an error from a PMNS_NAMES lookup. This will allow subsequent PMNS_NAMES
717
       lookups to work in the same conversation
718
     */
719
0
    if(error_num == PM_ERR_NAME) {
720
0
        pcp_conv_info = get_pcp_conversation_info(pinfo);
721
0
        pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
722
0
    }
723
724
0
    return offset;
725
0
}
726
727
/* START packet format:
728
    unsigned int    sts,
729
    struct          __pmPDUInfo
730
     |
731
     |> unsigned int    zero : 1 bit
732
        unsigned int    version : 7 bits
733
        unsigned int    licensed : 8 bits
734
        unsigned int    features : 16 bits
735
*/
736
static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
737
0
{
738
    /* create a start tree to hold the information*/
739
0
    proto_item *pcp_start_item;
740
0
    proto_tree *pcp_start_tree;
741
0
    uint32_t    status;
742
743
0
    pcp_start_item = proto_tree_add_item(tree, hf_pcp_start, tvb, 0, -1, ENC_NA);
744
0
    pcp_start_tree = proto_item_add_subtree(pcp_start_item, ett_pcp);
745
746
    /* append the type of packet, we can't look this up as it clashes with ERROR */
747
0
    col_append_str(pinfo->cinfo, COL_INFO, "[START]");
748
749
    /* status */
750
0
    status = tvb_get_ntohl(tvb, offset);
751
0
    proto_tree_add_item(pcp_start_tree, hf_pcp_start_status, tvb, offset, 4, ENC_BIG_ENDIAN);
752
0
    offset += 4;
753
0
    if(tvb_reported_length_remaining(tvb, offset) == 0){
754
        /* Most likely we're in a SSL upgrade if this is the end of the start packet */
755
0
        if(status == PCP_SECURE_ACK_SUCCESSFUL) {
756
0
            expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade);
757
0
            ssl_starttls_ack(find_dissector("tls"), pinfo, pcp_handle);
758
0
        }
759
0
        else {
760
0
            expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade_failed);
761
0
        }
762
0
    }
763
0
    else {
764
        /* zero bit and version bits */
765
0
        proto_tree_add_item(pcp_start_tree, hf_pcp_start_zero, tvb, offset, 1, ENC_BIG_ENDIAN);
766
0
        proto_tree_add_item(pcp_start_tree, hf_pcp_start_version, tvb, offset, 1, ENC_BIG_ENDIAN);
767
0
        offset += 1;
768
        /* licensed */
769
0
        proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN);
770
0
        offset += 1;
771
        /* features */
772
0
        offset = dissect_pcp_partial_features(tvb, pinfo, pcp_start_tree, offset);
773
0
    }
774
0
    return offset;
775
0
}
776
777
/* PMNS_TRAVERSE packet format:
778
    uint32_t subtype
779
    uint32_t namelen
780
    char name[sizeof(namelen)] + padding
781
*/
782
static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
783
0
{
784
0
    proto_item *pcp_pmns_traverse_item;
785
0
    proto_tree *pcp_pmns_traverse_tree;
786
0
    uint32_t    name_len;
787
0
    uint32_t    padding;
788
789
    /* append the type of packet */
790
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
791
0
                    val_to_str(PCP_PDU_PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x"));
792
793
0
    pcp_pmns_traverse_item = proto_tree_add_item(tree, hf_pcp_pmns_traverse, tvb, offset, -1, ENC_NA);
794
0
    pcp_pmns_traverse_tree = proto_item_add_subtree(pcp_pmns_traverse_item, ett_pcp);
795
796
    /* subtype */
797
0
    proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
798
0
    offset += 4;
799
    /* namelen */
800
0
    proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
801
0
    name_len = tvb_get_ntohl(tvb, offset); /* get the actual length out so we can use it in the next item */
802
0
    offset += 4;
803
    /* name */
804
0
    proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII);
805
0
    offset += name_len; /* increment by whatever the length of the name string was */
806
807
    /* "padding" (not really padding, just what is left over in the old buffer) */
808
0
    padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
809
0
    if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
810
0
        padding = 4 - padding; /* we want the inverse of the remainder */
811
812
0
        proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
813
0
        offset += padding;
814
0
    }
815
0
    return offset;
816
0
}
817
818
/* PMNS_NAMES packet format:
819
    uint32_t    nstrbytes (number of str bytes)
820
    uint32_t    numstatus (0 if no status. Also, if 0, use name_t, otherwise use name_status_t )
821
    uint32_t    numnames
822
    __pmPDU     names (if numstatus = 0, filled with name_t, otherwise name_status_t)
823
    | |
824
    | |> -- name_t --
825
    |    int namelen
826
    |    char name[sizeof(namelen)]
827
    |
828
    |>  -- name_status_t --
829
        int status
830
        int namelen
831
        char name[sizeof(namelen)]
832
*/
833
static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
834
0
{
835
0
    proto_item *pcp_pmns_names_item;
836
0
    proto_tree *pcp_pmns_names_tree;
837
0
    proto_item *pcp_pmns_names_name_item;
838
0
    proto_tree *pcp_pmns_names_name_tree;
839
0
    uint32_t    is_pmns_names_status;
840
0
    uint32_t    num_names;
841
0
    uint32_t    name_len;
842
0
    uint32_t    full_name_len;
843
0
    uint32_t    padding;
844
0
    uint32_t    i;
845
846
    /* append the type of packet */
847
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_NAMES, packettypenames, "Unknown Type:0x%02x"));
848
849
0
    pcp_pmns_names_item = proto_tree_add_item(tree, hf_pcp_pmns_names, tvb, offset, -1, ENC_NA);
850
0
    pcp_pmns_names_tree = proto_item_add_subtree(pcp_pmns_names_item, ett_pcp);
851
852
    /* nstrbytes */
853
0
    proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nstrbytes, tvb, offset, 4, ENC_BIG_ENDIAN);
854
0
    offset += 4;
855
856
    /* numstatus */
857
0
    proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numstatus, tvb, offset, 4, ENC_BIG_ENDIAN);
858
0
    is_pmns_names_status = tvb_get_ntohl(tvb, offset); /* is the status also present in this PDU? */
859
0
    offset += 4;
860
861
    /* numnames */
862
0
    proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numnames, tvb, offset, 4, ENC_BIG_ENDIAN);
863
0
    num_names = tvb_get_ntohl(tvb, offset); /* get the number of names to iterate through */
864
0
    offset += 4;
865
866
    /* nametrees */
867
0
    for (i=0; i < num_names; i++) {
868
        /* find out the size of the name_t/name_status_t before we create the tree */
869
0
        if (is_pmns_names_status) {
870
0
            name_len = tvb_get_ntohl(tvb, offset+4);
871
0
            full_name_len = name_len + 8;
872
0
        } else {
873
0
            name_len = tvb_get_ntohl(tvb, offset);
874
0
            full_name_len = name_len + 4;
875
0
        }
876
        /* add a new subtree for each name */
877
0
        pcp_pmns_names_name_item = proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nametree,
878
0
                                                       tvb, offset, full_name_len, ENC_NA);
879
0
        pcp_pmns_names_name_tree = proto_item_add_subtree(pcp_pmns_names_name_item, ett_pcp);
880
881
0
        if (is_pmns_names_status) {
882
            /* print out the name status and increment if we're supposed to have it */
883
0
            proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_status,
884
0
                                tvb, offset, 4, ENC_BIG_ENDIAN);
885
0
            offset += 4;
886
0
        }
887
        /* namelen */
888
0
        proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_namelen,
889
0
                            tvb, offset, 4, ENC_BIG_ENDIAN);
890
0
        offset += 4;
891
        /* name */
892
0
        if(client_to_server(pinfo)) {
893
0
            add_candidate_name_for_pmid_resolution(pinfo, tvb, offset, name_len);
894
0
        }
895
0
        proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_name,
896
0
                            tvb, offset, name_len, ENC_ASCII);
897
0
        offset += name_len;
898
        /* padding */
899
0
        padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
900
0
        if (padding != 0) {
901
0
            padding = 4 - padding; /* we want the inverse of the remainder */
902
            /* if there is padding, keep going till the remainder of mod 8 */
903
0
            proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
904
0
            offset += padding;
905
0
        }
906
0
    }
907
0
    if(client_to_server(pinfo)) {
908
0
        mark_this_frame_as_last_pmns_names_frame(pinfo);
909
0
    }
910
0
    return offset;
911
0
}
912
913
/* PMNS_CHILD packet format:
914
    uint32_t subtype
915
    uint32_t namelen
916
    char name[namelen]
917
*/
918
static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
919
0
{
920
0
    proto_item *pcp_pmns_child_item;
921
0
    proto_tree *pcp_pmns_child_tree;
922
0
    uint32_t    name_len;
923
924
0
    pcp_pmns_child_item = proto_tree_add_item(tree, hf_pcp_pmns_child, tvb, offset, -1, ENC_NA);
925
0
    pcp_pmns_child_tree = proto_item_add_subtree(pcp_pmns_child_item, ett_pcp);
926
927
    /* append the type of packet */
928
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_CHILD, packettypenames, "Unknown Type:0x%02x"));
929
930
    /* subtype */
931
0
    proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
932
0
    offset += 4;
933
934
    /* namelen */
935
0
    proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
936
0
    name_len = tvb_get_ntohl(tvb, offset); /* length of the next value */
937
0
    offset += 4;
938
939
    /* name */
940
0
    proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII);
941
0
    offset += 4;
942
0
    return offset;
943
0
}
944
945
/* PMNS_IDS packet format
946
    uint32_t status
947
    uint32_t numids
948
    pmID    idlist[numids] (where pmID = uint32)
949
950
*/
951
static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
952
0
{
953
0
    proto_item *pcp_pmns_ids_item;
954
0
    proto_tree *pcp_pmns_ids_tree;
955
0
    uint32_t    num_ids;
956
0
    uint32_t    i;
957
958
    /* append the type of packet */
959
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
960
0
                    val_to_str(PCP_PDU_PMNS_IDS, packettypenames, "Unknown Type:0x%02x"));
961
962
0
    pcp_pmns_ids_item = proto_tree_add_item(tree, hf_pcp_pmns_ids, tvb, offset, -1, ENC_NA);
963
0
    pcp_pmns_ids_tree = proto_item_add_subtree(pcp_pmns_ids_item, ett_pcp);
964
965
    /* status */
966
0
    proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_status, tvb, offset, 4, ENC_BIG_ENDIAN);
967
0
    offset += 4;
968
969
    /* numids */
970
0
    proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_numids, tvb, offset, 4, ENC_BIG_ENDIAN);
971
0
    num_ids = tvb_get_ntohl(tvb, offset);
972
0
    offset += 4;
973
974
    /* Populate the PMID to name mapping */
975
0
    populate_pmids_to_names(pinfo, tvb, offset, num_ids);
976
977
    /* pmIDs */
978
0
    for (i=0; i<num_ids; i++) {
979
        /* pmID */
980
0
        offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_pmns_ids_tree, offset);
981
0
    }
982
0
    return offset;
983
0
}
984
985
/*  PROFILE packet format
986
    uint32_t    ctxnum;
987
    uint32_t    g_state;
988
    uint32_t    numprof;
989
    uint32_t    pad;
990
    pmProfile   profiles[numprof]
991
      |
992
      |> pmInDom indom;
993
         int     state;
994
         int     numinst;
995
         int     pad;
996
*/
997
static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
998
0
{
999
0
    proto_item *pcp_profile_item;
1000
0
    proto_tree *pcp_profile_tree;
1001
0
    proto_item *pcp_profile_profile_item;
1002
0
    proto_tree *pcp_profile_profile_tree;
1003
0
    uint32_t    num_prof;
1004
0
    uint32_t    i;
1005
1006
    /* append the type of packet */
1007
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PROFILE, packettypenames, "Unknown Type:0x%02x"));
1008
1009
0
    pcp_profile_item = proto_tree_add_item(tree, hf_pcp_profile, tvb, offset, -1, ENC_NA);
1010
0
    pcp_profile_tree = proto_item_add_subtree(pcp_profile_item, ett_pcp);
1011
1012
    /* ctxnum */
1013
0
    proto_tree_add_item(pcp_profile_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
1014
0
    offset += 4;
1015
1016
    /* g_state */
1017
0
    proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_g_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1018
0
    offset += 4;
1019
1020
    /* numprof */
1021
0
    proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_numprof, tvb, offset, 4, ENC_BIG_ENDIAN);
1022
0
    num_prof = tvb_get_ntohl(tvb, offset);
1023
0
    offset += 4;
1024
1025
    /* pad */
1026
0
    proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
1027
0
    offset += 4;
1028
1029
    /* iterate through each profile */
1030
0
    for (i=0; i<num_prof; i++) {
1031
        /* subtree for each profile */
1032
0
        pcp_profile_profile_item = proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_profile, tvb, offset, 32, ENC_NA);
1033
0
        pcp_profile_profile_tree = proto_item_add_subtree(pcp_profile_profile_item, ett_pcp);
1034
1035
        /* indom */
1036
0
        proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1037
0
        offset += 4;
1038
1039
        /* state - include/exclude */
1040
0
        proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1041
0
        offset += 4;
1042
1043
        /* numinst - number of instances to follow */
1044
0
        proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
1045
0
        offset += 4;
1046
1047
        /* padding */
1048
0
        proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
1049
0
        offset += 4;
1050
0
    }
1051
0
    return offset;
1052
0
}
1053
1054
/*  FETCH packet format
1055
    uint32_t        cxtnum
1056
    __pmTimeval     when (unsigned int tv_sec, unsigned int tv_usec)
1057
    uint32_t        numpmid
1058
    pmID            pmidlist[1-x] (unsigned int)
1059
 */
1060
static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1061
0
{
1062
0
    proto_item *pcp_fetch_item;
1063
0
    proto_tree *pcp_fetch_tree;
1064
0
    uint32_t    num_pmid;
1065
0
    uint32_t    i;
1066
1067
    /* append the type of packet */
1068
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
1069
0
                    val_to_str(PCP_PDU_FETCH, packettypenames, "Unknown Type:0x%02x"));
1070
1071
0
    pcp_fetch_item = proto_tree_add_item(tree, hf_pcp_fetch, tvb, offset, -1, ENC_NA);
1072
0
    pcp_fetch_tree = proto_item_add_subtree(pcp_fetch_item, ett_pcp);
1073
1074
    /* ctxnum */
1075
0
    proto_tree_add_item(pcp_fetch_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
1076
0
    offset += 4;
1077
1078
    /* when */
1079
0
    offset = dissect_pcp_partial_when(tvb, pinfo, pcp_fetch_tree, offset);
1080
1081
    /* numpmid */
1082
0
    proto_tree_add_item(pcp_fetch_tree, hf_pcp_fetch_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1083
0
    num_pmid = tvb_get_ntohl(tvb, offset);
1084
0
    offset += 4;
1085
1086
    /* pmIDs*/
1087
0
    for (i=0; i<num_pmid; i++) {
1088
        /* decode partial PMID message */
1089
0
        offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_fetch_tree, offset);
1090
0
    }
1091
0
    return offset;
1092
0
}
1093
1094
/* RESULT packet format
1095
1096
    __pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
1097
    int         numpmid
1098
    _pmPDU      data[1-n] (contains v_list types)
1099
      |
1100
      |> pmID           pmid
1101
         int            numval
1102
         int            valfmt
1103
        __pmValue_PDU   vlist[1-n] (contains pmValue PDUs)
1104
          |
1105
          |> int    inst
1106
             int    offset/value
1107
             (if valfmt == PTR type)
1108
             int8   type
1109
             int24  length
1110
             char   value[length]
1111
*/
1112
static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1113
0
{
1114
0
    proto_item *pcp_results_item;
1115
0
    proto_tree *pcp_results_tree;
1116
0
    proto_item *pcp_result_item;
1117
0
    proto_tree *pcp_result_tree;
1118
0
    proto_item *pcp_result_instance_item;
1119
0
    proto_tree *pcp_result_instance_tree;
1120
0
    uint32_t    num_pmid;
1121
0
    uint32_t    num_val;
1122
0
    uint32_t    offset_start;
1123
0
    uint32_t    valfmt_type;
1124
0
    uint32_t    value_type;
1125
0
    uint32_t    pmvalueblock_offset;
1126
0
    uint32_t    pmvalueblock_value_length;
1127
0
    uint32_t    i;
1128
0
    uint32_t    j;
1129
1130
    /* append the type of packet */
1131
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_RESULT, packettypenames, "Unknown Type:0x%02x"));
1132
1133
0
    pcp_results_item = proto_tree_add_item(tree, hf_pcp_results, tvb, offset, -1, ENC_NA);
1134
0
    pcp_results_tree = proto_item_add_subtree(pcp_results_item, ett_pcp);
1135
1136
    /* when */
1137
0
    offset = dissect_pcp_partial_when(tvb, pinfo, pcp_results_tree, offset);
1138
1139
    /* numpmid */
1140
0
    proto_tree_add_item(pcp_results_tree, hf_pcp_results_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1141
0
    num_pmid = tvb_get_ntohl(tvb, offset);
1142
0
    offset += 4;
1143
1144
    /* result */
1145
0
    for (i=0; i<num_pmid; i++) {
1146
        /* work out how long each result should be - set starting offset */
1147
0
        offset_start = offset;
1148
1149
0
        pcp_result_item = proto_tree_add_item(pcp_results_tree, hf_pcp_result, tvb, offset, -1, ENC_NA);
1150
0
        pcp_result_tree = proto_item_add_subtree(pcp_result_item, ett_pcp);
1151
1152
        /* pmID */
1153
0
        offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_result_tree, offset);
1154
1155
        /* numval */
1156
0
        proto_tree_add_item(pcp_result_tree, hf_pcp_result_numval, tvb, offset, 4, ENC_BIG_ENDIAN);
1157
0
        num_val = tvb_get_ntohl(tvb, offset);
1158
0
        offset += 4;
1159
1160
        /* if there are no numvals, then the valfmt isn't sent */
1161
0
        if (num_val > 0) {
1162
1163
            /* valfmt */
1164
0
            proto_tree_add_item(pcp_result_tree, hf_pcp_result_valfmt, tvb, offset, 4, ENC_BIG_ENDIAN);
1165
0
            valfmt_type = tvb_get_ntohl(tvb, offset);
1166
0
            offset += 4;
1167
1168
            /* instance */
1169
0
            for (j=0; j<num_val; j++) {
1170
                /* give the subtree name length of inst (int) + offset/va (int) */
1171
0
                pcp_result_instance_item = proto_tree_add_item(pcp_result_tree, hf_pcp_instance,
1172
0
                                                               tvb, offset, 8, ENC_NA);
1173
0
                pcp_result_instance_tree = proto_item_add_subtree(pcp_result_instance_item, ett_pcp);
1174
1175
                /* inst */
1176
0
                proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1177
0
                offset += 4;
1178
1179
                /* valoffset/value: depending on the format, the next 32 bits is the value _OR_ the offset to where
1180
                   the value is */
1181
0
                if (valfmt_type == PM_VAL_INSITU) {
1182
0
                    proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_insitu,
1183
0
                                        tvb, offset, 4, ENC_BIG_ENDIAN);
1184
0
                } else {
1185
                    /* offset in the packet to find pmValueBlock */
1186
0
                    proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_valoffset,
1187
0
                                        tvb, offset, 4, ENC_BIG_ENDIAN);
1188
                    /* get the offset (not the offset of the count we are at) but where we should look  */
1189
0
                    pmvalueblock_offset = tvb_get_ntohl(tvb, offset);
1190
0
                    pmvalueblock_offset = pmvalueblock_offset * 4; /* offset values are in 32bit units */
1191
1192
                    /* type */
1193
0
                    value_type = tvb_get_uint8(tvb, pmvalueblock_offset);
1194
0
                    proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_type,
1195
0
                                        tvb, pmvalueblock_offset, 1, ENC_BIG_ENDIAN);
1196
0
                    pmvalueblock_offset += 1;
1197
1198
                    /* length */
1199
0
                    pmvalueblock_value_length = tvb_get_ntoh24(tvb, pmvalueblock_offset);
1200
                    /* can't add a tree item the ususal way as it is outside of the tree */
1201
0
                    proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_vallength,
1202
0
                                        tvb, pmvalueblock_offset, 3, ENC_BIG_ENDIAN);
1203
0
                    pmvalueblock_offset += 3;
1204
1205
                    /* value - note we go up to the pmvalueblock_value_length - 4,
1206
                       as this value includes the previous 4 bytes */
1207
0
                    switch (value_type) {
1208
0
                        case PM_TYPE_32:
1209
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int, tvb,
1210
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1211
0
                            break;
1212
0
                        case PM_TYPE_U32:
1213
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint, tvb,
1214
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1215
0
                            break;
1216
0
                        case PM_TYPE_64:
1217
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int64, tvb,
1218
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1219
0
                            break;
1220
0
                        case PM_TYPE_U64:
1221
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint64, tvb,
1222
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1223
0
                            break;
1224
0
                        case PM_TYPE_FLOAT:
1225
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_float, tvb,
1226
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1227
0
                            break;
1228
0
                        case PM_TYPE_DOUBLE:
1229
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_double, tvb,
1230
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1231
0
                            break;
1232
0
                        case PM_TYPE_STRING:
1233
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_ptr, tvb,
1234
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_ASCII);
1235
0
                            break;
1236
0
                        case PM_TYPE_AGGREGATE:
1237
0
                        case PM_TYPE_AGGREGATE_STATIC:
1238
0
                            proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_aggr, tvb,
1239
0
                                pmvalueblock_offset, pmvalueblock_value_length-4, ENC_NA);
1240
0
                            break;
1241
0
                        case PM_TYPE_EVENT:
1242
0
                            expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_event_unimplemented);
1243
0
                            break;
1244
0
                        case PM_TYPE_NOSUPPORT:
1245
0
                            expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_nosupport_unsupported);
1246
0
                            break;
1247
0
                        case PM_TYPE_UNKNOWN:
1248
0
                            expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_unknown_unknown_value);
1249
0
                            break;
1250
0
                        default:
1251
0
                            expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_unimplemented_value);
1252
0
                            break;
1253
0
                }
1254
0
            }
1255
        /* bump the offset after the instance value _or_ the offset into
1256
           the packet (pcp.instance.valoffset) , each being 4 bytes */
1257
0
        offset += 4;
1258
0
        }
1259
1260
0
        }
1261
        /* we now know how long the field is */
1262
0
        proto_item_set_len(pcp_result_tree, offset-offset_start);
1263
1264
0
    }
1265
0
    return offset;
1266
0
}
1267
1268
/*  DESC_REQ pcaket format
1269
    pmID    pmid (32bit int)
1270
*/
1271
static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1272
0
{
1273
0
    proto_item *pcp_desc_req_item;
1274
0
    proto_tree *pcp_desc_req_tree;
1275
1276
    /* append the type of packet */
1277
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC_REQ, packettypenames, "Unknown Type:0x%02x"));
1278
1279
    /* subtree for packet type */
1280
0
    pcp_desc_req_item = proto_tree_add_item(tree, hf_pcp_desc_req, tvb, offset, -1, ENC_NA);
1281
0
    pcp_desc_req_tree = proto_item_add_subtree(pcp_desc_req_item, ett_pcp);
1282
1283
0
    offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_req_tree, offset);
1284
1285
0
    return offset;
1286
0
}
1287
1288
/* DESC packet format
1289
    pmID        pmid
1290
    int         type (base data type)
1291
    pmInDom     indom
1292
    int         sem (semantics of the value: instant? counter? etc..)
1293
    pmUnits     units
1294
        |
1295
        v
1296
        signed  int     dimSpace : 4
1297
        signed  int     dimTime : 4
1298
        signed  int     dimCount : 4
1299
        unsigned int    scaleSpace : 4
1300
        unsigned int    scaleTime : 4
1301
        signed  int     scaleCount : 4
1302
        unsigned int    pad : 8
1303
*/
1304
static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1305
0
{
1306
0
    proto_item *pcp_desc_item;
1307
0
    proto_tree *pcp_desc_tree;
1308
0
    proto_item *pcp_desc_units_item;
1309
0
    proto_tree *pcp_desc_units_tree;
1310
0
    uint32_t    bits_offset;
1311
1312
    /* append the type of packet */
1313
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC, packettypenames, "Unknown Type:0x%02x"));
1314
1315
    /* root desc tree */
1316
0
    pcp_desc_item = proto_tree_add_item(tree, hf_pcp_desc, tvb, offset, 4, ENC_NA);
1317
0
    pcp_desc_tree = proto_item_add_subtree(pcp_desc_item, ett_pcp);
1318
1319
    /* pmID */
1320
0
    offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_tree, offset);
1321
1322
    /* type */
1323
0
    proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1324
0
    offset += 4;
1325
1326
    /* indom */
1327
0
    proto_tree_add_item(pcp_desc_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1328
0
    offset += 4;
1329
1330
    /* sem */
1331
0
    proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_sem, tvb, offset, 4, ENC_BIG_ENDIAN);
1332
0
    offset += 4;
1333
1334
    /* pmUnits */
1335
0
    bits_offset = offset*8; /* create the bits offset */
1336
0
    pcp_desc_units_item = proto_tree_add_item(pcp_desc_tree, hf_pcp_units, tvb, offset, -1, ENC_NA);
1337
0
    pcp_desc_units_tree = proto_item_add_subtree(pcp_desc_units_item, ett_pcp);
1338
1339
    /* dimspace */
1340
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimspace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1341
0
    bits_offset += 4;
1342
    /* dimtime  */
1343
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimtime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1344
0
    bits_offset += 4;
1345
    /* dimcount */
1346
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimcount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1347
0
    bits_offset += 4;
1348
    /* scalespace */
1349
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalespace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1350
0
    bits_offset += 4;
1351
    /* scaletime */
1352
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scaletime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1353
0
    bits_offset += 4;
1354
    /* scalecount */
1355
0
    proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalecount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1356
    /*bits_offset += 4;*/
1357
    /* padding */
1358
0
    offset  += 3; /* total offset of pmunits before */
1359
0
    proto_tree_add_item(pcp_desc_units_tree, hf_pcp_pdu_padding, tvb, offset, 1, ENC_NA);
1360
0
    offset  += 1;
1361
    /*bits_offset += 8;*/
1362
0
    return offset;
1363
1364
0
}
1365
1366
/* INSTANCE_REQ packet format
1367
     pmInDom        indom
1368
     __pmTimeval    when
1369
     int            inst
1370
     int            namelen
1371
     char           name
1372
*/
1373
static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1374
0
{
1375
0
    proto_item *pcp_instance_req_item;
1376
0
    proto_tree *pcp_instance_req_tree;
1377
0
    uint32_t    name_len;
1378
1379
    /* append the type of packet */
1380
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x"));
1381
1382
0
    pcp_instance_req_item = proto_tree_add_item(tree, hf_pcp_instance_req, tvb, offset, -1, ENC_NA);
1383
0
    pcp_instance_req_tree = proto_item_add_subtree(pcp_instance_req_item, ett_pcp);
1384
1385
    /* indom */
1386
0
    proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1387
0
    offset += 4;
1388
1389
    /* when */
1390
0
    offset = dissect_pcp_partial_when(tvb, pinfo, pcp_instance_req_tree, offset);
1391
1392
    /* inst */
1393
0
    proto_tree_add_item(pcp_instance_req_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1394
0
    offset += 4;
1395
1396
    /* namelen */
1397
0
    proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1398
0
    name_len = tvb_get_ntohl(tvb, offset);
1399
0
    offset += 4;
1400
1401
    /* name */
1402
0
    if (name_len > 0) {
1403
0
        proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII);
1404
0
        offset += name_len;
1405
0
    }
1406
0
    return offset;
1407
0
}
1408
1409
/* TEXT_REQ packet format
1410
     int            ident
1411
     int            type
1412
*/
1413
static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1414
0
{
1415
0
    proto_item *pcp_text_req_item;
1416
0
    proto_tree *pcp_text_req_tree;
1417
0
    proto_item *pcp_text_req_type_item;
1418
0
    proto_tree *pcp_text_req_type_tree;
1419
0
    uint32_t    bits_offset;
1420
0
    uint32_t    type;
1421
1422
    /* append the type of packet */
1423
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT_REQ, packettypenames, "Unknown Type:0x%02x"));
1424
1425
0
    pcp_text_req_item = proto_tree_add_item(tree, hf_pcp_text_req, tvb, offset, -1, ENC_NA);
1426
0
    pcp_text_req_tree = proto_item_add_subtree(pcp_text_req_item, ett_pcp);
1427
1428
    /* peek at type to decode ident correctly */
1429
0
    type = tvb_get_ntohl(tvb, offset + 4);
1430
1431
    /* ident */
1432
0
    if (type & PM_TEXT_PMID) {
1433
0
        offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_text_req_tree, offset);
1434
0
    } else if (type & PM_TEXT_INDOM) {
1435
0
        proto_tree_add_item(pcp_text_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1436
0
        offset += 4;
1437
0
    }
1438
1439
    /* type */
1440
0
    pcp_text_req_type_item = proto_tree_add_item(pcp_text_req_tree, hf_pcp_text_type, tvb, offset, 4, ENC_NA);
1441
0
    pcp_text_req_type_tree = proto_item_add_subtree(pcp_text_req_type_item, ett_pcp);
1442
0
    bits_offset = offset * 8 + 28;
1443
0
    proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_ident, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1444
0
    bits_offset += 2;
1445
0
    proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_format, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1446
1447
0
    offset += 4;
1448
0
    return offset;
1449
0
}
1450
1451
/* TEXT packet format
1452
     int            ident
1453
     int            buflen
1454
     char           buffer
1455
*/
1456
static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1457
0
{
1458
0
    proto_item *pcp_text_item;
1459
0
    proto_tree *pcp_text_tree;
1460
0
    uint32_t    buflen;
1461
1462
    /* append the type of packet */
1463
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT, packettypenames, "Unknown Type:0x%02x"));
1464
1465
0
    pcp_text_item = proto_tree_add_item(tree, hf_pcp_text, tvb, offset, -1, ENC_NA);
1466
0
    pcp_text_tree = proto_item_add_subtree(pcp_text_item, ett_pcp);
1467
1468
    /* ident */
1469
0
    proto_tree_add_item(pcp_text_tree, hf_pcp_text_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1470
0
    offset += 4;
1471
1472
    /* buflen */
1473
0
    buflen = tvb_get_ntohl(tvb, offset);
1474
0
    proto_tree_add_item(pcp_text_tree, hf_pcp_text_buflen, tvb, offset, 4, ENC_BIG_ENDIAN);
1475
0
    offset += 4;
1476
1477
    /* buffer */
1478
0
    proto_tree_add_item(pcp_text_tree, hf_pcp_text_buffer, tvb, offset, buflen, ENC_ASCII);
1479
0
    offset += buflen;
1480
1481
0
    return offset;
1482
0
}
1483
1484
/* USER_AUTH packet format
1485
     int            ident
1486
     int            buflen
1487
     char           buffer
1488
*/
1489
static int dissect_pcp_message_user_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1490
0
{
1491
    /* append the type of packet */
1492
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_USER_AUTH, packettypenames, "Unknown Type:0x%02x"));
1493
1494
0
    proto_tree_add_item(tree, hf_pcp_user_auth_payload, tvb, offset, -1, ENC_NA);
1495
1496
0
    return tvb_reported_length(tvb);
1497
0
}
1498
1499
/* LABEL_REQ packet format
1500
    int         ident
1501
    int         type
1502
*/
1503
static int dissect_pcp_message_label_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1504
0
{
1505
    /* append the type of packet */
1506
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_LABEL_REQ, packettypenames, "Unknown Type:0x%02x"));
1507
1508
0
    proto_item *pcp_label_req_item = proto_tree_add_item(tree, hf_pcp_label_req, tvb, offset, -1, ENC_NA);
1509
0
    proto_tree *pcp_label_req_tree = proto_item_add_subtree(pcp_label_req_item, ett_pcp);
1510
1511
    /* ident */
1512
0
    proto_tree_add_item(pcp_label_req_tree, hf_pcp_label_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1513
0
    offset += 4;
1514
1515
    /* type */
1516
0
    proto_tree_add_item(pcp_label_req_tree, hf_pcp_label_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1517
0
    offset += 4;
1518
1519
0
    return offset;
1520
0
}
1521
1522
/* LABEL packet format
1523
    int     ident
1524
    int     type
1525
    int     padding;
1526
    int     nsets;
1527
    labelset_t  sets[1];
1528
      |
1529
      |> int     inst
1530
         int     nlabels
1531
         int     json
1532
         int     jsonlen
1533
         pmLabel labels[0]
1534
*/
1535
static int dissect_pcp_message_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1536
0
{
1537
    /* append the type of packet */
1538
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_LABEL, packettypenames, "Unknown Type:0x%02x"));
1539
1540
0
    proto_item *pcp_label_item = proto_tree_add_item(tree, hf_pcp_label, tvb, offset, -1, ENC_NA);
1541
0
    proto_tree *pcp_label_tree = proto_item_add_subtree(pcp_label_item, ett_pcp);
1542
1543
    /* ident */
1544
0
    proto_tree_add_item(pcp_label_tree, hf_pcp_label_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1545
0
    offset += 4;
1546
1547
    /* type */
1548
0
    proto_tree_add_item(pcp_label_tree, hf_pcp_label_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1549
0
    offset += 4;
1550
1551
    /* padding */
1552
0
    proto_tree_add_item(pcp_label_tree, hf_pcp_label_padding, tvb, offset, 4, ENC_NA);
1553
0
    offset += 4;
1554
1555
    /* number of label sets */
1556
0
    int32_t nsets;
1557
0
    proto_tree_add_item_ret_int(pcp_label_tree, hf_pcp_label_nsets, tvb, offset, 4, ENC_NA, &nsets);
1558
0
    offset += 4;
1559
1560
1561
0
    for (int32_t i = 0; i < nsets; i++) {
1562
0
        offset = dissect_pcp_partial_labelset(tvb, pcp_label_tree, pinfo, offset);
1563
0
    }
1564
1565
0
    return offset;
1566
0
}
1567
1568
/* INSTANCE packet type
1569
 pmInDom    indom
1570
 int        numinst
1571
 instlist_t instlist[numinst]
1572
    |
1573
    |>  int         inst
1574
        int         namelen
1575
        char        name
1576
 */
1577
static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1578
0
{
1579
0
    proto_item *pcp_instances_item;
1580
0
    proto_tree *pcp_instances_tree;
1581
0
    proto_item *pcp_instance_item;
1582
0
    proto_tree *pcp_instance_tree;
1583
0
    uint32_t    num_inst;
1584
0
    uint32_t    i;
1585
0
    uint32_t    name_len;
1586
0
    uint32_t    padding;
1587
1588
    /* append the type of packet */
1589
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE, packettypenames, "Unknown Type:0x%02x"));
1590
1591
0
    pcp_instances_item = proto_tree_add_item(tree, hf_pcp_instances, tvb, offset, -1, ENC_NA);
1592
0
    pcp_instances_tree = proto_item_add_subtree(pcp_instances_item, ett_pcp);
1593
1594
    /* indom */
1595
0
    proto_tree_add_item(pcp_instances_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1596
0
    offset += 4;
1597
    /* numinst */
1598
0
    proto_tree_add_item(pcp_instances_tree, hf_pcp_instances_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
1599
0
    num_inst = tvb_get_ntohl(tvb, offset);
1600
0
    offset += 4;
1601
1602
    /* instlist */
1603
0
    for (i=0; i<num_inst; i++) {
1604
        /* get the size of the name first, so we know how much offset to give */
1605
0
        name_len = tvb_get_ntohl(tvb, offset+4);
1606
1607
        /* give the subtree name length + 2 ints */
1608
0
        pcp_instance_item = proto_tree_add_item(pcp_instances_tree, hf_pcp_instance, tvb, offset, name_len+8, ENC_NA);
1609
0
        pcp_instance_tree = proto_item_add_subtree(pcp_instance_item, ett_pcp);
1610
1611
        /* inst */
1612
0
        proto_tree_add_item(pcp_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1613
0
        offset += 4;
1614
1615
        /* namelen */
1616
0
        proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1617
0
        offset += 4;
1618
1619
        /* name */
1620
0
        if (name_len > 0) {
1621
0
            proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII);
1622
0
            offset += name_len;
1623
0
        }
1624
1625
        /* padding */
1626
0
        padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
1627
0
        if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
1628
0
            padding = 4 - padding; /* we want the inverse of the remainder */
1629
1630
0
            proto_tree_add_item(pcp_instance_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
1631
0
            offset += padding;
1632
0
        }
1633
0
    }
1634
0
    return offset;
1635
0
}
1636
1637
/* PARTIAL DISSECTOR ROUTINES
1638
   these routines are called by dissect_pcp_message_* as needed
1639
*/
1640
1641
static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1642
0
{
1643
0
    proto_item *pcp_pmid_item;
1644
0
    proto_tree *pcp_pmid_tree;
1645
0
    uint32_t    bits_offset;
1646
0
    uint32_t    pmid;
1647
0
    uint8_t    *name;
1648
1649
0
    bits_offset = offset * 8;
1650
1651
0
    pmid = tvb_get_ntohl(tvb, offset);
1652
0
    name = get_name_from_pmid(pmid, pinfo);
1653
1654
    /* subtree for pmid */
1655
0
    pcp_pmid_item = proto_tree_add_item(tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1656
0
    proto_item_append_text(pcp_pmid_item, " (%s)", name);
1657
0
    pcp_pmid_tree = proto_item_add_subtree(pcp_pmid_item, ett_pcp);
1658
1659
    /* flag - 1 bit */
1660
0
    proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
1661
0
    bits_offset += 1;
1662
    /* domain - 9 bits */
1663
0
    proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
1664
0
    bits_offset += 9;
1665
    /* cluster - 12 bits */
1666
0
    proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
1667
0
    bits_offset += 12;
1668
    /* item - 10 bits */
1669
0
    proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
1670
0
    offset += 4;
1671
1672
0
    return offset;
1673
0
}
1674
1675
static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1676
0
{
1677
0
    proto_item *pcp_when_item;
1678
0
    proto_tree *pcp_when_tree;
1679
1680
    /* when - create a new subtree for each val */
1681
0
    pcp_when_item = proto_tree_add_item(tree, hf_pcp_when, tvb, offset, 8, ENC_NA);
1682
0
    pcp_when_tree = proto_item_add_subtree(pcp_when_item, ett_pcp);
1683
1684
    /* when tv_sec */
1685
0
    proto_tree_add_item(pcp_when_tree, hf_pcp_when_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
1686
0
    offset += 4;
1687
    /* when tv_usec */
1688
0
    proto_tree_add_item(pcp_when_tree, hf_pcp_when_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
1689
0
    offset += 4;
1690
1691
0
    return offset;
1692
0
}
1693
1694
static int dissect_pcp_partial_features(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1695
0
{
1696
0
    uint16_t    feature_flags;
1697
0
    const char *feature_flags_string;
1698
1699
0
    static int * const pcp_feature_flags_header_fields[] = {
1700
0
            &hf_pcp_features_flags_labels,
1701
0
            &hf_pcp_features_flags_bad_label,
1702
0
            &hf_pcp_features_flags_cert_reqd,
1703
0
            &hf_pcp_features_flags_container,
1704
0
            &hf_pcp_features_flags_no_nss_init,
1705
0
            &hf_pcp_features_flags_secure_ack,
1706
0
            &hf_pcp_features_flags_creds_reqd,
1707
0
            &hf_pcp_features_flags_auth,
1708
0
            &hf_pcp_features_flags_compress,
1709
0
            &hf_pcp_features_flags_secure,
1710
0
            NULL
1711
0
    };
1712
1713
0
    feature_flags = tvb_get_ntohs(tvb, offset);
1714
0
    feature_flags_string = get_pcp_features_to_string(pinfo->pool, feature_flags);
1715
1716
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " Features=[%s]", feature_flags_string);
1717
1718
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_pcp_features_flags, ett_pcp_start_features, pcp_feature_flags_header_fields, ENC_BIG_ENDIAN);
1719
0
    offset += 2;
1720
1721
0
    if ((feature_flags & PCP_PDU_FLAG_LABELS) == PCP_PDU_FLAG_LABELS && server_to_client(pinfo)) {
1722
0
        pcp_conv_info_t *pcp_conv_info = get_pcp_conversation_info(pinfo);
1723
0
        pcp_conv_info->using_good_labels = true;
1724
0
    }
1725
1726
0
    return offset;
1727
0
}
1728
1729
static int dissect_pcp_partial_labelset(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1730
0
{
1731
0
    proto_item *pcp_label_sets_item = proto_tree_add_item(tree, hf_pcp_label_sets, tvb, offset, -1, ENC_NA);
1732
0
    proto_tree *pcp_label_sets_tree = proto_item_add_subtree(pcp_label_sets_item, ett_pcp);
1733
1734
    /* Instance */
1735
0
    proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1736
0
    offset += 4;
1737
1738
    /* Number of labels or error */
1739
0
    int32_t nlabels_or_error = tvb_get_ntohl(tvb, offset);
1740
0
    proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_nlabels, tvb, offset, 4, ENC_BIG_ENDIAN);
1741
0
    offset += 4;
1742
0
    if (nlabels_or_error < 0) {
1743
0
        expert_add_info(pinfo, pcp_label_sets_tree, &ei_pcp_label_error);
1744
0
    }
1745
1746
    /* Offset to start of JSON */
1747
0
    uint32_t json_start_offset = tvb_get_ntohl(tvb, offset);
1748
0
    proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_json, tvb, offset, 4, ENC_BIG_ENDIAN);
1749
0
    offset += 4;
1750
1751
    /* Length of JSON string */
1752
0
    proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_jsonlen, tvb, offset, 4, ENC_BIG_ENDIAN);
1753
0
    offset += 4;
1754
1755
    /* pmLabels */
1756
0
    for (int i = 0; i < nlabels_or_error; i++) {
1757
0
        offset = dissect_pcp_partial_label(tvb, pinfo, pcp_label_sets_tree, offset, json_start_offset);
1758
0
    }
1759
1760
    /* Fix up end length */
1761
0
    proto_item_set_end(pcp_label_sets_item, tvb, offset);
1762
1763
0
    return offset;
1764
1765
0
}
1766
1767
static int dissect_pcp_partial_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint32_t json_start_offset)
1768
0
{
1769
0
    proto_item *pcp_label_sets_label_item = proto_tree_add_item(tree, hf_pcp_label_sets_labels, tvb, offset, -1, ENC_NA);
1770
0
    proto_tree *pcp_label_sets_label_tree = proto_item_add_subtree(pcp_label_sets_label_item, ett_pcp);
1771
1772
    /* Name offset*/
1773
0
    uint16_t name_offset = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1774
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_nameoffset, tvb, offset, 2, ENC_BIG_ENDIAN);
1775
0
    offset += 2;
1776
1777
    /* Name length */
1778
0
    uint32_t name_length = tvb_get_uint8(tvb, offset);
1779
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_namelen, tvb, offset, 1, ENC_NA);
1780
0
    offset += 1;
1781
1782
    /* Flags */
1783
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_flags, tvb, offset, 1, ENC_NA);
1784
0
    offset += 1;
1785
1786
    /* Value offset */
1787
0
    uint16_t value_offset = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1788
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valueoffset, tvb, offset, 2, ENC_BIG_ENDIAN);
1789
0
    offset += 2;
1790
1791
    /* Value Length */
1792
0
    uint16_t value_length = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1793
    /* Value length was not correctly converted to network-byte order in pcp v4.0.0-v4.0.1, it was encoded with whatever
1794
     * byte order the host uses. We try and pick this up and accommodate either by detecting the feature off the START PDU
1795
     * and failing that, check if the offset+length would be greater than the length of the captured packets. This isn't
1796
     * exhaustive but there is not much else to do apart from _only_ dissecting the known good LABEL PDUs.
1797
     */
1798
0
    if(is_using_good_labels(pinfo)) {
1799
0
        proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_BIG_ENDIAN);
1800
0
    }
1801
0
    else if(label_value_length_looks_like_wrong_endianness(tvb, value_offset, value_length)) {
1802
        /* We're _probably_ using the wrong endianness but we didn't capture the initial exchange to find out */
1803
0
        value_length = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1804
0
        proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1805
0
        expert_add_info(pinfo, pcp_label_sets_label_tree, &ei_pcp_label_error_endianness);
1806
0
    } else {
1807
0
        proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_BIG_ENDIAN);
1808
0
        expert_add_info(pinfo, pcp_label_sets_label_tree, &ei_pcp_label_error_endianness);
1809
0
    }
1810
0
    offset += 2;
1811
1812
    /* Name */
1813
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_name, tvb, json_start_offset + name_offset, name_length, ENC_ASCII | ENC_NA);
1814
1815
    /* Value */
1816
0
    proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_value, tvb, json_start_offset + value_offset, value_length, ENC_ASCII | ENC_NA);
1817
1818
    /* Add to subtree  */
1819
0
    uint8_t *name = tvb_get_string_enc(pinfo->pool, tvb, json_start_offset + name_offset, name_length, ENC_ASCII | ENC_NA);
1820
0
    uint8_t *value = tvb_get_string_enc(pinfo->pool, tvb, json_start_offset + value_offset, value_length, ENC_ASCII | ENC_NA);
1821
0
    proto_item_append_text(pcp_label_sets_label_item, " (%s:%s)", name, value);
1822
1823
0
    proto_item_set_end(pcp_label_sets_label_item, tvb, offset);
1824
1825
0
    return offset;
1826
0
}
1827
1828
static bool is_using_good_labels(packet_info *pinfo)
1829
0
{
1830
    /* Try to establish if we've got good labels from an earlier START PDU */
1831
0
    return get_pcp_conversation_info(pinfo)->using_good_labels;
1832
0
}
1833
1834
static bool label_value_length_looks_like_wrong_endianness(tvbuff_t *tvb, uint16_t value_offset, uint16_t value_length)
1835
0
{
1836
    /* Try to detect if the offset + length is greater than the TVB length which may happen with a
1837
     * wrongly-encoded endianness. This may fail in some cases if the label is early on in the frame and has
1838
     * many other labels that wouldn't push it over of the TVB length.
1839
     */
1840
0
    return tvb_reported_length(tvb) < ((unsigned)value_offset + (unsigned)value_length);
1841
0
}
1842
1843
/* MAIN DISSECTING ROUTINE (after passed from dissect_tcp, all non-ssl packets hit function) */
1844
static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1845
0
{
1846
0
    proto_item *root_pcp_item;
1847
0
    proto_tree *pcp_tree;
1848
0
    conversation_t  *conversation;
1849
0
    pcp_conv_info_t *pcp_conv_info;
1850
0
    uint32_t    packet_type;
1851
0
    int32_t     err_bytes;
1852
0
    int         offset = 0;
1853
1854
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCP");
1855
0
    col_clear(pinfo->cinfo, COL_INFO);
1856
1857
1858
0
    conversation = find_or_create_conversation(pinfo);
1859
1860
0
    pcp_conv_info = (pcp_conv_info_t*)conversation_get_proto_data(conversation, proto_pcp);
1861
1862
0
    if(pcp_conv_info == NULL) {
1863
0
        pcp_conv_info = wmem_new(wmem_file_scope(), pcp_conv_info_t);
1864
0
        conversation_add_proto_data(conversation, proto_pcp, pcp_conv_info);
1865
1866
0
        pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
1867
0
        pcp_conv_info->pmid_to_name = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
1868
0
        pcp_conv_info->last_pmns_names_frame = 0;
1869
0
        pcp_conv_info->last_processed_pmns_names_frame = 0;
1870
0
        pcp_conv_info->using_good_labels = false;
1871
0
    }
1872
1873
0
    root_pcp_item = proto_tree_add_item(tree, proto_pcp, tvb, 0, -1, ENC_NA);
1874
0
    pcp_tree      = proto_item_add_subtree(root_pcp_item, ett_pcp);
1875
1876
0
    packet_type   = tvb_get_ntohl(tvb, 4);
1877
1878
    /* check if we are the client requesting or the server */
1879
0
    if (server_to_client(pinfo)) {
1880
0
        col_set_str(pinfo->cinfo, COL_INFO, "Server > Client ");
1881
0
    } else {
1882
0
        col_set_str(pinfo->cinfo, COL_INFO, "Client > Server ");
1883
0
    }
1884
1885
    /* PCP packet length */
1886
0
    proto_tree_add_item(pcp_tree, hf_pcp_pdu_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1887
0
    offset += 4;
1888
    /* PCP Packet type */
1889
0
    proto_tree_add_item(pcp_tree, hf_pcp_pdu_type,   tvb, offset, 4, ENC_BIG_ENDIAN);
1890
0
    offset += 4;
1891
    /* PCP Remote PID */
1892
0
    proto_tree_add_item(pcp_tree, hf_pcp_pdu_pid,    tvb, offset, 4, ENC_BIG_ENDIAN);
1893
0
    offset += 4;
1894
1895
    /* dissect the rest of the packet depending on the type */
1896
0
    switch (packet_type) {
1897
0
        case PCP_PDU_CREDS:
1898
0
            dissect_pcp_message_creds(tvb, pinfo, pcp_tree, offset);
1899
0
            break;
1900
1901
0
        case PCP_PDU_START_OR_ERROR:
1902
0
            err_bytes = tvb_get_ntohl(tvb, offset); /* get the first 4 bytes, determine if this is an error or not */
1903
            /* errors are signed and are all negative so check for a negative number.
1904
               It's the only way we can differentiate between start/error packets */
1905
0
            if (err_bytes < 0) {
1906
0
                dissect_pcp_message_error(tvb, pinfo, pcp_tree, offset);
1907
0
            } else {
1908
0
                dissect_pcp_message_start(tvb, pinfo, pcp_tree, offset);
1909
0
            }
1910
0
            break;
1911
1912
0
        case PCP_PDU_PMNS_TRAVERSE:
1913
0
            dissect_pcp_message_pmns_traverse(tvb, pinfo, pcp_tree, offset);
1914
0
            break;
1915
1916
0
        case PCP_PDU_PMNS_NAMES:
1917
0
            dissect_pcp_message_pmns_names(tvb, pinfo, pcp_tree, offset);
1918
0
            break;
1919
1920
0
        case PCP_PDU_PMNS_CHILD:
1921
0
            dissect_pcp_message_pmns_child(tvb, pinfo, pcp_tree, offset);
1922
0
            break;
1923
1924
0
        case PCP_PDU_PMNS_IDS:
1925
0
            dissect_pcp_message_pmns_ids(tvb, pinfo, pcp_tree, offset);
1926
0
            break;
1927
1928
0
        case PCP_PDU_PROFILE:
1929
0
            dissect_pcp_message_profile(tvb, pinfo, pcp_tree, offset);
1930
0
            break;
1931
1932
0
        case PCP_PDU_FETCH:
1933
0
            dissect_pcp_message_fetch(tvb, pinfo, pcp_tree, offset);
1934
0
            break;
1935
1936
0
        case PCP_PDU_RESULT:
1937
0
            dissect_pcp_message_result(tvb, pinfo, pcp_tree, offset);
1938
0
            break;
1939
1940
0
        case PCP_PDU_DESC_REQ:
1941
0
            dissect_pcp_message_desc_req(tvb, pinfo, pcp_tree, offset);
1942
0
            break;
1943
1944
0
        case PCP_PDU_DESC:
1945
0
            dissect_pcp_message_desc(tvb, pinfo, pcp_tree, offset);
1946
0
            break;
1947
1948
0
        case PCP_PDU_INSTANCE_REQ:
1949
0
            dissect_pcp_message_instance_req(tvb, pinfo, pcp_tree, offset);
1950
0
            break;
1951
1952
0
        case PCP_PDU_INSTANCE:
1953
0
            dissect_pcp_message_instance(tvb, pinfo, pcp_tree, offset);
1954
0
            break;
1955
1956
0
        case PCP_PDU_TEXT_REQ:
1957
0
            dissect_pcp_message_text_req(tvb, pinfo, pcp_tree, offset);
1958
0
            break;
1959
1960
0
        case PCP_PDU_TEXT:
1961
0
            dissect_pcp_message_text(tvb, pinfo, pcp_tree, offset);
1962
0
            break;
1963
1964
0
        case PCP_PDU_USER_AUTH:
1965
0
            dissect_pcp_message_user_auth(tvb, pinfo, pcp_tree, offset);
1966
0
            break;
1967
1968
0
        case PCP_PDU_LABEL_REQ:
1969
0
            dissect_pcp_message_label_req(tvb, pinfo, pcp_tree, offset);
1970
0
            break;
1971
1972
0
        case PCP_PDU_LABEL:
1973
0
            dissect_pcp_message_label(tvb, pinfo, pcp_tree, offset);
1974
0
            break;
1975
1976
0
        default:
1977
            /* append the type of packet */
1978
0
            col_append_str(pinfo->cinfo, COL_INFO, "[UNIMPLEMENTED TYPE]");
1979
            /* if we got here, then we didn't get a packet type that we know of */
1980
0
            expert_add_info(pinfo, pcp_tree, &ei_pcp_unimplemented_packet_type);
1981
0
            break;
1982
0
    }
1983
0
    return tvb_captured_length(tvb);
1984
0
}
1985
1986
static int dissect_pcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1987
0
{
1988
    /* pass all packets through TCP-reassembly */
1989
0
    tcp_dissect_pdus(tvb, pinfo, tree, true, PCP_HEADER_LEN, get_pcp_message_len, dissect_pcp_message, data);
1990
0
    return tvb_captured_length(tvb);
1991
0
}
1992
1993
/* setup the dissecting */
1994
void proto_register_pcp(void)
1995
14
{
1996
14
    static hf_register_info hf[] = {
1997
14
        { &hf_pcp_pdu_length,
1998
14
          { "PDU Length", "pcp.length",
1999
14
            FT_UINT32, BASE_DEC,
2000
14
            NULL, 0x0,
2001
14
            NULL, HFILL
2002
14
          }
2003
14
        },
2004
14
        { &hf_pcp_pdu_type,
2005
14
          { "Type", "pcp.type",
2006
14
            FT_UINT32, BASE_HEX,
2007
14
            VALS(packettypenames), 0x0,
2008
14
            NULL, HFILL
2009
14
          }
2010
14
        },
2011
14
        { &hf_pcp_pdu_pid,
2012
14
          { "From", "pcp.from",
2013
14
            FT_UINT32, BASE_DEC,
2014
14
            NULL, 0x0,
2015
14
            NULL, HFILL
2016
14
          }
2017
14
        },
2018
14
        { &hf_pcp_pdu_error,
2019
14
          { "Error", "pcp.error",
2020
14
            FT_INT32, BASE_DEC,
2021
14
            VALS(packettypenames_errors), 0x0,
2022
14
            NULL, HFILL
2023
14
          }
2024
14
        },
2025
14
        { &hf_pcp_pdu_padding,
2026
14
          { "Padding", "pcp.padding",
2027
14
            FT_NONE, BASE_NONE,
2028
14
            NULL, 0x0,
2029
14
            NULL, HFILL
2030
14
          }
2031
14
        },
2032
14
        { &hf_pcp_creds_number_of,
2033
14
          { "Number of Credentials", "pcp.creds.number",
2034
14
            FT_UINT32, BASE_DEC,
2035
14
            NULL, 0x0,
2036
14
            NULL, HFILL
2037
14
          }
2038
14
        },
2039
14
        { &hf_pcp_creds_type,
2040
14
          { "Credentials Type", "pcp.creds.type",
2041
14
            FT_UINT8, BASE_DEC,
2042
14
            VALS(packettypenames_creds), 0x0,
2043
14
            NULL, HFILL
2044
14
          }
2045
14
        },
2046
14
        { &hf_pcp_creds_version,
2047
14
          { "Credentials Version", "pcp.creds.version",
2048
14
            FT_UINT8, BASE_DEC,
2049
14
            NULL, 0x0,
2050
14
            NULL, HFILL
2051
14
          }
2052
14
        },
2053
14
        { &hf_pcp_start,
2054
14
          { "Start", "pcp.start",
2055
14
            FT_NONE, BASE_NONE,
2056
14
            NULL, 0x0,
2057
14
            NULL, HFILL
2058
14
          }
2059
14
        },
2060
14
        { &hf_pcp_start_zero,
2061
14
          { "Start Bit", "pcp.start.zero",
2062
14
            FT_BOOLEAN, 8,
2063
14
            TFS(&tfs_set_notset), 0x80,
2064
14
            NULL, HFILL
2065
14
          }
2066
14
        },
2067
14
        { &hf_pcp_start_version,
2068
14
          { "Version", "pcp.start.version",
2069
14
            FT_UINT8, BASE_DEC, /* not a real 8 bit int, only uses 7 bits */
2070
14
            NULL, 0x7F,
2071
14
            NULL, HFILL
2072
14
          }
2073
14
        },
2074
14
        { &hf_pcp_start_status,
2075
14
          { "Start Status", "pcp.start.status",
2076
14
            FT_UINT32, BASE_DEC,
2077
14
            NULL, 0x0,
2078
14
            NULL, HFILL
2079
14
          }
2080
14
        },
2081
14
        { &hf_pcp_start_licensed,
2082
14
          { "Licensed", "pcp.start.licensed",
2083
14
            FT_UINT8, BASE_DEC,
2084
14
            NULL, 0x0,
2085
14
            NULL, HFILL
2086
14
          }
2087
14
        },
2088
14
        { &hf_pcp_features_flags,
2089
14
          { "Features", "pcp.features.flags",
2090
14
            FT_UINT16, BASE_HEX,
2091
14
            NULL, 0x0,
2092
14
            NULL, HFILL
2093
14
          }
2094
14
        },
2095
14
        { &hf_pcp_features_flags_secure,
2096
14
          { "Secure", "pcp.features.flags.secure",
2097
14
            FT_BOOLEAN, 16,
2098
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE,
2099
14
            NULL, HFILL
2100
14
          }
2101
14
        },
2102
14
        { &hf_pcp_features_flags_compress,
2103
14
          { "Compression", "pcp.features.flags.compression",
2104
14
            FT_BOOLEAN, 16,
2105
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_COMPRESS,
2106
14
            NULL, HFILL
2107
14
          }
2108
14
        },
2109
14
        { &hf_pcp_features_flags_auth,
2110
14
          { "Authentication", "pcp.features.flags.auth",
2111
14
            FT_BOOLEAN, 16,
2112
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_AUTH,
2113
14
            NULL, HFILL
2114
14
          }
2115
14
        },
2116
14
        { &hf_pcp_features_flags_creds_reqd,
2117
14
          { "Credentials Required", "pcp.features.flags.creds_reqd",
2118
14
            FT_BOOLEAN, 16,
2119
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_CREDS_REQD,
2120
14
            NULL, HFILL
2121
14
          }
2122
14
        },
2123
14
        { &hf_pcp_features_flags_secure_ack,
2124
14
          { "Secure Acknowledgement", "pcp.features.flags.secure_ack",
2125
14
            FT_BOOLEAN, 16,
2126
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE_ACK,
2127
14
            NULL, HFILL
2128
14
          }
2129
14
        },
2130
14
        { &hf_pcp_features_flags_no_nss_init,
2131
14
          { "No NSS Init", "pcp.features.flags.no_nss_init",
2132
14
            FT_BOOLEAN, 16,
2133
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_NO_NSS_INIT,
2134
14
            NULL, HFILL
2135
14
          }
2136
14
        },
2137
14
        { &hf_pcp_features_flags_container,
2138
14
          { "Container", "pcp.features.flags.container",
2139
14
            FT_BOOLEAN, 16,
2140
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_CONTAINER,
2141
14
            NULL, HFILL
2142
14
          }
2143
14
        },
2144
14
        { &hf_pcp_features_flags_cert_reqd,
2145
14
          { "Certificate Required", "pcp.features.flags.cert_reqd",
2146
14
            FT_BOOLEAN, 16,
2147
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_CERT_REQD,
2148
14
            NULL, HFILL
2149
14
          }
2150
14
        },
2151
14
        { &hf_pcp_features_flags_bad_label,
2152
14
          { "Bad Label", "pcp.features.flags.bad_label",
2153
14
            FT_BOOLEAN, 16,
2154
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_BAD_LABEL,
2155
14
            "Legacy label support. Incorrectly implemented in pcp v4.0.0-v4.0.1", HFILL
2156
14
          }
2157
14
        },
2158
14
        { &hf_pcp_features_flags_labels,
2159
14
          { "Labels", "pcp.features.flags.labels",
2160
14
            FT_BOOLEAN, 16,
2161
14
            TFS(&tfs_set_notset), PCP_PDU_FLAG_LABELS,
2162
14
            NULL, HFILL
2163
14
          }
2164
14
        },
2165
14
        { &hf_pcp_pmns_traverse,
2166
14
          { "PMNS Traverse", "pcp.pmns_traverse",
2167
14
            FT_NONE, BASE_NONE,
2168
14
            NULL, 0x0,
2169
14
            NULL, HFILL
2170
14
          }
2171
14
        },
2172
14
        { &hf_pcp_pmns_subtype,
2173
14
          { "Subtype", "pcp.pmns.subtype",
2174
14
            FT_UINT32, BASE_DEC,
2175
14
            NULL, 0x0,
2176
14
            NULL, HFILL
2177
14
          }
2178
14
        },
2179
14
        { &hf_pcp_pmns_namelen,
2180
14
          { "Name Length", "pcp.pmns.namelen",
2181
14
            FT_UINT32, BASE_DEC,
2182
14
            NULL, 0x0,
2183
14
            NULL, HFILL
2184
14
          }
2185
14
        },
2186
14
        { &hf_pcp_pmns_name,
2187
14
          { "Name", "pcp.pmns.name",
2188
14
            FT_STRING, BASE_NONE,
2189
14
            NULL, 0x0,
2190
14
            NULL, HFILL
2191
14
          }
2192
14
        },
2193
14
        { &hf_pcp_pmns_names,
2194
14
          { "PMNS Names", "pcp.pmns_names",
2195
14
            FT_NONE, BASE_NONE,
2196
14
            NULL, 0x0,
2197
14
            NULL, HFILL
2198
14
          }
2199
14
        },
2200
14
        { &hf_pcp_pmns_names_nstrbytes,
2201
14
          { "String Bytes", "pcp.pmns_names.nstrbytes",
2202
14
            FT_UINT32, BASE_DEC,
2203
14
            NULL, 0x0,
2204
14
            NULL, HFILL
2205
14
          }
2206
14
        },
2207
14
        { &hf_pcp_pmns_names_numstatus,
2208
14
          { "Status", "pcp.pmns_names.numstatus",
2209
14
            FT_UINT32, BASE_DEC,
2210
14
            NULL, 0x0,
2211
14
            NULL, HFILL
2212
14
          }
2213
14
        },
2214
14
        { &hf_pcp_pmns_names_numnames,
2215
14
          { "Number of Names", "pcp.pmns_names.numnames",
2216
14
            FT_UINT32, BASE_DEC,
2217
14
            NULL, 0x0,
2218
14
            NULL, HFILL
2219
14
          }
2220
14
        },
2221
14
        { &hf_pcp_pmns_names_nametree,
2222
14
          { "Names", "pcp.pmns_names.nametree",
2223
14
            FT_NONE, BASE_NONE,
2224
14
            NULL, 0x0,
2225
14
            NULL, HFILL
2226
14
          }
2227
14
        },
2228
14
        { &hf_pcp_pmns_names_nametree_status,
2229
14
          { "Status", "pcp.pmns_names.nametree.status",
2230
14
            FT_UINT32, BASE_DEC,
2231
14
            NULL, 0x0,
2232
14
            NULL, HFILL
2233
14
          }
2234
14
        },
2235
14
        { &hf_pcp_pmns_names_nametree_namelen,
2236
14
          { "Length", "pcp.pmns_names.nametree.namelen",
2237
14
            FT_UINT32, BASE_DEC,
2238
14
            NULL, 0x0,
2239
14
            NULL, HFILL
2240
14
          }
2241
14
        },
2242
14
        { &hf_pcp_pmns_names_nametree_name,
2243
14
          { "Name", "pcp.pmns_names.nametree.name",
2244
14
            FT_STRING, BASE_NONE,
2245
14
            NULL, 0x0,
2246
14
            NULL, HFILL
2247
14
          }
2248
14
        },
2249
14
        { &hf_pcp_pmns_ids,
2250
14
          { "PMNS IDs", "pcp.pmns_ids",
2251
14
            FT_NONE, BASE_NONE,
2252
14
            NULL, 0x0,
2253
14
            NULL, HFILL
2254
14
          }
2255
14
        },
2256
14
        { &hf_pcp_pmns_ids_status,
2257
14
          { "Status", "pcp.pmns_ids.status",
2258
14
            FT_UINT32, BASE_DEC,
2259
14
            NULL, 0x0,
2260
14
            NULL, HFILL
2261
14
          }
2262
14
        },
2263
14
        { &hf_pcp_pmns_ids_numids,
2264
14
          { "Number of IDs", "pcp.pmns_ids.numids",
2265
14
            FT_UINT32, BASE_DEC,
2266
14
            NULL, 0x0,
2267
14
            NULL, HFILL
2268
14
          }
2269
14
        },
2270
14
        { &hf_pcp_pmns_child,
2271
14
          { "PMID Child", "pcp.pmns.child",
2272
14
            FT_NONE, BASE_NONE,
2273
14
            NULL, 0x0,
2274
14
            NULL, HFILL
2275
14
          }
2276
14
        },
2277
14
        { &hf_pcp_pmid,
2278
14
          { "PMID", "pcp.pmid",
2279
14
            FT_UINT32, BASE_DEC,
2280
14
            NULL, 0x0,
2281
14
            NULL, HFILL
2282
14
          }
2283
14
        },
2284
14
        { &hf_pcp_pmid_flag,
2285
14
          { "Flag", "pcp.pmid.flag",
2286
14
            FT_BOOLEAN, BASE_NONE,
2287
14
            NULL, 0x0,
2288
14
            NULL, HFILL
2289
14
          }
2290
14
        },
2291
14
        { &hf_pcp_pmid_domain,
2292
14
          { "Domain", "pcp.pmid.domain",
2293
14
            FT_UINT16, BASE_DEC, /* uses 9 bits */
2294
14
            NULL, 0x0,
2295
14
            NULL, HFILL
2296
14
          }
2297
14
        },
2298
14
        { &hf_pcp_pmid_cluster,
2299
14
          { "Cluster", "pcp.pmid.cluster",
2300
14
            FT_UINT16, BASE_DEC, /* uses 12 bits */
2301
14
            NULL, 0x0,
2302
14
            NULL, HFILL
2303
14
          }
2304
14
        },
2305
14
        { &hf_pcp_pmid_item,
2306
14
          { "Item", "pcp.pmid.item",
2307
14
            FT_UINT16, BASE_DEC, /* uses 10 bits */
2308
14
            NULL, 0x0,
2309
14
            NULL, HFILL
2310
14
          }
2311
14
        },
2312
14
        { &hf_pcp_pmid_type,
2313
14
          { "Type", "pcp.pmid.type",
2314
14
            FT_INT32, BASE_DEC,
2315
14
            VALS(packettypenames_pm_types), 0x0,
2316
14
            NULL, HFILL
2317
14
          }
2318
14
        },
2319
14
        { &hf_pcp_pmid_sem,
2320
14
          { "Type Semantics", "pcp.pmid.sem",
2321
14
            FT_UINT32, BASE_DEC,
2322
14
            VALS(packettypenames_pm_types_sem), 0x0,
2323
14
            NULL, HFILL
2324
14
          }
2325
14
        },
2326
14
        { &hf_pcp_pmid_inst,
2327
14
          { "Instance", "pcp.pmid.inst",
2328
14
            FT_UINT32, BASE_DEC,
2329
14
            NULL, 0x0,
2330
14
            NULL, HFILL
2331
14
          }
2332
14
        },
2333
14
        { &hf_pcp_profile,
2334
14
          { "Profile", "pcp.profile",
2335
14
            FT_NONE, BASE_NONE,
2336
14
            NULL, 0x0,
2337
14
            NULL, HFILL
2338
14
          }
2339
14
        },
2340
14
        { &hf_pcp_ctxnum,
2341
14
          { "Context Number", "pcp.ctxnum",
2342
14
            FT_UINT32, BASE_DEC,
2343
14
            NULL, 0x0,
2344
14
            NULL, HFILL
2345
14
          }
2346
14
        },
2347
14
        { &hf_pcp_profile_g_state,
2348
14
          { "Global Include/Exclude State", "pcp.profile.g_state",
2349
14
            FT_UINT32, BASE_DEC,
2350
14
            NULL, 0x0,
2351
14
            NULL, HFILL
2352
14
          }
2353
14
        },
2354
14
        { &hf_pcp_profile_numprof,
2355
14
          { "Number of Profiles", "pcp.profile.numprof",
2356
14
            FT_UINT32, BASE_DEC,
2357
14
            NULL, 0x0,
2358
14
            NULL, HFILL
2359
14
          }
2360
14
        },
2361
14
        { &hf_pcp_profile_profile,
2362
14
          { "Each Profile", "pcp.profile.profile",
2363
14
            FT_NONE, BASE_NONE,
2364
14
            NULL, 0x0,
2365
14
            NULL, HFILL
2366
14
          }
2367
14
        },
2368
14
        { &hf_pcp_profile_profile_state,
2369
14
          { "Include/Exclude State", "pcp.profile.profile.state",
2370
14
            FT_UINT32, BASE_DEC,
2371
14
            NULL, 0x0,
2372
14
            NULL, HFILL
2373
14
          }
2374
14
        },
2375
14
        { &hf_pcp_profile_profile_numinst,
2376
14
          { "Number Instances to Follow", "pcp.profile.profile.numinst",
2377
14
            FT_UINT32, BASE_DEC,
2378
14
            NULL, 0x0,
2379
14
            NULL, HFILL
2380
14
          }
2381
14
        },
2382
14
        { &hf_pcp_fetch,
2383
14
          { "Fetch", "pcp.fetch",
2384
14
            FT_NONE, BASE_NONE,
2385
14
            NULL, 0x0,
2386
14
            NULL, HFILL
2387
14
          }
2388
14
        },
2389
14
        { &hf_pcp_fetch_numpmid,
2390
14
          { "Number PMIDs", "pcp.fetch.numpmid",
2391
14
            FT_UINT32, BASE_DEC,
2392
14
            NULL, 0x0,
2393
14
            NULL, HFILL
2394
14
          }
2395
14
        },
2396
14
        { &hf_pcp_when,
2397
14
          { "Time Value", "pcp.when",
2398
14
            FT_NONE, BASE_NONE,
2399
14
            NULL, 0x0,
2400
14
            NULL, HFILL
2401
14
          }
2402
14
        },
2403
14
        { &hf_pcp_when_sec,
2404
14
          { "Seconds", "pcp.when.sec",
2405
14
            FT_UINT32, BASE_DEC,
2406
14
            NULL, 0x0,
2407
14
            NULL, HFILL
2408
14
          }
2409
14
        },
2410
14
        { &hf_pcp_when_usec,
2411
14
          { "Microseconds", "pcp.when.usec",
2412
14
            FT_UINT32, BASE_DEC,
2413
14
            NULL, 0x0,
2414
14
            NULL, HFILL
2415
14
          }
2416
14
        },
2417
14
        { &hf_pcp_desc_req,
2418
14
          { "Description Request", "pcp.desc_req",
2419
14
            FT_NONE, BASE_NONE,
2420
14
            NULL, 0x0,
2421
14
            NULL, HFILL
2422
14
          }
2423
14
        },
2424
14
        { &hf_pcp_desc,
2425
14
          { "Description Response", "pcp.desc",
2426
14
            FT_NONE, BASE_NONE,
2427
14
            NULL, 0x0,
2428
14
            NULL, HFILL
2429
14
          }
2430
14
        },
2431
14
        { &hf_pcp_units,
2432
14
          { "PMID Units", "pcp.units",
2433
14
            FT_NONE, BASE_NONE,
2434
14
            NULL, 0x0,
2435
14
            NULL, HFILL
2436
14
          }
2437
14
        },
2438
14
        { &hf_pcp_units_dimspace,
2439
14
          { "Dimension Space", "pcp.units.dimspace",
2440
14
            FT_UINT8, BASE_DEC,
2441
14
            NULL, 0x0,
2442
14
            NULL, HFILL
2443
14
          }
2444
14
        },
2445
14
        { &hf_pcp_units_dimtime,
2446
14
          { "Dimension Time", "pcp.units.dimtime",
2447
14
            FT_UINT8, BASE_DEC,
2448
14
            NULL, 0x0,
2449
14
            NULL, HFILL
2450
14
          }
2451
14
        },
2452
14
        { &hf_pcp_units_dimcount,
2453
14
          { "Dimension Count", "pcp.units.dimcount",
2454
14
            FT_UINT8, BASE_DEC,
2455
14
            NULL, 0x0,
2456
14
            NULL, HFILL
2457
14
          }
2458
14
        },
2459
14
        { &hf_pcp_units_scalespace,
2460
14
          { "Scale Space", "pcp.units.scalespace",
2461
14
            FT_UINT8, BASE_DEC,
2462
14
            VALS(packettypenames_pm_units_space), 0x0,
2463
14
            NULL, HFILL
2464
14
          }
2465
14
        },
2466
14
        { &hf_pcp_units_scaletime,
2467
14
          { "Scale Time", "pcp.units.scaletime",
2468
14
            FT_UINT8, BASE_DEC,
2469
14
            VALS(packettypenames_pm_units_time), 0x0,
2470
14
            NULL, HFILL
2471
14
          }
2472
14
        },
2473
14
        { &hf_pcp_units_scalecount,
2474
14
          { "Scale Count", "pcp.units.scalecount",
2475
14
            FT_UINT8, BASE_DEC,
2476
14
            NULL, 0x0,
2477
14
            NULL, HFILL
2478
14
          }
2479
14
        },
2480
14
        { &hf_pcp_instance_req,
2481
14
          { "Instance Request", "pcp.instance_req",
2482
14
            FT_NONE, BASE_NONE,
2483
14
            NULL, 0x0,
2484
14
            NULL, HFILL
2485
14
          }
2486
14
        },
2487
14
        { &hf_pcp_instances,
2488
14
          { "Instance Response", "pcp.instances",
2489
14
            FT_NONE, BASE_NONE,
2490
14
            NULL, 0x0,
2491
14
            NULL, HFILL
2492
14
          }
2493
14
        },
2494
14
        { &hf_pcp_instances_numinst,
2495
14
          { "Number of Instances", "pcp.instance_resp.numinst",
2496
14
            FT_UINT32, BASE_DEC,
2497
14
            NULL, 0x0,
2498
14
            NULL, HFILL
2499
14
          }
2500
14
        },
2501
14
        { &hf_pcp_instance,
2502
14
          { "Instance", "pcp.instance",
2503
14
            FT_NONE, BASE_NONE,
2504
14
            NULL, 0x0,
2505
14
            NULL, HFILL
2506
14
          }
2507
14
        },
2508
14
        { &hf_pcp_instance_namelen,
2509
14
          { "Name Length", "pcp.instance.namelen",
2510
14
            FT_UINT32, BASE_DEC,
2511
14
            NULL, 0x0,
2512
14
            NULL, HFILL
2513
14
          }
2514
14
        },
2515
14
        { &hf_pcp_instance_name,
2516
14
          { "Name", "pcp.instance.name",
2517
14
            FT_STRING, BASE_NONE,
2518
14
            NULL, 0x0,
2519
14
            NULL, HFILL
2520
14
          }
2521
14
        },
2522
14
        { &hf_pcp_instance_indom,
2523
14
          { "Instance Domain", "pcp.instance.indom",
2524
14
            FT_UINT32, BASE_DEC,
2525
14
            NULL, 0x0,
2526
14
            NULL, HFILL
2527
14
          }
2528
14
        },
2529
14
        { &hf_pcp_instance_valoffset,
2530
14
          { "Instance Offset", "pcp.instance.valoffset",
2531
14
            FT_UINT32, BASE_DEC,
2532
14
            NULL, 0x0,
2533
14
            NULL, HFILL
2534
14
          }
2535
14
        },
2536
14
        { &hf_pcp_instance_vallength,
2537
14
          { "Instance Value Length", "pcp.instance.vallength",
2538
14
            FT_INT24, BASE_DEC,
2539
14
            NULL, 0x0,
2540
14
            NULL, HFILL
2541
14
          }
2542
14
        },
2543
14
        { &hf_pcp_instance_value_insitu,
2544
14
          { "Instance Value", "pcp.instance.value.uint",
2545
14
            FT_UINT32, BASE_DEC,
2546
14
            NULL, 0x0,
2547
14
            NULL, HFILL
2548
14
          }
2549
14
        },
2550
14
        { &hf_pcp_instance_value_ptr,
2551
14
          { "Instance Value", "pcp.instance.value.string",
2552
14
            FT_STRING, BASE_NONE,
2553
14
            NULL, 0x0,
2554
14
            NULL, HFILL
2555
14
          }
2556
14
        },
2557
14
        { &hf_pcp_instance_value_int,
2558
14
          { "Instance Value", "pcp.instance.value.int",
2559
14
            FT_INT32, BASE_DEC,
2560
14
            NULL, 0x0,
2561
14
            NULL, HFILL
2562
14
          }
2563
14
        },
2564
14
        { &hf_pcp_instance_value_uint,
2565
14
          { "Instance Value", "pcp.instance.value.uint",
2566
14
            FT_UINT32, BASE_DEC,
2567
14
            NULL, 0x0,
2568
14
            NULL, HFILL
2569
14
          }
2570
14
        },
2571
14
        { &hf_pcp_instance_value_int64,
2572
14
          { "Instance Value", "pcp.instance.value.int64",
2573
14
            FT_INT64, BASE_DEC,
2574
14
            NULL, 0x0,
2575
14
            NULL, HFILL
2576
14
          }
2577
14
        },
2578
14
        { &hf_pcp_instance_value_uint64,
2579
14
          { "Instance Value", "pcp.instance.value.uint64",
2580
14
            FT_UINT64, BASE_DEC,
2581
14
            NULL, 0x0,
2582
14
            NULL, HFILL
2583
14
          }
2584
14
        },
2585
14
        { &hf_pcp_instance_value_float,
2586
14
          { "Instance Value", "pcp.instance.value.float",
2587
14
            FT_FLOAT, BASE_NONE,
2588
14
            NULL, 0x0,
2589
14
            NULL, HFILL
2590
14
          }
2591
14
        },
2592
14
        { &hf_pcp_instance_value_double,
2593
14
          { "Instance Value", "pcp.instance.value.float",
2594
14
            FT_DOUBLE, BASE_NONE,
2595
14
            NULL, 0x0,
2596
14
            NULL, HFILL
2597
14
          }
2598
14
        },
2599
14
        { &hf_pcp_instance_value_aggr,
2600
14
          { "Instance Value", "pcp.instance.value.bytes",
2601
14
            FT_BYTES, BASE_NONE,
2602
14
            NULL, 0x0,
2603
14
            NULL, HFILL
2604
14
          }
2605
14
        },
2606
14
        { &hf_pcp_results,
2607
14
          { "Fetch Results", "pcp.results",
2608
14
            FT_NONE, BASE_NONE,
2609
14
            NULL, 0x0,
2610
14
            NULL, HFILL
2611
14
          }
2612
14
        },
2613
14
        { &hf_pcp_results_numpmid,
2614
14
          { "Number of PMIDs", "pcp.results.numpmid",
2615
14
            FT_UINT32, BASE_DEC,
2616
14
            NULL, 0x0,
2617
14
            NULL, HFILL
2618
14
          }
2619
14
        },
2620
14
        { &hf_pcp_result,
2621
14
          { "Result", "pcp.result",
2622
14
            FT_NONE, BASE_NONE,
2623
14
            NULL, 0x0,
2624
14
            NULL, HFILL
2625
14
          }
2626
14
        },
2627
14
        { &hf_pcp_result_numval,
2628
14
          { "Number of Values", "pcp.result.numval",
2629
14
            FT_UINT32, BASE_DEC,
2630
14
            NULL, 0x0,
2631
14
            NULL, HFILL
2632
14
          }
2633
14
        },
2634
14
        { &hf_pcp_result_valfmt,
2635
14
          { "Value Encoding Format", "pcp.result.valfmt",
2636
14
            FT_UINT32, BASE_DEC,
2637
14
            VALS(packettypenames_valfmt), 0x0,
2638
14
            NULL, HFILL
2639
14
          }
2640
14
        },
2641
14
        { &hf_pcp_text_req,
2642
14
          { "Text Request", "pcp.text_req",
2643
14
            FT_NONE, BASE_NONE,
2644
14
            NULL, 0x0,
2645
14
            NULL, HFILL
2646
14
          }
2647
14
        },
2648
14
        { &hf_pcp_text_type,
2649
14
          { "Help Text Type", "pcp.text.type",
2650
14
            FT_NONE, BASE_NONE,
2651
14
            NULL, 0x0,
2652
14
            NULL, HFILL
2653
14
          }
2654
14
        },
2655
14
        { &hf_pcp_text_type_format,
2656
14
          { "Text Type Format", "pcp.text.type.format",
2657
14
            FT_UINT8, BASE_DEC,
2658
14
            VALS(packettypenames_text_type_format), 0x0,
2659
14
            NULL, HFILL
2660
14
          }
2661
14
        },
2662
14
        { &hf_pcp_text_type_ident,
2663
14
          { "Text Type Ident", "pcp.text.type.ident",
2664
14
            FT_UINT8, BASE_DEC,
2665
14
            VALS(packettypenames_text_type_ident), 0x0,
2666
14
            NULL, HFILL
2667
14
          }
2668
14
        },
2669
14
        { &hf_pcp_text,
2670
14
          { "Text Response", "pcp.text",
2671
14
            FT_NONE, BASE_NONE,
2672
14
            NULL, 0x0,
2673
14
            NULL, HFILL
2674
14
          }
2675
14
        },
2676
14
        { &hf_pcp_text_ident,
2677
14
          { "Text Ident (raw)", "pcp.text.ident",
2678
14
            FT_UINT32, BASE_DEC,
2679
14
            NULL, 0x0,
2680
14
            NULL, HFILL
2681
14
          }
2682
14
        },
2683
14
        { &hf_pcp_text_buflen,
2684
14
          { "Text Buffer Length", "pcp.text.buflen",
2685
14
            FT_UINT32, BASE_DEC,
2686
14
            NULL, 0x0,
2687
14
            NULL, HFILL
2688
14
          }
2689
14
        },
2690
14
        { &hf_pcp_text_buffer,
2691
14
          { "Text Buffer", "pcp.text.buffer",
2692
14
            FT_STRING, BASE_NONE,
2693
14
            NULL, 0x0,
2694
14
            NULL, HFILL
2695
14
          }
2696
14
        },
2697
14
        { &hf_pcp_user_auth_payload,
2698
14
          { "User Authentication Payload", "pcp.user_auth_payload",
2699
14
            FT_NONE, BASE_NONE,
2700
14
            NULL, 0x0,
2701
14
            NULL, HFILL
2702
14
          }
2703
14
        },
2704
14
        { &hf_pcp_label_req,
2705
14
          { "Label Request", "pcp.label_req",
2706
14
            FT_NONE, BASE_NONE,
2707
14
            NULL, 0x0,
2708
14
            NULL, HFILL
2709
14
          }
2710
14
        },
2711
14
        { &hf_pcp_label_ident,
2712
14
          { "Label Ident", "pcp.label.ident",
2713
14
            FT_INT32, BASE_DEC,
2714
14
            NULL, 0x0,
2715
14
            "Domain, PMID or pmInDom identifier", HFILL
2716
14
          }
2717
14
        },
2718
14
        { &hf_pcp_label_type,
2719
14
          { "Label Type", "pcp.label.type",
2720
14
            FT_INT32, BASE_DEC,
2721
14
            VALS(packettypenames_label_req_type), 0x0,
2722
14
            NULL, HFILL
2723
14
          }
2724
14
        },
2725
14
        { &hf_pcp_label,
2726
14
          { "Labels", "pcp.label",
2727
14
            FT_NONE, BASE_NONE,
2728
14
            NULL, 0x0,
2729
14
            NULL, HFILL
2730
14
          }
2731
14
        },
2732
14
        { &hf_pcp_label_padding,
2733
14
          { "Padding", "pcp.label.padding",
2734
14
            FT_NONE, BASE_NONE,
2735
14
            NULL, 0x0,
2736
14
            NULL, HFILL
2737
14
          }
2738
14
        },
2739
14
        { &hf_pcp_label_nsets,
2740
14
          { "Num Label Sets", "pcp.label.nsets",
2741
14
            FT_INT32, BASE_DEC,
2742
14
            NULL, 0x0,
2743
14
            "Number of Label Sets", HFILL
2744
14
          }
2745
14
        },
2746
14
        { &hf_pcp_label_sets,
2747
14
          { "Label Set", "pcp.label.sets",
2748
14
            FT_NONE, BASE_NONE,
2749
14
            NULL, 0x0,
2750
14
            NULL, HFILL
2751
14
          }
2752
14
        },
2753
14
        { &hf_pcp_label_sets_inst,
2754
14
          { "Instance", "pcp.label.sets.inst",
2755
14
            FT_INT32, BASE_DEC,
2756
14
            NULL, 0x0,
2757
14
            "Instance identifier or PM_IN_NULL", HFILL
2758
14
          }
2759
14
        },
2760
14
        { &hf_pcp_label_sets_nlabels,
2761
14
          { "Num of Labels", "pcp.label.sets.nlabels",
2762
14
            FT_INT32, BASE_DEC,
2763
14
            NULL, 0x0,
2764
14
            "Number of labels or error code", HFILL
2765
14
          }
2766
14
        },
2767
14
        { &hf_pcp_label_sets_json,
2768
14
          { "JSON Offset", "pcp.label.sets.json",
2769
14
            FT_INT32, BASE_DEC,
2770
14
            NULL, 0x0,
2771
14
            "Offset to start of JSON string", HFILL
2772
14
          }
2773
14
        },
2774
14
        { &hf_pcp_label_sets_jsonlen,
2775
14
          { "JSON Length", "pcp.label.sets.jsonlen",
2776
14
            FT_INT32, BASE_DEC,
2777
14
            NULL, 0x0,
2778
14
            "Length of bytes of the JSON string", HFILL
2779
14
          }
2780
14
        },
2781
14
        { &hf_pcp_label_sets_labels,
2782
14
          { "Label", "pcp.label.sets.label",
2783
14
            FT_NONE, BASE_NONE,
2784
14
            NULL, 0x0,
2785
14
            NULL, HFILL
2786
14
          }
2787
14
        },
2788
14
        { &hf_pcp_label_sets_labels_nameoffset,
2789
14
          { "Name Offset", "pcp.label.sets.label.nameoffset",
2790
14
            FT_INT16, BASE_DEC,
2791
14
            NULL, 0x0,
2792
14
            "Label name offset in the JSONB string", HFILL
2793
14
          }
2794
14
        },
2795
14
        { &hf_pcp_label_sets_labels_namelen,
2796
14
          { "Name Length", "pcp.label.sets.label.namelen",
2797
14
            FT_INT8, BASE_DEC,
2798
14
            NULL, 0x0,
2799
14
            "Length of name excluding NULL terminator", HFILL
2800
14
          }
2801
14
        },
2802
14
        { &hf_pcp_label_sets_labels_flags,
2803
14
          { "Flags", "pcp.label.sets.label.flags",
2804
14
            FT_INT8, BASE_DEC,
2805
14
            NULL, 0x0,
2806
14
            "Information about this label", HFILL
2807
14
          }
2808
14
        },
2809
14
        { &hf_pcp_label_sets_labels_valueoffset,
2810
14
          { "Value Offset", "pcp.label.sets.label.valueoffset",
2811
14
            FT_INT16, BASE_DEC,
2812
14
            NULL, 0x0,
2813
14
            "Offset of the label value", HFILL
2814
14
          }
2815
14
        },
2816
14
        { &hf_pcp_label_sets_labels_valuelen,
2817
14
          { "Value Length", "pcp.label.sets.label.valuelen",
2818
14
            FT_INT16, BASE_DEC,
2819
14
            NULL, 0x0,
2820
14
            "Length of the value in bytes", HFILL
2821
14
          }
2822
14
        },
2823
14
        { &hf_pcp_label_sets_labels_name,
2824
14
          { "Name", "pcp.label.sets.label.name",
2825
14
            FT_STRING, BASE_NONE,
2826
14
            NULL, 0x0,
2827
14
            "Label name", HFILL
2828
14
          }
2829
14
        },
2830
14
        { &hf_pcp_label_sets_labels_value,
2831
14
          { "Value", "pcp.label.sets.label.value",
2832
14
            FT_STRING, BASE_NONE,
2833
14
            NULL, 0x0,
2834
14
            "Label value", HFILL
2835
14
          }
2836
14
        },
2837
2838
2839
14
    };
2840
2841
14
    static int *ett[] = {
2842
14
        &ett_pcp,
2843
14
        &ett_pcp_pdu_length,
2844
14
        &ett_pcp_pdu_type,
2845
14
        &ett_pcp_pdu_pid,
2846
14
        &ett_pcp_pdu_error,
2847
14
        &ett_pcp_pdu_padding,
2848
14
        &ett_pcp_creds_number_of,
2849
14
        &ett_pcp_creds_type,
2850
14
        &ett_pcp_creds_vala,
2851
14
        &ett_pcp_creds_valb,
2852
14
        &ett_pcp_creds_valc,
2853
14
        &ett_pcp_start,
2854
14
        &ett_pcp_start_status,
2855
14
        &ett_pcp_start_zero,
2856
14
        &ett_pcp_start_version,
2857
14
        &ett_pcp_start_licensed,
2858
14
        &ett_pcp_start_features,
2859
14
        &ett_pcp_pmns_traverse,
2860
14
        &ett_pcp_pmns_subtype,
2861
14
        &ett_pcp_pmns_namelen,
2862
14
        &ett_pcp_pmns_name,
2863
14
        &ett_pcp_pmns_names,
2864
14
        &ett_pcp_pmns_names_nstrbytes,
2865
14
        &ett_pcp_pmns_names_numstatus,
2866
14
        &ett_pcp_pmns_names_numnames,
2867
14
        &ett_pcp_pmns_names_nametree,
2868
14
        &ett_pcp_pmns_names_nametree_status,
2869
14
        &ett_pcp_pmns_names_nametree_namelen,
2870
14
        &ett_pcp_pmns_names_nametree_name,
2871
14
        &ett_pcp_pmns_ids,
2872
14
        &ett_pcp_pmns_ids_status,
2873
14
        &ett_pcp_pmns_ids_numids,
2874
14
        &ett_pcp_pmns_child,
2875
14
        &ett_pcp_pmid,
2876
14
        &ett_pcp_pmid_flag,
2877
14
        &ett_pcp_pmid_domain,
2878
14
        &ett_pcp_pmid_cluster,
2879
14
        &ett_pcp_pmid_item,
2880
14
        &ett_pcp_pmid_type,
2881
14
        &ett_pcp_pmid_sem,
2882
14
        &ett_pcp_profile,
2883
14
        &ett_pcp_ctxnum,
2884
14
        &ett_pcp_profile_g_state,
2885
14
        &ett_pcp_profile_numprof,
2886
14
        &ett_pcp_profile_profile,
2887
14
        &ett_pcp_profile_profile_state,
2888
14
        &ett_pcp_profile_profile_numinst,
2889
14
        &ett_pcp_fetch,
2890
14
        &ett_pcp_fetch_numpmid,
2891
14
        &ett_pcp_when,
2892
14
        &ett_pcp_when_sec,
2893
14
        &ett_pcp_when_usec,
2894
14
        &ett_pcp_desc_req,
2895
14
        &ett_pcp_units,
2896
14
        &ett_pcp_units_dimspace,
2897
14
        &ett_pcp_units_dimtime,
2898
14
        &ett_pcp_units_dimcount,
2899
14
        &ett_pcp_units_scalespace,
2900
14
        &ett_pcp_units_scaletime,
2901
14
        &ett_pcp_units_scalecount,
2902
14
        &ett_pcp_instance,
2903
14
        &ett_pcp_instance_req,
2904
14
        &ett_pcp_instance_namelen,
2905
14
        &ett_pcp_instance_name,
2906
14
        &ett_pcp_instance_indom,
2907
14
        &ett_pcp_instance_inst,
2908
14
        &ett_pcp_instance_valoffset,
2909
14
        &ett_pcp_instance_vallength,
2910
14
        &ett_pcp_instance_value_insitu,
2911
14
        &ett_pcp_instance_value_ptr,
2912
14
        &ett_pcp_instance_value_int,
2913
14
        &ett_pcp_instance_value_uint,
2914
14
        &ett_pcp_instance_value_int64,
2915
14
        &ett_pcp_instance_value_uint64,
2916
14
        &ett_pcp_instance_value_float,
2917
14
        &ett_pcp_instance_value_double,
2918
14
        &ett_pcp_instance_value_aggr,
2919
14
        &ett_pcp_instances,
2920
14
        &ett_pcp_instances_numinst,
2921
14
        &ett_pcp_results,
2922
14
        &ett_pcp_results_numpmid,
2923
14
        &ett_pcp_result,
2924
14
        &ett_pcp_result_numval,
2925
14
        &ett_pcp_result_valfmt,
2926
14
        &ett_pcp_text_req,
2927
14
        &ett_pcp_text_type,
2928
14
        &ett_pcp_text_type_format,
2929
14
        &ett_pcp_text_type_ident,
2930
14
        &ett_pcp_text,
2931
14
        &ett_pcp_text_ident,
2932
14
        &ett_pcp_text_buflen,
2933
14
        &ett_pcp_text_buffer,
2934
14
    };
2935
2936
14
    static ei_register_info ei[] = {
2937
14
        { &ei_pcp_type_event_unimplemented, { "pcp.pmid.type.event.unimplemented", PI_UNDECODED, PI_WARN, "PM_TYPE_EVENT: Unimplemented Value Type", EXPFILL }},
2938
14
        { &ei_pcp_type_nosupport_unsupported, { "pcp.pmid.type.nosupport.unsupported", PI_UNDECODED, PI_WARN, "PM_TYPE_NOSUPPORT: Unsupported Value Type", EXPFILL }},
2939
14
        { &ei_pcp_type_unknown_unknown_value, { "pcp.pmid.type.unknown.unknown_value", PI_UNDECODED, PI_WARN, "PM_TYPE_UNKNOWN: Unknown Value Type", EXPFILL }},
2940
14
        { &ei_pcp_unimplemented_value, { "pcp.pmid.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Value Type", EXPFILL }},
2941
14
        { &ei_pcp_unimplemented_packet_type, { "pcp.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Packet Type", EXPFILL }},
2942
14
        { &ei_pcp_ssl_upgrade, { "pcp.ssl_upgrade", PI_COMMENTS_GROUP, PI_COMMENT, "SSL upgrade via SECURE_ACK", EXPFILL }},
2943
14
        { &ei_pcp_ssl_upgrade_failed, { "pcp.ssl_upgrade_failed", PI_RESPONSE_CODE, PI_WARN, "SSL upgrade via SECURE_ACK failed", EXPFILL }},
2944
14
        { &ei_pcp_label_error, { "pcp.label.error", PI_RESPONSE_CODE, PI_NOTE, "Label returned an error", EXPFILL }},
2945
14
        { &ei_pcp_label_error_endianness, { "pcp.label.error.endianness", PI_RESPONSE_CODE, PI_NOTE, "Value length has been decoded without knowing the endianness. It has been attempted to be detected but may be wrong", EXPFILL }},
2946
14
    };
2947
2948
14
    expert_module_t* expert_pcp;
2949
2950
14
    proto_pcp = proto_register_protocol("Performance Co-Pilot", "PCP", "pcp");
2951
2952
14
    expert_pcp = expert_register_protocol(proto_pcp);
2953
14
    expert_register_field_array(expert_pcp, ei, array_length(ei));
2954
2955
14
    proto_register_field_array(proto_pcp, hf, array_length(hf));
2956
14
    proto_register_subtree_array(ett, array_length(ett));
2957
2958
14
    pcp_handle = register_dissector("pcp", dissect_pcp, proto_pcp);
2959
14
}
2960
2961
void proto_reg_handoff_pcp(void)
2962
14
{
2963
14
    dissector_add_uint_with_preference("tcp.port", PCP_PORT, pcp_handle);
2964
14
}
2965
2966
/*
2967
* Editor modelines - https://www.wireshark.org/tools/modelines.html
2968
*
2969
* Local variables:
2970
* c-basic-offset: 4
2971
* tab-width: 8
2972
* indent-tabs-mode: nil
2973
* End:
2974
*
2975
* vi: set shiftwidth=4 tabstop=8 expandtab:
2976
* :indentSize=4:tabSize=8:noTabs=true:
2977
*/