epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-pcp.c
blobea68a59d140dedf1428b1cbd64d89c6440446273
1 /* packet-pcp.c
2 * Routines for Performace Co-Pilot protocol dissection
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
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"
20 void proto_register_pcp(void);
21 void proto_reg_handoff_pcp(void);
23 #define PCP_PORT 44321
24 #define PMPROXY_PORT 44322
25 #define PCP_HEADER_LEN 12
27 #define PM_ERR_NAME -12357
29 static dissector_handle_t pcp_handle;
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;
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;
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;
256 /* Magic numbers */
257 #define PCP_SECURE_ACK_SUCCESSFUL 0
259 static const value_string pcp_feature_flags[] = {
260 #define PCP_PDU_FLAG_SECURE 0x0001
261 { PCP_PDU_FLAG_SECURE, "SECURE" },
262 #define PCP_PDU_FLAG_COMPRESS 0x0002
263 { PCP_PDU_FLAG_COMPRESS, "COMPRESS" },
264 #define PCP_PDU_FLAG_AUTH 0x0004
265 { PCP_PDU_FLAG_AUTH, "AUTH"},
266 #define PCP_PDU_FLAG_CREDS_REQD 0x0008
267 { PCP_PDU_FLAG_CREDS_REQD, "CREDS_REQD" },
268 #define PCP_PDU_FLAG_SECURE_ACK 0x0010
269 { PCP_PDU_FLAG_SECURE_ACK, "SECURE_ACK" },
270 #define PCP_PDU_FLAG_NO_NSS_INIT 0x0020
271 { PCP_PDU_FLAG_NO_NSS_INIT, "NO_NSS_INIT" },
272 #define PCP_PDU_FLAG_CONTAINER 0x0040
273 { PCP_PDU_FLAG_CONTAINER, "CONTAINER" },
274 #define PCP_PDU_FLAG_CERT_REQD 0x0080
275 { PCP_PDU_FLAG_CERT_REQD, "CERT_REQD" },
276 #define PCP_PDU_FLAG_BAD_LABEL 0x0100
277 { PCP_PDU_FLAG_BAD_LABEL, "BAD_LABEL" },
278 #define PCP_PDU_FLAG_LABELS 0x0200
279 { PCP_PDU_FLAG_LABELS, "LABELS" },
280 { 0, NULL }
283 /* packet types */
284 static const value_string packettypenames[] = {
285 #define PCP_PDU_START_OR_ERROR 0x7000
286 {PCP_PDU_START_OR_ERROR, "START/ERROR" },
287 #define PCP_PDU_RESULT 0x7001
288 {PCP_PDU_RESULT, "RESULT" },
289 #define PCP_PDU_PROFILE 0x7002
290 {PCP_PDU_PROFILE, "PROFILE"},
291 #define PCP_PDU_FETCH 0x7003
292 {PCP_PDU_FETCH, "FETCH"},
293 #define PCP_PDU_DESC_REQ 0x7004
294 {PCP_PDU_DESC_REQ, "DESC_REQ"},
295 #define PCP_PDU_DESC 0x7005
296 {PCP_PDU_DESC, "DESC"},
297 #define PCP_PDU_INSTANCE_REQ 0x7006
298 {PCP_PDU_INSTANCE_REQ, "INSTANCE_REQ" },
299 #define PCP_PDU_INSTANCE 0x7007
300 {PCP_PDU_INSTANCE, "INSTANCE" },
301 #define PCP_PDU_TEXT_REQ 0x7008
302 {PCP_PDU_TEXT_REQ, "TEXT_REQ" },
303 #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 #define PCP_PDU_CREDS 0x700c
310 {PCP_PDU_CREDS, "CREDS" },
311 #define PCP_PDU_PMNS_IDS 0x700d
312 {PCP_PDU_PMNS_IDS, "PMNS_IDS" },
313 #define PCP_PDU_PMNS_NAMES 0x700e
314 {PCP_PDU_PMNS_NAMES, "PMNS_NAMES" },
315 #define PCP_PDU_PMNS_CHILD 0x700f
316 {PCP_PDU_PMNS_CHILD, "PMNS_CHILD" },
317 #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 #define PCP_PDU_USER_AUTH 0x7011
320 {PCP_PDU_USER_AUTH, "USER_AUTH" },
321 #define PCP_PDU_LABEL_REQ 0x7012
322 {PCP_PDU_LABEL_REQ, "LABEL_REQ" },
323 #define PCP_PDU_LABEL 0x7013
324 {PCP_PDU_LABEL, "LABEL" },
325 { 0, NULL }
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 }
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 }
349 static const value_string packettypenames_pm_types[] = {
350 #define PM_TYPE_NOSUPPORT -1
351 { -1, "PM_TYPE_NOSUPPORT" },
352 #define PM_TYPE_32 0
353 { 0, "PM_TYPE_32" },
354 #define PM_TYPE_U32 1
355 { 1, "PM_TYPE_U32" },
356 #define PM_TYPE_64 2
357 { 2, "PM_TYPE_64" },
358 #define PM_TYPE_U64 3
359 { 3, "PM_TYPE_U64" },
360 #define PM_TYPE_FLOAT 4
361 { 4, "PM_TYPE_FLOAT" },
362 #define PM_TYPE_DOUBLE 5
363 { 5, "PM_TYPE_DOUBLE" },
364 #define PM_TYPE_STRING 6
365 { 6, "PM_TYPE_STRING" },
366 #define PM_TYPE_AGGREGATE 7
367 { 7, "PM_TYPE_AGGREGATE" },
368 #define PM_TYPE_AGGREGATE_STATIC 8
369 { 8, "PM_TYPE_AGGREGATE_STATIC" },
370 #define PM_TYPE_EVENT 9
371 { 9, "PM_TYPE_EVENT" },
372 #define PM_TYPE_UNKNOWN 255
373 { 255, "PM_TYPE_UNKNOWN" },
374 { 0, NULL }
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 }
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 }
392 static const value_string packettypenames_text_type_ident[] = {
393 #define PM_TEXT_PMID 4
394 { 1, "PM_TEXT_PMID" },
395 #define PM_TEXT_INDOM 8
396 { 2, "PM_TEXT_INDOM" },
397 { 0, NULL }
400 static const value_string packettypenames_valfmt[] = {
401 #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 }
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 }
469 static const value_string packettypenames_creds[]= {
470 { 1, "CVERSION" },
471 { 2, "CAUTH" },
472 { 0, NULL }
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 }
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;
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);
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_)
535 /* length is at the very start of the packet, after tcp header */
536 return (unsigned)tvb_get_ntohl(tvb, offset);
539 static void mark_this_frame_as_last_pmns_names_frame(packet_info *pinfo) {
540 pcp_conv_info_t *pcp_conv_info;
541 pcp_conv_info = get_pcp_conversation_info(pinfo);
543 if(pinfo->num > pcp_conv_info->last_pmns_names_frame) {
544 pcp_conv_info->last_pmns_names_frame = pinfo->num;
548 static inline int has_unprocessed_pmns_names_frame(pcp_conv_info_t *pcp_conv_info) {
549 return pcp_conv_info->last_pmns_names_frame > pcp_conv_info->last_processed_pmns_names_frame;
552 static inline int client_to_server(packet_info *pinfo) {
553 return pinfo->destport == PCP_PORT || pinfo->destport == PMPROXY_PORT;
556 static inline int server_to_client(packet_info *pinfo) {
557 return !client_to_server(pinfo);
560 static uint8_t* get_name_from_pmid(uint32_t pmid, packet_info *pinfo) {
561 uint8_t *name;
562 wmem_map_t *pmid_to_name;
564 pmid_to_name = get_pcp_conversation_info(pinfo)->pmid_to_name;
566 name = (uint8_t*)wmem_map_lookup(pmid_to_name, GINT_TO_POINTER(pmid));
567 if(!name) {
568 name = (uint8_t*)wmem_strdup(pinfo->pool, "Metric name unknown");
571 return name;
574 static const char *get_pcp_features_to_string(wmem_allocator_t *pool, uint16_t feature_flags)
576 const value_string *flag_under_test;
577 wmem_strbuf_t *string_buffer;
578 size_t string_length;
580 string_buffer = wmem_strbuf_new(pool, "");
582 /* Build the comma-separated list of feature flags as a string. EG 'SECURE, COMPRESS, AUTH, ' */
583 flag_under_test = &pcp_feature_flags[0];
584 while (flag_under_test->value) {
585 if (feature_flags & flag_under_test->value) {
586 wmem_strbuf_append_printf(string_buffer, "%s, ", flag_under_test->strptr);
588 flag_under_test++;
591 /* Cleanup the last remaining ', ' from the string */
592 string_length = wmem_strbuf_get_len(string_buffer);
593 if (string_length > 2) {
594 wmem_strbuf_truncate(string_buffer, string_length - 2);
597 return wmem_strbuf_get_str(string_buffer);
600 static pcp_conv_info_t* get_pcp_conversation_info(packet_info *pinfo) {
601 conversation_t *conversation;
602 pcp_conv_info_t *pcp_conv_info;
604 conversation = find_conversation_pinfo(pinfo, 0);
606 /* Conversation setup is done in the main dissecting routine so it should never be null */
607 DISSECTOR_ASSERT(conversation);
609 pcp_conv_info = (pcp_conv_info_t *)conversation_get_proto_data(conversation, proto_pcp);
611 /* Conversation data is initialized when creating the conversation so should never be null */
612 DISSECTOR_ASSERT(pcp_conv_info);
614 return pcp_conv_info;
617 static void add_candidate_name_for_pmid_resolution(packet_info *pinfo, tvbuff_t *tvb, int offset, int name_len) {
618 pcp_conv_info_t *pcp_conv_info;
619 uint8_t *name;
621 pcp_conv_info = get_pcp_conversation_info(pinfo);
623 if(is_unvisited_pmns_names_frame(pinfo)) {
624 name = tvb_get_string_enc(wmem_file_scope(), tvb, offset, name_len, ENC_ASCII);
625 wmem_array_append_one(pcp_conv_info->pmid_name_candidates, name);
629 static int is_unvisited_pmns_names_frame(packet_info *pinfo) {
630 pcp_conv_info_t *pcp_conv_info;
632 pcp_conv_info = get_pcp_conversation_info(pinfo);
634 return pinfo->num > pcp_conv_info->last_processed_pmns_names_frame && pinfo->num > pcp_conv_info->last_pmns_names_frame;
637 static void populate_pmids_to_names(packet_info *pinfo, tvbuff_t *tvb, int offset, uint32_t num_ids) {
638 pcp_conv_info_t *pcp_conv_info;
639 unsigned number_of_name_candidates;
641 pcp_conv_info = get_pcp_conversation_info(pinfo);
642 number_of_name_candidates = wmem_array_get_count(pcp_conv_info->pmid_name_candidates);
644 if(number_of_name_candidates == num_ids && has_unprocessed_pmns_names_frame(pcp_conv_info)) {
645 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 pcp_conv_info->last_processed_pmns_names_frame = pcp_conv_info->last_pmns_names_frame;
650 pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
653 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 uint32_t i;
656 for(i=0; i<num_ids; i++) {
657 uint32_t pmid;
658 uint8_t *pmid_name;
660 pmid = tvb_get_ntohl(tvb, offset);
661 pmid_name = *(uint8_t **)wmem_array_index(pcp_conv_info->pmid_name_candidates, i);
663 if(wmem_map_lookup(pcp_conv_info->pmid_to_name, GINT_TO_POINTER(pmid)) == NULL) {
664 wmem_map_insert(pcp_conv_info->pmid_to_name, GINT_TO_POINTER(pmid), pmid_name);
666 offset += 4;
670 static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
672 uint32_t creds_length;
673 uint32_t i;
675 /* append the type of packet */
676 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
677 val_to_str(PCP_PDU_CREDS, packettypenames, "Unknown Type:0x%02x"));
679 /* first is the number of creds */
680 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 creds_length = tvb_get_ntohl(tvb, offset);
683 offset += 4;
684 /* go through each __pmVersionCred struct */
685 for (i = 0; i < creds_length; i++) {
686 /* __pmVersionCred.c_type */
687 proto_tree_add_item(tree, hf_pcp_creds_type, tvb, offset, 1, ENC_BIG_ENDIAN);
688 offset += 1;
689 /* __pmVersionCred.c_version */
690 proto_tree_add_item(tree, hf_pcp_creds_version, tvb, offset, 1, ENC_BIG_ENDIAN);
691 offset += 1;
692 /* __pmVersionCred.c_flags */
693 offset = dissect_pcp_partial_features(tvb, pinfo, tree, offset);
695 return offset;
698 /* ERROR packet format:
699 signed int error
701 static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
703 int32_t error_num;
704 pcp_conv_info_t *pcp_conv_info;
706 /* append the type of packet, we can't look this up as it clashes with START */
707 col_append_str(pinfo->cinfo, COL_INFO, "[ERROR] ");
709 /* add the error item to the tree and column */
710 proto_tree_add_item(tree, hf_pcp_pdu_error, tvb, offset, 4, ENC_BIG_ENDIAN);
711 error_num = tvb_get_ntohl(tvb, offset);
712 col_append_fstr(pinfo->cinfo, COL_INFO, "error=%s ",
713 val_to_str(error_num, packettypenames_errors, "Unknown Error:%i"));
714 offset += 4;
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
719 if(error_num == PM_ERR_NAME) {
720 pcp_conv_info = get_pcp_conversation_info(pinfo);
721 pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
724 return offset;
727 /* START packet format:
728 unsigned int sts,
729 struct __pmPDUInfo
731 |> unsigned int zero : 1 bit
732 unsigned int version : 7 bits
733 unsigned int licensed : 8 bits
734 unsigned int features : 16 bits
736 static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
738 /* create a start tree to hold the information*/
739 proto_item *pcp_start_item;
740 proto_tree *pcp_start_tree;
741 uint32_t status;
743 pcp_start_item = proto_tree_add_item(tree, hf_pcp_start, tvb, 0, -1, ENC_NA);
744 pcp_start_tree = proto_item_add_subtree(pcp_start_item, ett_pcp);
746 /* append the type of packet, we can't look this up as it clashes with ERROR */
747 col_append_str(pinfo->cinfo, COL_INFO, "[START]");
749 /* status */
750 status = tvb_get_ntohl(tvb, offset);
751 proto_tree_add_item(pcp_start_tree, hf_pcp_start_status, tvb, offset, 4, ENC_BIG_ENDIAN);
752 offset += 4;
753 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 if(status == PCP_SECURE_ACK_SUCCESSFUL) {
756 expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade);
757 ssl_starttls_ack(find_dissector("tls"), pinfo, pcp_handle);
759 else {
760 expert_add_info(pinfo, tree, &ei_pcp_ssl_upgrade_failed);
763 else {
764 /* zero bit and version bits */
765 proto_tree_add_item(pcp_start_tree, hf_pcp_start_zero, tvb, offset, 1, ENC_BIG_ENDIAN);
766 proto_tree_add_item(pcp_start_tree, hf_pcp_start_version, tvb, offset, 1, ENC_BIG_ENDIAN);
767 offset += 1;
768 /* licensed */
769 proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN);
770 offset += 1;
771 /* features */
772 offset = dissect_pcp_partial_features(tvb, pinfo, pcp_start_tree, offset);
774 return offset;
777 /* PMNS_TRAVERSE packet format:
778 uint32_t subtype
779 uint32_t namelen
780 char name[sizeof(namelen)] + padding
782 static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
784 proto_item *pcp_pmns_traverse_item;
785 proto_tree *pcp_pmns_traverse_tree;
786 uint32_t name_len;
787 uint32_t padding;
789 /* append the type of packet */
790 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
791 val_to_str(PCP_PDU_PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x"));
793 pcp_pmns_traverse_item = proto_tree_add_item(tree, hf_pcp_pmns_traverse, tvb, offset, -1, ENC_NA);
794 pcp_pmns_traverse_tree = proto_item_add_subtree(pcp_pmns_traverse_item, ett_pcp);
796 /* subtype */
797 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
798 offset += 4;
799 /* namelen */
800 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
801 name_len = tvb_get_ntohl(tvb, offset); /* get the actual length out so we can use it in the next item */
802 offset += 4;
803 /* name */
804 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII);
805 offset += name_len; /* increment by whatever the length of the name string was */
807 /* "padding" (not really padding, just what is left over in the old buffer) */
808 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
809 if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
810 padding = 4 - padding; /* we want the inverse of the remainder */
812 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
813 offset += padding;
815 return offset;
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)
824 | |> -- name_t --
825 | int namelen
826 | char name[sizeof(namelen)]
828 |> -- name_status_t --
829 int status
830 int namelen
831 char name[sizeof(namelen)]
833 static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
835 proto_item *pcp_pmns_names_item;
836 proto_tree *pcp_pmns_names_tree;
837 proto_item *pcp_pmns_names_name_item;
838 proto_tree *pcp_pmns_names_name_tree;
839 uint32_t is_pmns_names_status;
840 uint32_t num_names;
841 uint32_t name_len;
842 uint32_t full_name_len;
843 uint32_t padding;
844 uint32_t i;
846 /* append the type of packet */
847 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_NAMES, packettypenames, "Unknown Type:0x%02x"));
849 pcp_pmns_names_item = proto_tree_add_item(tree, hf_pcp_pmns_names, tvb, offset, -1, ENC_NA);
850 pcp_pmns_names_tree = proto_item_add_subtree(pcp_pmns_names_item, ett_pcp);
852 /* nstrbytes */
853 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nstrbytes, tvb, offset, 4, ENC_BIG_ENDIAN);
854 offset += 4;
856 /* numstatus */
857 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numstatus, tvb, offset, 4, ENC_BIG_ENDIAN);
858 is_pmns_names_status = tvb_get_ntohl(tvb, offset); /* is the status also present in this PDU? */
859 offset += 4;
861 /* numnames */
862 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numnames, tvb, offset, 4, ENC_BIG_ENDIAN);
863 num_names = tvb_get_ntohl(tvb, offset); /* get the number of names to iterate through */
864 offset += 4;
866 /* nametrees */
867 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 if (is_pmns_names_status) {
870 name_len = tvb_get_ntohl(tvb, offset+4);
871 full_name_len = name_len + 8;
872 } else {
873 name_len = tvb_get_ntohl(tvb, offset);
874 full_name_len = name_len + 4;
876 /* add a new subtree for each name */
877 pcp_pmns_names_name_item = proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nametree,
878 tvb, offset, full_name_len, ENC_NA);
879 pcp_pmns_names_name_tree = proto_item_add_subtree(pcp_pmns_names_name_item, ett_pcp);
881 if (is_pmns_names_status) {
882 /* print out the name status and increment if we're supposed to have it */
883 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_status,
884 tvb, offset, 4, ENC_BIG_ENDIAN);
885 offset += 4;
887 /* namelen */
888 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_namelen,
889 tvb, offset, 4, ENC_BIG_ENDIAN);
890 offset += 4;
891 /* name */
892 if(client_to_server(pinfo)) {
893 add_candidate_name_for_pmid_resolution(pinfo, tvb, offset, name_len);
895 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_name,
896 tvb, offset, name_len, ENC_ASCII);
897 offset += name_len;
898 /* padding */
899 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
900 if (padding != 0) {
901 padding = 4 - padding; /* we want the inverse of the remainder */
902 /* if there is padding, keep going till the remainder of mod 8 */
903 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
904 offset += padding;
907 if(client_to_server(pinfo)) {
908 mark_this_frame_as_last_pmns_names_frame(pinfo);
910 return offset;
913 /* PMNS_CHILD packet format:
914 uint32_t subtype
915 uint32_t namelen
916 char name[namelen]
918 static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
920 proto_item *pcp_pmns_child_item;
921 proto_tree *pcp_pmns_child_tree;
922 uint32_t name_len;
924 pcp_pmns_child_item = proto_tree_add_item(tree, hf_pcp_pmns_child, tvb, offset, -1, ENC_NA);
925 pcp_pmns_child_tree = proto_item_add_subtree(pcp_pmns_child_item, ett_pcp);
927 /* append the type of packet */
928 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PMNS_CHILD, packettypenames, "Unknown Type:0x%02x"));
930 /* subtype */
931 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
932 offset += 4;
934 /* namelen */
935 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
936 name_len = tvb_get_ntohl(tvb, offset); /* length of the next value */
937 offset += 4;
939 /* name */
940 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII);
941 offset += 4;
942 return offset;
945 /* PMNS_IDS packet format
946 uint32_t status
947 uint32_t numids
948 pmID idlist[numids] (where pmID = uint32)
951 static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
953 proto_item *pcp_pmns_ids_item;
954 proto_tree *pcp_pmns_ids_tree;
955 uint32_t num_ids;
956 uint32_t i;
958 /* append the type of packet */
959 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
960 val_to_str(PCP_PDU_PMNS_IDS, packettypenames, "Unknown Type:0x%02x"));
962 pcp_pmns_ids_item = proto_tree_add_item(tree, hf_pcp_pmns_ids, tvb, offset, -1, ENC_NA);
963 pcp_pmns_ids_tree = proto_item_add_subtree(pcp_pmns_ids_item, ett_pcp);
965 /* status */
966 proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_status, tvb, offset, 4, ENC_BIG_ENDIAN);
967 offset += 4;
969 /* numids */
970 proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_numids, tvb, offset, 4, ENC_BIG_ENDIAN);
971 num_ids = tvb_get_ntohl(tvb, offset);
972 offset += 4;
974 /* Populate the PMID to name mapping */
975 populate_pmids_to_names(pinfo, tvb, offset, num_ids);
977 /* pmIDs */
978 for (i=0; i<num_ids; i++) {
979 /* pmID */
980 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_pmns_ids_tree, offset);
982 return offset;
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]
992 |> pmInDom indom;
993 int state;
994 int numinst;
995 int pad;
997 static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
999 proto_item *pcp_profile_item;
1000 proto_tree *pcp_profile_tree;
1001 proto_item *pcp_profile_profile_item;
1002 proto_tree *pcp_profile_profile_tree;
1003 uint32_t num_prof;
1004 uint32_t i;
1006 /* append the type of packet */
1007 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_PROFILE, packettypenames, "Unknown Type:0x%02x"));
1009 pcp_profile_item = proto_tree_add_item(tree, hf_pcp_profile, tvb, offset, -1, ENC_NA);
1010 pcp_profile_tree = proto_item_add_subtree(pcp_profile_item, ett_pcp);
1012 /* ctxnum */
1013 proto_tree_add_item(pcp_profile_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
1014 offset += 4;
1016 /* g_state */
1017 proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_g_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1018 offset += 4;
1020 /* numprof */
1021 proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_numprof, tvb, offset, 4, ENC_BIG_ENDIAN);
1022 num_prof = tvb_get_ntohl(tvb, offset);
1023 offset += 4;
1025 /* pad */
1026 proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
1027 offset += 4;
1029 /* iterate through each profile */
1030 for (i=0; i<num_prof; i++) {
1031 /* subtree for each profile */
1032 pcp_profile_profile_item = proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_profile, tvb, offset, 32, ENC_NA);
1033 pcp_profile_profile_tree = proto_item_add_subtree(pcp_profile_profile_item, ett_pcp);
1035 /* indom */
1036 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1037 offset += 4;
1039 /* state - include/exclude */
1040 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1041 offset += 4;
1043 /* numinst - number of instances to follow */
1044 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
1045 offset += 4;
1047 /* padding */
1048 proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
1049 offset += 4;
1051 return offset;
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)
1060 static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1062 proto_item *pcp_fetch_item;
1063 proto_tree *pcp_fetch_tree;
1064 uint32_t num_pmid;
1065 uint32_t i;
1067 /* append the type of packet */
1068 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
1069 val_to_str(PCP_PDU_FETCH, packettypenames, "Unknown Type:0x%02x"));
1071 pcp_fetch_item = proto_tree_add_item(tree, hf_pcp_fetch, tvb, offset, -1, ENC_NA);
1072 pcp_fetch_tree = proto_item_add_subtree(pcp_fetch_item, ett_pcp);
1074 /* ctxnum */
1075 proto_tree_add_item(pcp_fetch_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
1076 offset += 4;
1078 /* when */
1079 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_fetch_tree, offset);
1081 /* numpmid */
1082 proto_tree_add_item(pcp_fetch_tree, hf_pcp_fetch_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1083 num_pmid = tvb_get_ntohl(tvb, offset);
1084 offset += 4;
1086 /* pmIDs*/
1087 for (i=0; i<num_pmid; i++) {
1088 /* decode partial PMID message */
1089 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_fetch_tree, offset);
1091 return offset;
1094 /* RESULT packet format
1096 __pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
1097 int numpmid
1098 _pmPDU data[1-n] (contains v_list types)
1100 |> pmID pmid
1101 int numval
1102 int valfmt
1103 __pmValue_PDU vlist[1-n] (contains pmValue PDUs)
1105 |> int inst
1106 int offset/value
1107 (if valfmt == PTR type)
1108 int8 type
1109 int24 length
1110 char value[length]
1112 static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1114 proto_item *pcp_results_item;
1115 proto_tree *pcp_results_tree;
1116 proto_item *pcp_result_item;
1117 proto_tree *pcp_result_tree;
1118 proto_item *pcp_result_instance_item;
1119 proto_tree *pcp_result_instance_tree;
1120 uint32_t num_pmid;
1121 uint32_t num_val;
1122 uint32_t offset_start;
1123 uint32_t valfmt_type;
1124 uint32_t value_type;
1125 uint32_t pmvalueblock_offset;
1126 uint32_t pmvalueblock_value_length;
1127 uint32_t i;
1128 uint32_t j;
1130 /* append the type of packet */
1131 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_RESULT, packettypenames, "Unknown Type:0x%02x"));
1133 pcp_results_item = proto_tree_add_item(tree, hf_pcp_results, tvb, offset, -1, ENC_NA);
1134 pcp_results_tree = proto_item_add_subtree(pcp_results_item, ett_pcp);
1136 /* when */
1137 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_results_tree, offset);
1139 /* numpmid */
1140 proto_tree_add_item(pcp_results_tree, hf_pcp_results_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1141 num_pmid = tvb_get_ntohl(tvb, offset);
1142 offset += 4;
1144 /* result */
1145 for (i=0; i<num_pmid; i++) {
1146 /* work out how long each result should be - set starting offset */
1147 offset_start = offset;
1149 pcp_result_item = proto_tree_add_item(pcp_results_tree, hf_pcp_result, tvb, offset, -1, ENC_NA);
1150 pcp_result_tree = proto_item_add_subtree(pcp_result_item, ett_pcp);
1152 /* pmID */
1153 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_result_tree, offset);
1155 /* numval */
1156 proto_tree_add_item(pcp_result_tree, hf_pcp_result_numval, tvb, offset, 4, ENC_BIG_ENDIAN);
1157 num_val = tvb_get_ntohl(tvb, offset);
1158 offset += 4;
1160 /* if there are no numvals, then the valfmt isn't sent */
1161 if (num_val > 0) {
1163 /* valfmt */
1164 proto_tree_add_item(pcp_result_tree, hf_pcp_result_valfmt, tvb, offset, 4, ENC_BIG_ENDIAN);
1165 valfmt_type = tvb_get_ntohl(tvb, offset);
1166 offset += 4;
1168 /* instance */
1169 for (j=0; j<num_val; j++) {
1170 /* give the subtree name length of inst (int) + offset/va (int) */
1171 pcp_result_instance_item = proto_tree_add_item(pcp_result_tree, hf_pcp_instance,
1172 tvb, offset, 8, ENC_NA);
1173 pcp_result_instance_tree = proto_item_add_subtree(pcp_result_instance_item, ett_pcp);
1175 /* inst */
1176 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1177 offset += 4;
1179 /* valoffset/value: depending on the format, the next 32 bits is the value _OR_ the offset to where
1180 the value is */
1181 if (valfmt_type == PM_VAL_INSITU) {
1182 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_insitu,
1183 tvb, offset, 4, ENC_BIG_ENDIAN);
1184 } else {
1185 /* offset in the packet to find pmValueBlock */
1186 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_valoffset,
1187 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 pmvalueblock_offset = tvb_get_ntohl(tvb, offset);
1190 pmvalueblock_offset = pmvalueblock_offset * 4; /* offset values are in 32bit units */
1192 /* type */
1193 value_type = tvb_get_uint8(tvb, pmvalueblock_offset);
1194 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_type,
1195 tvb, pmvalueblock_offset, 1, ENC_BIG_ENDIAN);
1196 pmvalueblock_offset += 1;
1198 /* length */
1199 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 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_vallength,
1202 tvb, pmvalueblock_offset, 3, ENC_BIG_ENDIAN);
1203 pmvalueblock_offset += 3;
1205 /* value - note we go up to the pmvalueblock_value_length - 4,
1206 as this value includes the previous 4 bytes */
1207 switch (value_type) {
1208 case PM_TYPE_32:
1209 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int, tvb,
1210 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1211 break;
1212 case PM_TYPE_U32:
1213 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint, tvb,
1214 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1215 break;
1216 case PM_TYPE_64:
1217 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int64, tvb,
1218 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1219 break;
1220 case PM_TYPE_U64:
1221 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint64, tvb,
1222 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1223 break;
1224 case PM_TYPE_FLOAT:
1225 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_float, tvb,
1226 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1227 break;
1228 case PM_TYPE_DOUBLE:
1229 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_double, tvb,
1230 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
1231 break;
1232 case PM_TYPE_STRING:
1233 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_ptr, tvb,
1234 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_ASCII);
1235 break;
1236 case PM_TYPE_AGGREGATE:
1237 case PM_TYPE_AGGREGATE_STATIC:
1238 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_aggr, tvb,
1239 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_NA);
1240 break;
1241 case PM_TYPE_EVENT:
1242 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_event_unimplemented);
1243 break;
1244 case PM_TYPE_NOSUPPORT:
1245 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_nosupport_unsupported);
1246 break;
1247 case PM_TYPE_UNKNOWN:
1248 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_unknown_unknown_value);
1249 break;
1250 default:
1251 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_unimplemented_value);
1252 break;
1255 /* bump the offset after the instance value _or_ the offset into
1256 the packet (pcp.instance.valoffset) , each being 4 bytes */
1257 offset += 4;
1261 /* we now know how long the field is */
1262 proto_item_set_len(pcp_result_tree, offset-offset_start);
1265 return offset;
1268 /* DESC_REQ pcaket format
1269 pmID pmid (32bit int)
1271 static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1273 proto_item *pcp_desc_req_item;
1274 proto_tree *pcp_desc_req_tree;
1276 /* append the type of packet */
1277 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC_REQ, packettypenames, "Unknown Type:0x%02x"));
1279 /* subtree for packet type */
1280 pcp_desc_req_item = proto_tree_add_item(tree, hf_pcp_desc_req, tvb, offset, -1, ENC_NA);
1281 pcp_desc_req_tree = proto_item_add_subtree(pcp_desc_req_item, ett_pcp);
1283 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_req_tree, offset);
1285 return offset;
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
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
1304 static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1306 proto_item *pcp_desc_item;
1307 proto_tree *pcp_desc_tree;
1308 proto_item *pcp_desc_units_item;
1309 proto_tree *pcp_desc_units_tree;
1310 uint32_t bits_offset;
1312 /* append the type of packet */
1313 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_DESC, packettypenames, "Unknown Type:0x%02x"));
1315 /* root desc tree */
1316 pcp_desc_item = proto_tree_add_item(tree, hf_pcp_desc, tvb, offset, 4, ENC_NA);
1317 pcp_desc_tree = proto_item_add_subtree(pcp_desc_item, ett_pcp);
1319 /* pmID */
1320 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_tree, offset);
1322 /* type */
1323 proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1324 offset += 4;
1326 /* indom */
1327 proto_tree_add_item(pcp_desc_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1328 offset += 4;
1330 /* sem */
1331 proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_sem, tvb, offset, 4, ENC_BIG_ENDIAN);
1332 offset += 4;
1334 /* pmUnits */
1335 bits_offset = offset*8; /* create the bits offset */
1336 pcp_desc_units_item = proto_tree_add_item(pcp_desc_tree, hf_pcp_units, tvb, offset, -1, ENC_NA);
1337 pcp_desc_units_tree = proto_item_add_subtree(pcp_desc_units_item, ett_pcp);
1339 /* dimspace */
1340 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimspace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1341 bits_offset += 4;
1342 /* dimtime */
1343 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimtime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1344 bits_offset += 4;
1345 /* dimcount */
1346 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimcount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1347 bits_offset += 4;
1348 /* scalespace */
1349 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalespace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1350 bits_offset += 4;
1351 /* scaletime */
1352 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scaletime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1353 bits_offset += 4;
1354 /* scalecount */
1355 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 offset += 3; /* total offset of pmunits before */
1359 proto_tree_add_item(pcp_desc_units_tree, hf_pcp_pdu_padding, tvb, offset, 1, ENC_NA);
1360 offset += 1;
1361 /*bits_offset += 8;*/
1362 return offset;
1366 /* INSTANCE_REQ packet format
1367 pmInDom indom
1368 __pmTimeval when
1369 int inst
1370 int namelen
1371 char name
1373 static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1375 proto_item *pcp_instance_req_item;
1376 proto_tree *pcp_instance_req_tree;
1377 uint32_t name_len;
1379 /* append the type of packet */
1380 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x"));
1382 pcp_instance_req_item = proto_tree_add_item(tree, hf_pcp_instance_req, tvb, offset, -1, ENC_NA);
1383 pcp_instance_req_tree = proto_item_add_subtree(pcp_instance_req_item, ett_pcp);
1385 /* indom */
1386 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1387 offset += 4;
1389 /* when */
1390 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_instance_req_tree, offset);
1392 /* inst */
1393 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1394 offset += 4;
1396 /* namelen */
1397 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1398 name_len = tvb_get_ntohl(tvb, offset);
1399 offset += 4;
1401 /* name */
1402 if (name_len > 0) {
1403 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII);
1404 offset += name_len;
1406 return offset;
1409 /* TEXT_REQ packet format
1410 int ident
1411 int type
1413 static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1415 proto_item *pcp_text_req_item;
1416 proto_tree *pcp_text_req_tree;
1417 proto_item *pcp_text_req_type_item;
1418 proto_tree *pcp_text_req_type_tree;
1419 uint32_t bits_offset;
1420 uint32_t type;
1422 /* append the type of packet */
1423 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT_REQ, packettypenames, "Unknown Type:0x%02x"));
1425 pcp_text_req_item = proto_tree_add_item(tree, hf_pcp_text_req, tvb, offset, -1, ENC_NA);
1426 pcp_text_req_tree = proto_item_add_subtree(pcp_text_req_item, ett_pcp);
1428 /* peek at type to decode ident correctly */
1429 type = tvb_get_ntohl(tvb, offset + 4);
1431 /* ident */
1432 if (type & PM_TEXT_PMID) {
1433 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_text_req_tree, offset);
1434 } else if (type & PM_TEXT_INDOM) {
1435 proto_tree_add_item(pcp_text_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1436 offset += 4;
1439 /* type */
1440 pcp_text_req_type_item = proto_tree_add_item(pcp_text_req_tree, hf_pcp_text_type, tvb, offset, 4, ENC_NA);
1441 pcp_text_req_type_tree = proto_item_add_subtree(pcp_text_req_type_item, ett_pcp);
1442 bits_offset = offset * 8 + 28;
1443 proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_ident, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1444 bits_offset += 2;
1445 proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_format, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1447 offset += 4;
1448 return offset;
1451 /* TEXT packet format
1452 int ident
1453 int buflen
1454 char buffer
1456 static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1458 proto_item *pcp_text_item;
1459 proto_tree *pcp_text_tree;
1460 uint32_t buflen;
1462 /* append the type of packet */
1463 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_TEXT, packettypenames, "Unknown Type:0x%02x"));
1465 pcp_text_item = proto_tree_add_item(tree, hf_pcp_text, tvb, offset, -1, ENC_NA);
1466 pcp_text_tree = proto_item_add_subtree(pcp_text_item, ett_pcp);
1468 /* ident */
1469 proto_tree_add_item(pcp_text_tree, hf_pcp_text_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1470 offset += 4;
1472 /* buflen */
1473 buflen = tvb_get_ntohl(tvb, offset);
1474 proto_tree_add_item(pcp_text_tree, hf_pcp_text_buflen, tvb, offset, 4, ENC_BIG_ENDIAN);
1475 offset += 4;
1477 /* buffer */
1478 proto_tree_add_item(pcp_text_tree, hf_pcp_text_buffer, tvb, offset, buflen, ENC_ASCII);
1479 offset += buflen;
1481 return offset;
1484 /* USER_AUTH packet format
1485 int ident
1486 int buflen
1487 char buffer
1489 static int dissect_pcp_message_user_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1491 /* append the type of packet */
1492 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_USER_AUTH, packettypenames, "Unknown Type:0x%02x"));
1494 proto_tree_add_item(tree, hf_pcp_user_auth_payload, tvb, offset, -1, ENC_NA);
1496 return tvb_reported_length(tvb);
1499 /* LABEL_REQ packet format
1500 int ident
1501 int type
1503 static int dissect_pcp_message_label_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1505 /* append the type of packet */
1506 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_LABEL_REQ, packettypenames, "Unknown Type:0x%02x"));
1508 proto_item *pcp_label_req_item = proto_tree_add_item(tree, hf_pcp_label_req, tvb, offset, -1, ENC_NA);
1509 proto_tree *pcp_label_req_tree = proto_item_add_subtree(pcp_label_req_item, ett_pcp);
1511 /* ident */
1512 proto_tree_add_item(pcp_label_req_tree, hf_pcp_label_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1513 offset += 4;
1515 /* type */
1516 proto_tree_add_item(pcp_label_req_tree, hf_pcp_label_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1517 offset += 4;
1519 return offset;
1522 /* LABEL packet format
1523 int ident
1524 int type
1525 int padding;
1526 int nsets;
1527 labelset_t sets[1];
1529 |> int inst
1530 int nlabels
1531 int json
1532 int jsonlen
1533 pmLabel labels[0]
1535 static int dissect_pcp_message_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1537 /* append the type of packet */
1538 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_LABEL, packettypenames, "Unknown Type:0x%02x"));
1540 proto_item *pcp_label_item = proto_tree_add_item(tree, hf_pcp_label, tvb, offset, -1, ENC_NA);
1541 proto_tree *pcp_label_tree = proto_item_add_subtree(pcp_label_item, ett_pcp);
1543 /* ident */
1544 proto_tree_add_item(pcp_label_tree, hf_pcp_label_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1545 offset += 4;
1547 /* type */
1548 proto_tree_add_item(pcp_label_tree, hf_pcp_label_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1549 offset += 4;
1551 /* padding */
1552 proto_tree_add_item(pcp_label_tree, hf_pcp_label_padding, tvb, offset, 4, ENC_NA);
1553 offset += 4;
1555 /* number of label sets */
1556 int32_t nsets;
1557 proto_tree_add_item_ret_int(pcp_label_tree, hf_pcp_label_nsets, tvb, offset, 4, ENC_NA, &nsets);
1558 offset += 4;
1561 for (int32_t i = 0; i < nsets; i++) {
1562 offset = dissect_pcp_partial_labelset(tvb, pcp_label_tree, pinfo, offset);
1565 return offset;
1568 /* INSTANCE packet type
1569 pmInDom indom
1570 int numinst
1571 instlist_t instlist[numinst]
1573 |> int inst
1574 int namelen
1575 char name
1577 static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1579 proto_item *pcp_instances_item;
1580 proto_tree *pcp_instances_tree;
1581 proto_item *pcp_instance_item;
1582 proto_tree *pcp_instance_tree;
1583 uint32_t num_inst;
1584 uint32_t i;
1585 uint32_t name_len;
1586 uint32_t padding;
1588 /* append the type of packet */
1589 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PCP_PDU_INSTANCE, packettypenames, "Unknown Type:0x%02x"));
1591 pcp_instances_item = proto_tree_add_item(tree, hf_pcp_instances, tvb, offset, -1, ENC_NA);
1592 pcp_instances_tree = proto_item_add_subtree(pcp_instances_item, ett_pcp);
1594 /* indom */
1595 proto_tree_add_item(pcp_instances_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1596 offset += 4;
1597 /* numinst */
1598 proto_tree_add_item(pcp_instances_tree, hf_pcp_instances_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
1599 num_inst = tvb_get_ntohl(tvb, offset);
1600 offset += 4;
1602 /* instlist */
1603 for (i=0; i<num_inst; i++) {
1604 /* get the size of the name first, so we know how much offset to give */
1605 name_len = tvb_get_ntohl(tvb, offset+4);
1607 /* give the subtree name length + 2 ints */
1608 pcp_instance_item = proto_tree_add_item(pcp_instances_tree, hf_pcp_instance, tvb, offset, name_len+8, ENC_NA);
1609 pcp_instance_tree = proto_item_add_subtree(pcp_instance_item, ett_pcp);
1611 /* inst */
1612 proto_tree_add_item(pcp_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1613 offset += 4;
1615 /* namelen */
1616 proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1617 offset += 4;
1619 /* name */
1620 if (name_len > 0) {
1621 proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII);
1622 offset += name_len;
1625 /* padding */
1626 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
1627 if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
1628 padding = 4 - padding; /* we want the inverse of the remainder */
1630 proto_tree_add_item(pcp_instance_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
1631 offset += padding;
1634 return offset;
1637 /* PARTIAL DISSECTOR ROUTINES
1638 these routines are called by dissect_pcp_message_* as needed
1641 static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1643 proto_item *pcp_pmid_item;
1644 proto_tree *pcp_pmid_tree;
1645 uint32_t bits_offset;
1646 uint32_t pmid;
1647 uint8_t *name;
1649 bits_offset = offset * 8;
1651 pmid = tvb_get_ntohl(tvb, offset);
1652 name = get_name_from_pmid(pmid, pinfo);
1654 /* subtree for pmid */
1655 pcp_pmid_item = proto_tree_add_item(tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1656 proto_item_append_text(pcp_pmid_item, " (%s)", name);
1657 pcp_pmid_tree = proto_item_add_subtree(pcp_pmid_item, ett_pcp);
1659 /* flag - 1 bit */
1660 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
1661 bits_offset += 1;
1662 /* domain - 9 bits */
1663 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
1664 bits_offset += 9;
1665 /* cluster - 12 bits */
1666 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
1667 bits_offset += 12;
1668 /* item - 10 bits */
1669 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
1670 offset += 4;
1672 return offset;
1675 static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1677 proto_item *pcp_when_item;
1678 proto_tree *pcp_when_tree;
1680 /* when - create a new subtree for each val */
1681 pcp_when_item = proto_tree_add_item(tree, hf_pcp_when, tvb, offset, 8, ENC_NA);
1682 pcp_when_tree = proto_item_add_subtree(pcp_when_item, ett_pcp);
1684 /* when tv_sec */
1685 proto_tree_add_item(pcp_when_tree, hf_pcp_when_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
1686 offset += 4;
1687 /* when tv_usec */
1688 proto_tree_add_item(pcp_when_tree, hf_pcp_when_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
1689 offset += 4;
1691 return offset;
1694 static int dissect_pcp_partial_features(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1696 uint16_t feature_flags;
1697 const char *feature_flags_string;
1699 static int * const pcp_feature_flags_header_fields[] = {
1700 &hf_pcp_features_flags_labels,
1701 &hf_pcp_features_flags_bad_label,
1702 &hf_pcp_features_flags_cert_reqd,
1703 &hf_pcp_features_flags_container,
1704 &hf_pcp_features_flags_no_nss_init,
1705 &hf_pcp_features_flags_secure_ack,
1706 &hf_pcp_features_flags_creds_reqd,
1707 &hf_pcp_features_flags_auth,
1708 &hf_pcp_features_flags_compress,
1709 &hf_pcp_features_flags_secure,
1710 NULL
1713 feature_flags = tvb_get_ntohs(tvb, offset);
1714 feature_flags_string = get_pcp_features_to_string(pinfo->pool, feature_flags);
1716 col_append_fstr(pinfo->cinfo, COL_INFO, " Features=[%s]", feature_flags_string);
1718 proto_tree_add_bitmask(tree, tvb, offset, hf_pcp_features_flags, ett_pcp_start_features, pcp_feature_flags_header_fields, ENC_BIG_ENDIAN);
1719 offset += 2;
1721 if ((feature_flags & PCP_PDU_FLAG_LABELS) == PCP_PDU_FLAG_LABELS && server_to_client(pinfo)) {
1722 pcp_conv_info_t *pcp_conv_info = get_pcp_conversation_info(pinfo);
1723 pcp_conv_info->using_good_labels = true;
1726 return offset;
1729 static int dissect_pcp_partial_labelset(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1731 proto_item *pcp_label_sets_item = proto_tree_add_item(tree, hf_pcp_label_sets, tvb, offset, -1, ENC_NA);
1732 proto_tree *pcp_label_sets_tree = proto_item_add_subtree(pcp_label_sets_item, ett_pcp);
1734 /* Instance */
1735 proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1736 offset += 4;
1738 /* Number of labels or error */
1739 int32_t nlabels_or_error = tvb_get_ntohl(tvb, offset);
1740 proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_nlabels, tvb, offset, 4, ENC_BIG_ENDIAN);
1741 offset += 4;
1742 if (nlabels_or_error < 0) {
1743 expert_add_info(pinfo, pcp_label_sets_tree, &ei_pcp_label_error);
1746 /* Offset to start of JSON */
1747 uint32_t json_start_offset = tvb_get_ntohl(tvb, offset);
1748 proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_json, tvb, offset, 4, ENC_BIG_ENDIAN);
1749 offset += 4;
1751 /* Length of JSON string */
1752 proto_tree_add_item(pcp_label_sets_tree, hf_pcp_label_sets_jsonlen, tvb, offset, 4, ENC_BIG_ENDIAN);
1753 offset += 4;
1755 /* pmLabels */
1756 for (int i = 0; i < nlabels_or_error; i++) {
1757 offset = dissect_pcp_partial_label(tvb, pinfo, pcp_label_sets_tree, offset, json_start_offset);
1760 /* Fix up end length */
1761 proto_item_set_end(pcp_label_sets_item, tvb, offset);
1763 return offset;
1767 static int dissect_pcp_partial_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint32_t json_start_offset)
1769 proto_item *pcp_label_sets_label_item = proto_tree_add_item(tree, hf_pcp_label_sets_labels, tvb, offset, -1, ENC_NA);
1770 proto_tree *pcp_label_sets_label_tree = proto_item_add_subtree(pcp_label_sets_label_item, ett_pcp);
1772 /* Name offset*/
1773 uint16_t name_offset = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1774 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_nameoffset, tvb, offset, 2, ENC_BIG_ENDIAN);
1775 offset += 2;
1777 /* Name length */
1778 uint32_t name_length = tvb_get_uint8(tvb, offset);
1779 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_namelen, tvb, offset, 1, ENC_NA);
1780 offset += 1;
1782 /* Flags */
1783 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_flags, tvb, offset, 1, ENC_NA);
1784 offset += 1;
1786 /* Value offset */
1787 uint16_t value_offset = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1788 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valueoffset, tvb, offset, 2, ENC_BIG_ENDIAN);
1789 offset += 2;
1791 /* Value Length */
1792 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.
1798 if(is_using_good_labels(pinfo)) {
1799 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_BIG_ENDIAN);
1801 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 value_length = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1804 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1805 expert_add_info(pinfo, pcp_label_sets_label_tree, &ei_pcp_label_error_endianness);
1806 } else {
1807 proto_tree_add_item(pcp_label_sets_label_tree, hf_pcp_label_sets_labels_valuelen, tvb, offset, 2, ENC_BIG_ENDIAN);
1808 expert_add_info(pinfo, pcp_label_sets_label_tree, &ei_pcp_label_error_endianness);
1810 offset += 2;
1812 /* Name */
1813 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);
1815 /* Value */
1816 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);
1818 /* Add to subtree */
1819 uint8_t *name = tvb_get_string_enc(pinfo->pool, tvb, json_start_offset + name_offset, name_length, ENC_ASCII | ENC_NA);
1820 uint8_t *value = tvb_get_string_enc(pinfo->pool, tvb, json_start_offset + value_offset, value_length, ENC_ASCII | ENC_NA);
1821 proto_item_append_text(pcp_label_sets_label_item, " (%s:%s)", name, value);
1823 proto_item_set_end(pcp_label_sets_label_item, tvb, offset);
1825 return offset;
1828 static bool is_using_good_labels(packet_info *pinfo)
1830 /* Try to establish if we've got good labels from an earlier START PDU */
1831 return get_pcp_conversation_info(pinfo)->using_good_labels;
1834 static bool label_value_length_looks_like_wrong_endianness(tvbuff_t *tvb, uint16_t value_offset, uint16_t value_length)
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.
1840 return tvb_reported_length(tvb) < ((unsigned)value_offset + (unsigned)value_length);
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_)
1846 proto_item *root_pcp_item;
1847 proto_tree *pcp_tree;
1848 conversation_t *conversation;
1849 pcp_conv_info_t *pcp_conv_info;
1850 uint32_t packet_type;
1851 int32_t err_bytes;
1852 int offset = 0;
1854 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCP");
1855 col_clear(pinfo->cinfo, COL_INFO);
1858 conversation = find_or_create_conversation(pinfo);
1860 pcp_conv_info = (pcp_conv_info_t*)conversation_get_proto_data(conversation, proto_pcp);
1862 if(pcp_conv_info == NULL) {
1863 pcp_conv_info = wmem_new(wmem_file_scope(), pcp_conv_info_t);
1864 conversation_add_proto_data(conversation, proto_pcp, pcp_conv_info);
1866 pcp_conv_info->pmid_name_candidates = wmem_array_new(wmem_file_scope(), sizeof(uint8_t *));
1867 pcp_conv_info->pmid_to_name = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
1868 pcp_conv_info->last_pmns_names_frame = 0;
1869 pcp_conv_info->last_processed_pmns_names_frame = 0;
1870 pcp_conv_info->using_good_labels = false;
1873 root_pcp_item = proto_tree_add_item(tree, proto_pcp, tvb, 0, -1, ENC_NA);
1874 pcp_tree = proto_item_add_subtree(root_pcp_item, ett_pcp);
1876 packet_type = tvb_get_ntohl(tvb, 4);
1878 /* check if we are the client requesting or the server */
1879 if (server_to_client(pinfo)) {
1880 col_set_str(pinfo->cinfo, COL_INFO, "Server > Client ");
1881 } else {
1882 col_set_str(pinfo->cinfo, COL_INFO, "Client > Server ");
1885 /* PCP packet length */
1886 proto_tree_add_item(pcp_tree, hf_pcp_pdu_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1887 offset += 4;
1888 /* PCP Packet type */
1889 proto_tree_add_item(pcp_tree, hf_pcp_pdu_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1890 offset += 4;
1891 /* PCP Remote PID */
1892 proto_tree_add_item(pcp_tree, hf_pcp_pdu_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
1893 offset += 4;
1895 /* dissect the rest of the packet depending on the type */
1896 switch (packet_type) {
1897 case PCP_PDU_CREDS:
1898 dissect_pcp_message_creds(tvb, pinfo, pcp_tree, offset);
1899 break;
1901 case PCP_PDU_START_OR_ERROR:
1902 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 if (err_bytes < 0) {
1906 dissect_pcp_message_error(tvb, pinfo, pcp_tree, offset);
1907 } else {
1908 dissect_pcp_message_start(tvb, pinfo, pcp_tree, offset);
1910 break;
1912 case PCP_PDU_PMNS_TRAVERSE:
1913 dissect_pcp_message_pmns_traverse(tvb, pinfo, pcp_tree, offset);
1914 break;
1916 case PCP_PDU_PMNS_NAMES:
1917 dissect_pcp_message_pmns_names(tvb, pinfo, pcp_tree, offset);
1918 break;
1920 case PCP_PDU_PMNS_CHILD:
1921 dissect_pcp_message_pmns_child(tvb, pinfo, pcp_tree, offset);
1922 break;
1924 case PCP_PDU_PMNS_IDS:
1925 dissect_pcp_message_pmns_ids(tvb, pinfo, pcp_tree, offset);
1926 break;
1928 case PCP_PDU_PROFILE:
1929 dissect_pcp_message_profile(tvb, pinfo, pcp_tree, offset);
1930 break;
1932 case PCP_PDU_FETCH:
1933 dissect_pcp_message_fetch(tvb, pinfo, pcp_tree, offset);
1934 break;
1936 case PCP_PDU_RESULT:
1937 dissect_pcp_message_result(tvb, pinfo, pcp_tree, offset);
1938 break;
1940 case PCP_PDU_DESC_REQ:
1941 dissect_pcp_message_desc_req(tvb, pinfo, pcp_tree, offset);
1942 break;
1944 case PCP_PDU_DESC:
1945 dissect_pcp_message_desc(tvb, pinfo, pcp_tree, offset);
1946 break;
1948 case PCP_PDU_INSTANCE_REQ:
1949 dissect_pcp_message_instance_req(tvb, pinfo, pcp_tree, offset);
1950 break;
1952 case PCP_PDU_INSTANCE:
1953 dissect_pcp_message_instance(tvb, pinfo, pcp_tree, offset);
1954 break;
1956 case PCP_PDU_TEXT_REQ:
1957 dissect_pcp_message_text_req(tvb, pinfo, pcp_tree, offset);
1958 break;
1960 case PCP_PDU_TEXT:
1961 dissect_pcp_message_text(tvb, pinfo, pcp_tree, offset);
1962 break;
1964 case PCP_PDU_USER_AUTH:
1965 dissect_pcp_message_user_auth(tvb, pinfo, pcp_tree, offset);
1966 break;
1968 case PCP_PDU_LABEL_REQ:
1969 dissect_pcp_message_label_req(tvb, pinfo, pcp_tree, offset);
1970 break;
1972 case PCP_PDU_LABEL:
1973 dissect_pcp_message_label(tvb, pinfo, pcp_tree, offset);
1974 break;
1976 default:
1977 /* append the type of packet */
1978 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 expert_add_info(pinfo, pcp_tree, &ei_pcp_unimplemented_packet_type);
1981 break;
1983 return tvb_captured_length(tvb);
1986 static int dissect_pcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1988 /* pass all packets through TCP-reassembly */
1989 tcp_dissect_pdus(tvb, pinfo, tree, true, PCP_HEADER_LEN, get_pcp_message_len, dissect_pcp_message, data);
1990 return tvb_captured_length(tvb);
1993 /* setup the dissecting */
1994 void proto_register_pcp(void)
1996 static hf_register_info hf[] = {
1997 { &hf_pcp_pdu_length,
1998 { "PDU Length", "pcp.length",
1999 FT_UINT32, BASE_DEC,
2000 NULL, 0x0,
2001 NULL, HFILL
2004 { &hf_pcp_pdu_type,
2005 { "Type", "pcp.type",
2006 FT_UINT32, BASE_HEX,
2007 VALS(packettypenames), 0x0,
2008 NULL, HFILL
2011 { &hf_pcp_pdu_pid,
2012 { "From", "pcp.from",
2013 FT_UINT32, BASE_DEC,
2014 NULL, 0x0,
2015 NULL, HFILL
2018 { &hf_pcp_pdu_error,
2019 { "Error", "pcp.error",
2020 FT_INT32, BASE_DEC,
2021 VALS(packettypenames_errors), 0x0,
2022 NULL, HFILL
2025 { &hf_pcp_pdu_padding,
2026 { "Padding", "pcp.padding",
2027 FT_NONE, BASE_NONE,
2028 NULL, 0x0,
2029 NULL, HFILL
2032 { &hf_pcp_creds_number_of,
2033 { "Number of Credentials", "pcp.creds.number",
2034 FT_UINT32, BASE_DEC,
2035 NULL, 0x0,
2036 NULL, HFILL
2039 { &hf_pcp_creds_type,
2040 { "Credentials Type", "pcp.creds.type",
2041 FT_UINT8, BASE_DEC,
2042 VALS(packettypenames_creds), 0x0,
2043 NULL, HFILL
2046 { &hf_pcp_creds_version,
2047 { "Credentials Version", "pcp.creds.version",
2048 FT_UINT8, BASE_DEC,
2049 NULL, 0x0,
2050 NULL, HFILL
2053 { &hf_pcp_start,
2054 { "Start", "pcp.start",
2055 FT_NONE, BASE_NONE,
2056 NULL, 0x0,
2057 NULL, HFILL
2060 { &hf_pcp_start_zero,
2061 { "Start Bit", "pcp.start.zero",
2062 FT_BOOLEAN, 8,
2063 TFS(&tfs_set_notset), 0x80,
2064 NULL, HFILL
2067 { &hf_pcp_start_version,
2068 { "Version", "pcp.start.version",
2069 FT_UINT8, BASE_DEC, /* not a real 8 bit int, only uses 7 bits */
2070 NULL, 0x7F,
2071 NULL, HFILL
2074 { &hf_pcp_start_status,
2075 { "Start Status", "pcp.start.status",
2076 FT_UINT32, BASE_DEC,
2077 NULL, 0x0,
2078 NULL, HFILL
2081 { &hf_pcp_start_licensed,
2082 { "Licensed", "pcp.start.licensed",
2083 FT_UINT8, BASE_DEC,
2084 NULL, 0x0,
2085 NULL, HFILL
2088 { &hf_pcp_features_flags,
2089 { "Features", "pcp.features.flags",
2090 FT_UINT16, BASE_HEX,
2091 NULL, 0x0,
2092 NULL, HFILL
2095 { &hf_pcp_features_flags_secure,
2096 { "Secure", "pcp.features.flags.secure",
2097 FT_BOOLEAN, 16,
2098 TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE,
2099 NULL, HFILL
2102 { &hf_pcp_features_flags_compress,
2103 { "Compression", "pcp.features.flags.compression",
2104 FT_BOOLEAN, 16,
2105 TFS(&tfs_set_notset), PCP_PDU_FLAG_COMPRESS,
2106 NULL, HFILL
2109 { &hf_pcp_features_flags_auth,
2110 { "Authentication", "pcp.features.flags.auth",
2111 FT_BOOLEAN, 16,
2112 TFS(&tfs_set_notset), PCP_PDU_FLAG_AUTH,
2113 NULL, HFILL
2116 { &hf_pcp_features_flags_creds_reqd,
2117 { "Credentials Required", "pcp.features.flags.creds_reqd",
2118 FT_BOOLEAN, 16,
2119 TFS(&tfs_set_notset), PCP_PDU_FLAG_CREDS_REQD,
2120 NULL, HFILL
2123 { &hf_pcp_features_flags_secure_ack,
2124 { "Secure Acknowledgement", "pcp.features.flags.secure_ack",
2125 FT_BOOLEAN, 16,
2126 TFS(&tfs_set_notset), PCP_PDU_FLAG_SECURE_ACK,
2127 NULL, HFILL
2130 { &hf_pcp_features_flags_no_nss_init,
2131 { "No NSS Init", "pcp.features.flags.no_nss_init",
2132 FT_BOOLEAN, 16,
2133 TFS(&tfs_set_notset), PCP_PDU_FLAG_NO_NSS_INIT,
2134 NULL, HFILL
2137 { &hf_pcp_features_flags_container,
2138 { "Container", "pcp.features.flags.container",
2139 FT_BOOLEAN, 16,
2140 TFS(&tfs_set_notset), PCP_PDU_FLAG_CONTAINER,
2141 NULL, HFILL
2144 { &hf_pcp_features_flags_cert_reqd,
2145 { "Certificate Required", "pcp.features.flags.cert_reqd",
2146 FT_BOOLEAN, 16,
2147 TFS(&tfs_set_notset), PCP_PDU_FLAG_CERT_REQD,
2148 NULL, HFILL
2151 { &hf_pcp_features_flags_bad_label,
2152 { "Bad Label", "pcp.features.flags.bad_label",
2153 FT_BOOLEAN, 16,
2154 TFS(&tfs_set_notset), PCP_PDU_FLAG_BAD_LABEL,
2155 "Legacy label support. Incorrectly implemented in pcp v4.0.0-v4.0.1", HFILL
2158 { &hf_pcp_features_flags_labels,
2159 { "Labels", "pcp.features.flags.labels",
2160 FT_BOOLEAN, 16,
2161 TFS(&tfs_set_notset), PCP_PDU_FLAG_LABELS,
2162 NULL, HFILL
2165 { &hf_pcp_pmns_traverse,
2166 { "PMNS Traverse", "pcp.pmns_traverse",
2167 FT_NONE, BASE_NONE,
2168 NULL, 0x0,
2169 NULL, HFILL
2172 { &hf_pcp_pmns_subtype,
2173 { "Subtype", "pcp.pmns.subtype",
2174 FT_UINT32, BASE_DEC,
2175 NULL, 0x0,
2176 NULL, HFILL
2179 { &hf_pcp_pmns_namelen,
2180 { "Name Length", "pcp.pmns.namelen",
2181 FT_UINT32, BASE_DEC,
2182 NULL, 0x0,
2183 NULL, HFILL
2186 { &hf_pcp_pmns_name,
2187 { "Name", "pcp.pmns.name",
2188 FT_STRING, BASE_NONE,
2189 NULL, 0x0,
2190 NULL, HFILL
2193 { &hf_pcp_pmns_names,
2194 { "PMNS Names", "pcp.pmns_names",
2195 FT_NONE, BASE_NONE,
2196 NULL, 0x0,
2197 NULL, HFILL
2200 { &hf_pcp_pmns_names_nstrbytes,
2201 { "String Bytes", "pcp.pmns_names.nstrbytes",
2202 FT_UINT32, BASE_DEC,
2203 NULL, 0x0,
2204 NULL, HFILL
2207 { &hf_pcp_pmns_names_numstatus,
2208 { "Status", "pcp.pmns_names.numstatus",
2209 FT_UINT32, BASE_DEC,
2210 NULL, 0x0,
2211 NULL, HFILL
2214 { &hf_pcp_pmns_names_numnames,
2215 { "Number of Names", "pcp.pmns_names.numnames",
2216 FT_UINT32, BASE_DEC,
2217 NULL, 0x0,
2218 NULL, HFILL
2221 { &hf_pcp_pmns_names_nametree,
2222 { "Names", "pcp.pmns_names.nametree",
2223 FT_NONE, BASE_NONE,
2224 NULL, 0x0,
2225 NULL, HFILL
2228 { &hf_pcp_pmns_names_nametree_status,
2229 { "Status", "pcp.pmns_names.nametree.status",
2230 FT_UINT32, BASE_DEC,
2231 NULL, 0x0,
2232 NULL, HFILL
2235 { &hf_pcp_pmns_names_nametree_namelen,
2236 { "Length", "pcp.pmns_names.nametree.namelen",
2237 FT_UINT32, BASE_DEC,
2238 NULL, 0x0,
2239 NULL, HFILL
2242 { &hf_pcp_pmns_names_nametree_name,
2243 { "Name", "pcp.pmns_names.nametree.name",
2244 FT_STRING, BASE_NONE,
2245 NULL, 0x0,
2246 NULL, HFILL
2249 { &hf_pcp_pmns_ids,
2250 { "PMNS IDs", "pcp.pmns_ids",
2251 FT_NONE, BASE_NONE,
2252 NULL, 0x0,
2253 NULL, HFILL
2256 { &hf_pcp_pmns_ids_status,
2257 { "Status", "pcp.pmns_ids.status",
2258 FT_UINT32, BASE_DEC,
2259 NULL, 0x0,
2260 NULL, HFILL
2263 { &hf_pcp_pmns_ids_numids,
2264 { "Number of IDs", "pcp.pmns_ids.numids",
2265 FT_UINT32, BASE_DEC,
2266 NULL, 0x0,
2267 NULL, HFILL
2270 { &hf_pcp_pmns_child,
2271 { "PMID Child", "pcp.pmns.child",
2272 FT_NONE, BASE_NONE,
2273 NULL, 0x0,
2274 NULL, HFILL
2277 { &hf_pcp_pmid,
2278 { "PMID", "pcp.pmid",
2279 FT_UINT32, BASE_DEC,
2280 NULL, 0x0,
2281 NULL, HFILL
2284 { &hf_pcp_pmid_flag,
2285 { "Flag", "pcp.pmid.flag",
2286 FT_BOOLEAN, BASE_NONE,
2287 NULL, 0x0,
2288 NULL, HFILL
2291 { &hf_pcp_pmid_domain,
2292 { "Domain", "pcp.pmid.domain",
2293 FT_UINT16, BASE_DEC, /* uses 9 bits */
2294 NULL, 0x0,
2295 NULL, HFILL
2298 { &hf_pcp_pmid_cluster,
2299 { "Cluster", "pcp.pmid.cluster",
2300 FT_UINT16, BASE_DEC, /* uses 12 bits */
2301 NULL, 0x0,
2302 NULL, HFILL
2305 { &hf_pcp_pmid_item,
2306 { "Item", "pcp.pmid.item",
2307 FT_UINT16, BASE_DEC, /* uses 10 bits */
2308 NULL, 0x0,
2309 NULL, HFILL
2312 { &hf_pcp_pmid_type,
2313 { "Type", "pcp.pmid.type",
2314 FT_INT32, BASE_DEC,
2315 VALS(packettypenames_pm_types), 0x0,
2316 NULL, HFILL
2319 { &hf_pcp_pmid_sem,
2320 { "Type Semantics", "pcp.pmid.sem",
2321 FT_UINT32, BASE_DEC,
2322 VALS(packettypenames_pm_types_sem), 0x0,
2323 NULL, HFILL
2326 { &hf_pcp_pmid_inst,
2327 { "Instance", "pcp.pmid.inst",
2328 FT_UINT32, BASE_DEC,
2329 NULL, 0x0,
2330 NULL, HFILL
2333 { &hf_pcp_profile,
2334 { "Profile", "pcp.profile",
2335 FT_NONE, BASE_NONE,
2336 NULL, 0x0,
2337 NULL, HFILL
2340 { &hf_pcp_ctxnum,
2341 { "Context Number", "pcp.ctxnum",
2342 FT_UINT32, BASE_DEC,
2343 NULL, 0x0,
2344 NULL, HFILL
2347 { &hf_pcp_profile_g_state,
2348 { "Global Include/Exclude State", "pcp.profile.g_state",
2349 FT_UINT32, BASE_DEC,
2350 NULL, 0x0,
2351 NULL, HFILL
2354 { &hf_pcp_profile_numprof,
2355 { "Number of Profiles", "pcp.profile.numprof",
2356 FT_UINT32, BASE_DEC,
2357 NULL, 0x0,
2358 NULL, HFILL
2361 { &hf_pcp_profile_profile,
2362 { "Each Profile", "pcp.profile.profile",
2363 FT_NONE, BASE_NONE,
2364 NULL, 0x0,
2365 NULL, HFILL
2368 { &hf_pcp_profile_profile_state,
2369 { "Include/Exclude State", "pcp.profile.profile.state",
2370 FT_UINT32, BASE_DEC,
2371 NULL, 0x0,
2372 NULL, HFILL
2375 { &hf_pcp_profile_profile_numinst,
2376 { "Number Instances to Follow", "pcp.profile.profile.numinst",
2377 FT_UINT32, BASE_DEC,
2378 NULL, 0x0,
2379 NULL, HFILL
2382 { &hf_pcp_fetch,
2383 { "Fetch", "pcp.fetch",
2384 FT_NONE, BASE_NONE,
2385 NULL, 0x0,
2386 NULL, HFILL
2389 { &hf_pcp_fetch_numpmid,
2390 { "Number PMIDs", "pcp.fetch.numpmid",
2391 FT_UINT32, BASE_DEC,
2392 NULL, 0x0,
2393 NULL, HFILL
2396 { &hf_pcp_when,
2397 { "Time Value", "pcp.when",
2398 FT_NONE, BASE_NONE,
2399 NULL, 0x0,
2400 NULL, HFILL
2403 { &hf_pcp_when_sec,
2404 { "Seconds", "pcp.when.sec",
2405 FT_UINT32, BASE_DEC,
2406 NULL, 0x0,
2407 NULL, HFILL
2410 { &hf_pcp_when_usec,
2411 { "Microseconds", "pcp.when.usec",
2412 FT_UINT32, BASE_DEC,
2413 NULL, 0x0,
2414 NULL, HFILL
2417 { &hf_pcp_desc_req,
2418 { "Description Request", "pcp.desc_req",
2419 FT_NONE, BASE_NONE,
2420 NULL, 0x0,
2421 NULL, HFILL
2424 { &hf_pcp_desc,
2425 { "Description Response", "pcp.desc",
2426 FT_NONE, BASE_NONE,
2427 NULL, 0x0,
2428 NULL, HFILL
2431 { &hf_pcp_units,
2432 { "PMID Units", "pcp.units",
2433 FT_NONE, BASE_NONE,
2434 NULL, 0x0,
2435 NULL, HFILL
2438 { &hf_pcp_units_dimspace,
2439 { "Dimension Space", "pcp.units.dimspace",
2440 FT_UINT8, BASE_DEC,
2441 NULL, 0x0,
2442 NULL, HFILL
2445 { &hf_pcp_units_dimtime,
2446 { "Dimension Time", "pcp.units.dimtime",
2447 FT_UINT8, BASE_DEC,
2448 NULL, 0x0,
2449 NULL, HFILL
2452 { &hf_pcp_units_dimcount,
2453 { "Dimension Count", "pcp.units.dimcount",
2454 FT_UINT8, BASE_DEC,
2455 NULL, 0x0,
2456 NULL, HFILL
2459 { &hf_pcp_units_scalespace,
2460 { "Scale Space", "pcp.units.scalespace",
2461 FT_UINT8, BASE_DEC,
2462 VALS(packettypenames_pm_units_space), 0x0,
2463 NULL, HFILL
2466 { &hf_pcp_units_scaletime,
2467 { "Scale Time", "pcp.units.scaletime",
2468 FT_UINT8, BASE_DEC,
2469 VALS(packettypenames_pm_units_time), 0x0,
2470 NULL, HFILL
2473 { &hf_pcp_units_scalecount,
2474 { "Scale Count", "pcp.units.scalecount",
2475 FT_UINT8, BASE_DEC,
2476 NULL, 0x0,
2477 NULL, HFILL
2480 { &hf_pcp_instance_req,
2481 { "Instance Request", "pcp.instance_req",
2482 FT_NONE, BASE_NONE,
2483 NULL, 0x0,
2484 NULL, HFILL
2487 { &hf_pcp_instances,
2488 { "Instance Response", "pcp.instances",
2489 FT_NONE, BASE_NONE,
2490 NULL, 0x0,
2491 NULL, HFILL
2494 { &hf_pcp_instances_numinst,
2495 { "Number of Instances", "pcp.instance_resp.numinst",
2496 FT_UINT32, BASE_DEC,
2497 NULL, 0x0,
2498 NULL, HFILL
2501 { &hf_pcp_instance,
2502 { "Instance", "pcp.instance",
2503 FT_NONE, BASE_NONE,
2504 NULL, 0x0,
2505 NULL, HFILL
2508 { &hf_pcp_instance_namelen,
2509 { "Name Length", "pcp.instance.namelen",
2510 FT_UINT32, BASE_DEC,
2511 NULL, 0x0,
2512 NULL, HFILL
2515 { &hf_pcp_instance_name,
2516 { "Name", "pcp.instance.name",
2517 FT_STRING, BASE_NONE,
2518 NULL, 0x0,
2519 NULL, HFILL
2522 { &hf_pcp_instance_indom,
2523 { "Instance Domain", "pcp.instance.indom",
2524 FT_UINT32, BASE_DEC,
2525 NULL, 0x0,
2526 NULL, HFILL
2529 { &hf_pcp_instance_valoffset,
2530 { "Instance Offset", "pcp.instance.valoffset",
2531 FT_UINT32, BASE_DEC,
2532 NULL, 0x0,
2533 NULL, HFILL
2536 { &hf_pcp_instance_vallength,
2537 { "Instance Value Length", "pcp.instance.vallength",
2538 FT_INT24, BASE_DEC,
2539 NULL, 0x0,
2540 NULL, HFILL
2543 { &hf_pcp_instance_value_insitu,
2544 { "Instance Value", "pcp.instance.value.uint",
2545 FT_UINT32, BASE_DEC,
2546 NULL, 0x0,
2547 NULL, HFILL
2550 { &hf_pcp_instance_value_ptr,
2551 { "Instance Value", "pcp.instance.value.string",
2552 FT_STRING, BASE_NONE,
2553 NULL, 0x0,
2554 NULL, HFILL
2557 { &hf_pcp_instance_value_int,
2558 { "Instance Value", "pcp.instance.value.int",
2559 FT_INT32, BASE_DEC,
2560 NULL, 0x0,
2561 NULL, HFILL
2564 { &hf_pcp_instance_value_uint,
2565 { "Instance Value", "pcp.instance.value.uint",
2566 FT_UINT32, BASE_DEC,
2567 NULL, 0x0,
2568 NULL, HFILL
2571 { &hf_pcp_instance_value_int64,
2572 { "Instance Value", "pcp.instance.value.int64",
2573 FT_INT64, BASE_DEC,
2574 NULL, 0x0,
2575 NULL, HFILL
2578 { &hf_pcp_instance_value_uint64,
2579 { "Instance Value", "pcp.instance.value.uint64",
2580 FT_UINT64, BASE_DEC,
2581 NULL, 0x0,
2582 NULL, HFILL
2585 { &hf_pcp_instance_value_float,
2586 { "Instance Value", "pcp.instance.value.float",
2587 FT_FLOAT, BASE_NONE,
2588 NULL, 0x0,
2589 NULL, HFILL
2592 { &hf_pcp_instance_value_double,
2593 { "Instance Value", "pcp.instance.value.float",
2594 FT_DOUBLE, BASE_NONE,
2595 NULL, 0x0,
2596 NULL, HFILL
2599 { &hf_pcp_instance_value_aggr,
2600 { "Instance Value", "pcp.instance.value.bytes",
2601 FT_BYTES, BASE_NONE,
2602 NULL, 0x0,
2603 NULL, HFILL
2606 { &hf_pcp_results,
2607 { "Fetch Results", "pcp.results",
2608 FT_NONE, BASE_NONE,
2609 NULL, 0x0,
2610 NULL, HFILL
2613 { &hf_pcp_results_numpmid,
2614 { "Number of PMIDs", "pcp.results.numpmid",
2615 FT_UINT32, BASE_DEC,
2616 NULL, 0x0,
2617 NULL, HFILL
2620 { &hf_pcp_result,
2621 { "Result", "pcp.result",
2622 FT_NONE, BASE_NONE,
2623 NULL, 0x0,
2624 NULL, HFILL
2627 { &hf_pcp_result_numval,
2628 { "Number of Values", "pcp.result.numval",
2629 FT_UINT32, BASE_DEC,
2630 NULL, 0x0,
2631 NULL, HFILL
2634 { &hf_pcp_result_valfmt,
2635 { "Value Encoding Format", "pcp.result.valfmt",
2636 FT_UINT32, BASE_DEC,
2637 VALS(packettypenames_valfmt), 0x0,
2638 NULL, HFILL
2641 { &hf_pcp_text_req,
2642 { "Text Request", "pcp.text_req",
2643 FT_NONE, BASE_NONE,
2644 NULL, 0x0,
2645 NULL, HFILL
2648 { &hf_pcp_text_type,
2649 { "Help Text Type", "pcp.text.type",
2650 FT_NONE, BASE_NONE,
2651 NULL, 0x0,
2652 NULL, HFILL
2655 { &hf_pcp_text_type_format,
2656 { "Text Type Format", "pcp.text.type.format",
2657 FT_UINT8, BASE_DEC,
2658 VALS(packettypenames_text_type_format), 0x0,
2659 NULL, HFILL
2662 { &hf_pcp_text_type_ident,
2663 { "Text Type Ident", "pcp.text.type.ident",
2664 FT_UINT8, BASE_DEC,
2665 VALS(packettypenames_text_type_ident), 0x0,
2666 NULL, HFILL
2669 { &hf_pcp_text,
2670 { "Text Response", "pcp.text",
2671 FT_NONE, BASE_NONE,
2672 NULL, 0x0,
2673 NULL, HFILL
2676 { &hf_pcp_text_ident,
2677 { "Text Ident (raw)", "pcp.text.ident",
2678 FT_UINT32, BASE_DEC,
2679 NULL, 0x0,
2680 NULL, HFILL
2683 { &hf_pcp_text_buflen,
2684 { "Text Buffer Length", "pcp.text.buflen",
2685 FT_UINT32, BASE_DEC,
2686 NULL, 0x0,
2687 NULL, HFILL
2690 { &hf_pcp_text_buffer,
2691 { "Text Buffer", "pcp.text.buffer",
2692 FT_STRING, BASE_NONE,
2693 NULL, 0x0,
2694 NULL, HFILL
2697 { &hf_pcp_user_auth_payload,
2698 { "User Authentication Payload", "pcp.user_auth_payload",
2699 FT_NONE, BASE_NONE,
2700 NULL, 0x0,
2701 NULL, HFILL
2704 { &hf_pcp_label_req,
2705 { "Label Request", "pcp.label_req",
2706 FT_NONE, BASE_NONE,
2707 NULL, 0x0,
2708 NULL, HFILL
2711 { &hf_pcp_label_ident,
2712 { "Label Ident", "pcp.label.ident",
2713 FT_INT32, BASE_DEC,
2714 NULL, 0x0,
2715 "Domain, PMID or pmInDom identifier", HFILL
2718 { &hf_pcp_label_type,
2719 { "Label Type", "pcp.label.type",
2720 FT_INT32, BASE_DEC,
2721 VALS(packettypenames_label_req_type), 0x0,
2722 NULL, HFILL
2725 { &hf_pcp_label,
2726 { "Labels", "pcp.label",
2727 FT_NONE, BASE_NONE,
2728 NULL, 0x0,
2729 NULL, HFILL
2732 { &hf_pcp_label_padding,
2733 { "Padding", "pcp.label.padding",
2734 FT_NONE, BASE_NONE,
2735 NULL, 0x0,
2736 NULL, HFILL
2739 { &hf_pcp_label_nsets,
2740 { "Num Label Sets", "pcp.label.nsets",
2741 FT_INT32, BASE_DEC,
2742 NULL, 0x0,
2743 "Number of Label Sets", HFILL
2746 { &hf_pcp_label_sets,
2747 { "Label Set", "pcp.label.sets",
2748 FT_NONE, BASE_NONE,
2749 NULL, 0x0,
2750 NULL, HFILL
2753 { &hf_pcp_label_sets_inst,
2754 { "Instance", "pcp.label.sets.inst",
2755 FT_INT32, BASE_DEC,
2756 NULL, 0x0,
2757 "Instance identifier or PM_IN_NULL", HFILL
2760 { &hf_pcp_label_sets_nlabels,
2761 { "Num of Labels", "pcp.label.sets.nlabels",
2762 FT_INT32, BASE_DEC,
2763 NULL, 0x0,
2764 "Number of labels or error code", HFILL
2767 { &hf_pcp_label_sets_json,
2768 { "JSON Offset", "pcp.label.sets.json",
2769 FT_INT32, BASE_DEC,
2770 NULL, 0x0,
2771 "Offset to start of JSON string", HFILL
2774 { &hf_pcp_label_sets_jsonlen,
2775 { "JSON Length", "pcp.label.sets.jsonlen",
2776 FT_INT32, BASE_DEC,
2777 NULL, 0x0,
2778 "Length of bytes of the JSON string", HFILL
2781 { &hf_pcp_label_sets_labels,
2782 { "Label", "pcp.label.sets.label",
2783 FT_NONE, BASE_NONE,
2784 NULL, 0x0,
2785 NULL, HFILL
2788 { &hf_pcp_label_sets_labels_nameoffset,
2789 { "Name Offset", "pcp.label.sets.label.nameoffset",
2790 FT_INT16, BASE_DEC,
2791 NULL, 0x0,
2792 "Label name offset in the JSONB string", HFILL
2795 { &hf_pcp_label_sets_labels_namelen,
2796 { "Name Length", "pcp.label.sets.label.namelen",
2797 FT_INT8, BASE_DEC,
2798 NULL, 0x0,
2799 "Length of name excluding NULL terminator", HFILL
2802 { &hf_pcp_label_sets_labels_flags,
2803 { "Flags", "pcp.label.sets.label.flags",
2804 FT_INT8, BASE_DEC,
2805 NULL, 0x0,
2806 "Information about this label", HFILL
2809 { &hf_pcp_label_sets_labels_valueoffset,
2810 { "Value Offset", "pcp.label.sets.label.valueoffset",
2811 FT_INT16, BASE_DEC,
2812 NULL, 0x0,
2813 "Offset of the label value", HFILL
2816 { &hf_pcp_label_sets_labels_valuelen,
2817 { "Value Length", "pcp.label.sets.label.valuelen",
2818 FT_INT16, BASE_DEC,
2819 NULL, 0x0,
2820 "Length of the value in bytes", HFILL
2823 { &hf_pcp_label_sets_labels_name,
2824 { "Name", "pcp.label.sets.label.name",
2825 FT_STRING, BASE_NONE,
2826 NULL, 0x0,
2827 "Label name", HFILL
2830 { &hf_pcp_label_sets_labels_value,
2831 { "Value", "pcp.label.sets.label.value",
2832 FT_STRING, BASE_NONE,
2833 NULL, 0x0,
2834 "Label value", HFILL
2841 static int *ett[] = {
2842 &ett_pcp,
2843 &ett_pcp_pdu_length,
2844 &ett_pcp_pdu_type,
2845 &ett_pcp_pdu_pid,
2846 &ett_pcp_pdu_error,
2847 &ett_pcp_pdu_padding,
2848 &ett_pcp_creds_number_of,
2849 &ett_pcp_creds_type,
2850 &ett_pcp_creds_vala,
2851 &ett_pcp_creds_valb,
2852 &ett_pcp_creds_valc,
2853 &ett_pcp_start,
2854 &ett_pcp_start_status,
2855 &ett_pcp_start_zero,
2856 &ett_pcp_start_version,
2857 &ett_pcp_start_licensed,
2858 &ett_pcp_start_features,
2859 &ett_pcp_pmns_traverse,
2860 &ett_pcp_pmns_subtype,
2861 &ett_pcp_pmns_namelen,
2862 &ett_pcp_pmns_name,
2863 &ett_pcp_pmns_names,
2864 &ett_pcp_pmns_names_nstrbytes,
2865 &ett_pcp_pmns_names_numstatus,
2866 &ett_pcp_pmns_names_numnames,
2867 &ett_pcp_pmns_names_nametree,
2868 &ett_pcp_pmns_names_nametree_status,
2869 &ett_pcp_pmns_names_nametree_namelen,
2870 &ett_pcp_pmns_names_nametree_name,
2871 &ett_pcp_pmns_ids,
2872 &ett_pcp_pmns_ids_status,
2873 &ett_pcp_pmns_ids_numids,
2874 &ett_pcp_pmns_child,
2875 &ett_pcp_pmid,
2876 &ett_pcp_pmid_flag,
2877 &ett_pcp_pmid_domain,
2878 &ett_pcp_pmid_cluster,
2879 &ett_pcp_pmid_item,
2880 &ett_pcp_pmid_type,
2881 &ett_pcp_pmid_sem,
2882 &ett_pcp_profile,
2883 &ett_pcp_ctxnum,
2884 &ett_pcp_profile_g_state,
2885 &ett_pcp_profile_numprof,
2886 &ett_pcp_profile_profile,
2887 &ett_pcp_profile_profile_state,
2888 &ett_pcp_profile_profile_numinst,
2889 &ett_pcp_fetch,
2890 &ett_pcp_fetch_numpmid,
2891 &ett_pcp_when,
2892 &ett_pcp_when_sec,
2893 &ett_pcp_when_usec,
2894 &ett_pcp_desc_req,
2895 &ett_pcp_units,
2896 &ett_pcp_units_dimspace,
2897 &ett_pcp_units_dimtime,
2898 &ett_pcp_units_dimcount,
2899 &ett_pcp_units_scalespace,
2900 &ett_pcp_units_scaletime,
2901 &ett_pcp_units_scalecount,
2902 &ett_pcp_instance,
2903 &ett_pcp_instance_req,
2904 &ett_pcp_instance_namelen,
2905 &ett_pcp_instance_name,
2906 &ett_pcp_instance_indom,
2907 &ett_pcp_instance_inst,
2908 &ett_pcp_instance_valoffset,
2909 &ett_pcp_instance_vallength,
2910 &ett_pcp_instance_value_insitu,
2911 &ett_pcp_instance_value_ptr,
2912 &ett_pcp_instance_value_int,
2913 &ett_pcp_instance_value_uint,
2914 &ett_pcp_instance_value_int64,
2915 &ett_pcp_instance_value_uint64,
2916 &ett_pcp_instance_value_float,
2917 &ett_pcp_instance_value_double,
2918 &ett_pcp_instance_value_aggr,
2919 &ett_pcp_instances,
2920 &ett_pcp_instances_numinst,
2921 &ett_pcp_results,
2922 &ett_pcp_results_numpmid,
2923 &ett_pcp_result,
2924 &ett_pcp_result_numval,
2925 &ett_pcp_result_valfmt,
2926 &ett_pcp_text_req,
2927 &ett_pcp_text_type,
2928 &ett_pcp_text_type_format,
2929 &ett_pcp_text_type_ident,
2930 &ett_pcp_text,
2931 &ett_pcp_text_ident,
2932 &ett_pcp_text_buflen,
2933 &ett_pcp_text_buffer,
2936 static ei_register_info ei[] = {
2937 { &ei_pcp_type_event_unimplemented, { "pcp.pmid.type.event.unimplemented", PI_UNDECODED, PI_WARN, "PM_TYPE_EVENT: Unimplemented Value Type", EXPFILL }},
2938 { &ei_pcp_type_nosupport_unsupported, { "pcp.pmid.type.nosupport.unsupported", PI_UNDECODED, PI_WARN, "PM_TYPE_NOSUPPORT: Unsupported Value Type", EXPFILL }},
2939 { &ei_pcp_type_unknown_unknown_value, { "pcp.pmid.type.unknown.unknown_value", PI_UNDECODED, PI_WARN, "PM_TYPE_UNKNOWN: Unknown Value Type", EXPFILL }},
2940 { &ei_pcp_unimplemented_value, { "pcp.pmid.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Value Type", EXPFILL }},
2941 { &ei_pcp_unimplemented_packet_type, { "pcp.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Packet Type", EXPFILL }},
2942 { &ei_pcp_ssl_upgrade, { "pcp.ssl_upgrade", PI_COMMENTS_GROUP, PI_COMMENT, "SSL upgrade via SECURE_ACK", EXPFILL }},
2943 { &ei_pcp_ssl_upgrade_failed, { "pcp.ssl_upgrade_failed", PI_RESPONSE_CODE, PI_WARN, "SSL upgrade via SECURE_ACK failed", EXPFILL }},
2944 { &ei_pcp_label_error, { "pcp.label.error", PI_RESPONSE_CODE, PI_NOTE, "Label returned an error", EXPFILL }},
2945 { &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 }},
2948 expert_module_t* expert_pcp;
2950 proto_pcp = proto_register_protocol("Performance Co-Pilot", "PCP", "pcp");
2952 expert_pcp = expert_register_protocol(proto_pcp);
2953 expert_register_field_array(expert_pcp, ei, array_length(ei));
2955 proto_register_field_array(proto_pcp, hf, array_length(hf));
2956 proto_register_subtree_array(ett, array_length(ett));
2958 pcp_handle = register_dissector("pcp", dissect_pcp, proto_pcp);
2961 void proto_reg_handoff_pcp(void)
2963 dissector_add_uint_with_preference("tcp.port", PCP_PORT, pcp_handle);
2967 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2969 * Local variables:
2970 * c-basic-offset: 4
2971 * tab-width: 8
2972 * indent-tabs-mode: nil
2973 * End:
2975 * vi: set shiftwidth=4 tabstop=8 expandtab:
2976 * :indentSize=4:tabSize=8:noTabs=true: