HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-pcp.c
blob353d5970fafae64b924722b7699e79d596b3060a
1 /* packet-pcp.c
2 * Routines for Performace Co-Pilot protocol dissection
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #include <epan/packet.h>
28 #include <epan/expert.h>
29 #include "packet-tcp.h"
31 #define PCP_PORT 44321
32 #define PCP_HEADER_LEN 12
35 static int proto_pcp = -1;
36 static int hf_pcp_pdu_length = -1;
37 static int hf_pcp_pdu_type = -1;
38 static int hf_pcp_pdu_pid = -1;
39 static int hf_pcp_pdu_error = -1;
40 static int hf_pcp_pdu_padding = -1;
41 static int hf_pcp_creds_number_of = -1;
42 static int hf_pcp_creds_type = -1;
43 static int hf_pcp_creds_vala = -1;
44 static int hf_pcp_creds_valb = -1;
45 static int hf_pcp_creds_valc = -1;
46 static int hf_pcp_start = -1;
47 static int hf_pcp_start_status = -1;
48 static int hf_pcp_start_zero = -1;
49 static int hf_pcp_start_version = -1;
50 static int hf_pcp_start_licensed = -1;
51 static int hf_pcp_start_authorize = -1;
52 static int hf_pcp_pmns_traverse = -1;
53 static int hf_pcp_pmns_subtype = -1;
54 static int hf_pcp_pmns_namelen = -1;
55 static int hf_pcp_pmns_name = -1;
56 static int hf_pcp_pmns_names = -1;
57 static int hf_pcp_pmns_names_nstrbytes = -1;
58 static int hf_pcp_pmns_names_numstatus = -1;
59 static int hf_pcp_pmns_names_numnames = -1;
60 static int hf_pcp_pmns_names_nametree = -1;
61 static int hf_pcp_pmns_names_nametree_status = -1;
62 static int hf_pcp_pmns_names_nametree_namelen = -1;
63 static int hf_pcp_pmns_names_nametree_name = -1;
64 static int hf_pcp_pmns_ids = -1;
65 static int hf_pcp_pmns_ids_status = -1;
66 static int hf_pcp_pmns_ids_numids = -1;
67 static int hf_pcp_pmns_child = -1;
68 static int hf_pcp_pmid = -1;
69 static int hf_pcp_pmid_flag = -1;
70 static int hf_pcp_pmid_domain = -1;
71 static int hf_pcp_pmid_cluster = -1;
72 static int hf_pcp_pmid_item = -1;
73 static int hf_pcp_pmid_type = -1;
74 static int hf_pcp_pmid_sem = -1;
75 static int hf_pcp_pmid_inst = -1;
76 static int hf_pcp_profile = -1;
77 static int hf_pcp_ctxnum = -1;
78 static int hf_pcp_profile_g_state = -1;
79 static int hf_pcp_profile_numprof = -1;
80 static int hf_pcp_profile_profile = -1;
81 static int hf_pcp_profile_profile_state = -1;
82 static int hf_pcp_profile_profile_numinst = -1;
83 static int hf_pcp_fetch = -1;
84 static int hf_pcp_fetch_numpmid = -1;
85 static int hf_pcp_when = -1;
86 static int hf_pcp_when_sec = -1;
87 static int hf_pcp_when_usec = -1;
88 static int hf_pcp_desc = -1;
89 static int hf_pcp_desc_req = -1;
90 static int hf_pcp_units = -1;
91 static int hf_pcp_units_dimspace = -1;
92 static int hf_pcp_units_dimtime = -1;
93 static int hf_pcp_units_dimcount = -1;
94 static int hf_pcp_units_scalespace = -1;
95 static int hf_pcp_units_scaletime = -1;
96 static int hf_pcp_units_scalecount = -1;
97 static int hf_pcp_instance = -1;
98 static int hf_pcp_instance_req = -1;
99 static int hf_pcp_instance_namelen = -1;
100 static int hf_pcp_instance_name = -1;
101 static int hf_pcp_instance_indom = -1;
102 static int hf_pcp_instance_valoffset = -1;
103 static int hf_pcp_instance_vallength = -1;
104 static int hf_pcp_instance_value_insitu = -1;
105 static int hf_pcp_instance_value_ptr = -1;
106 static int hf_pcp_instance_value_int = -1;
107 static int hf_pcp_instance_value_uint = -1;
108 static int hf_pcp_instance_value_int64 = -1;
109 static int hf_pcp_instance_value_uint64 = -1;
110 static int hf_pcp_instance_value_float = -1;
111 static int hf_pcp_instance_value_double = -1;
112 static int hf_pcp_instance_value_aggr = -1;
113 static int hf_pcp_instances = -1;
114 static int hf_pcp_instances_numinst = -1;
115 static int hf_pcp_results = -1;
116 static int hf_pcp_results_numpmid = -1;
117 static int hf_pcp_result = -1;
118 static int hf_pcp_result_numval = -1;
119 static int hf_pcp_result_valfmt = -1;
120 static int hf_pcp_text_req = -1;
121 static int hf_pcp_text_type = -1;
122 static int hf_pcp_text_type_format = -1;
123 static int hf_pcp_text_type_ident = -1;
124 static int hf_pcp_text = -1;
125 static int hf_pcp_text_ident = -1;
126 static int hf_pcp_text_buflen = -1;
127 static int hf_pcp_text_buffer = -1;
130 static gint ett_pcp = -1;
131 static gint ett_pcp_pdu_length = -1;
132 static gint ett_pcp_pdu_type = -1;
133 static gint ett_pcp_pdu_pid = -1;
134 static gint ett_pcp_pdu_error = -1;
135 static gint ett_pcp_pdu_padding = -1;
136 static gint ett_pcp_creds_number_of = -1;
137 static gint ett_pcp_creds_type = -1;
138 static gint ett_pcp_creds_vala = -1;
139 static gint ett_pcp_creds_valb = -1;
140 static gint ett_pcp_creds_valc = -1;
141 static gint ett_pcp_start = -1;
142 static gint ett_pcp_start_status = -1;
143 static gint ett_pcp_start_zero = -1;
144 static gint ett_pcp_start_version = -1;
145 static gint ett_pcp_start_licensed = -1;
146 static gint ett_pcp_start_authorize = -1;
147 static gint ett_pcp_pmns_traverse = -1;
148 static gint ett_pcp_pmns_subtype = -1;
149 static gint ett_pcp_pmns_namelen = -1;
150 static gint ett_pcp_pmns_name = -1;
151 static gint ett_pcp_pmns_names = -1;
152 static gint ett_pcp_pmns_names_nstrbytes = -1;
153 static gint ett_pcp_pmns_names_numstatus = -1;
154 static gint ett_pcp_pmns_names_numnames = -1;
155 static gint ett_pcp_pmns_names_nametree = -1;
156 static gint ett_pcp_pmns_names_nametree_status = -1;
157 static gint ett_pcp_pmns_names_nametree_namelen = -1;
158 static gint ett_pcp_pmns_names_nametree_name = -1;
159 static gint ett_pcp_pmns_ids = -1;
160 static gint ett_pcp_pmns_ids_status = -1;
161 static gint ett_pcp_pmns_ids_numids = -1;
162 static gint ett_pcp_pmns_child = -1;
163 static gint ett_pcp_pmid = -1;
164 static gint ett_pcp_pmid_flag = -1;
165 static gint ett_pcp_pmid_domain = -1;
166 static gint ett_pcp_pmid_cluster = -1;
167 static gint ett_pcp_pmid_item = -1;
168 static gint ett_pcp_pmid_type = -1;
169 static gint ett_pcp_pmid_sem = -1;
170 static gint ett_pcp_profile = -1;
171 static gint ett_pcp_ctxnum = -1;
172 static gint ett_pcp_profile_g_state = -1;
173 static gint ett_pcp_profile_numprof = -1;
174 static gint ett_pcp_profile_profile = -1;
175 static gint ett_pcp_profile_profile_state = -1;
176 static gint ett_pcp_profile_profile_numinst = -1;
177 static gint ett_pcp_fetch = -1;
178 static gint ett_pcp_fetch_numpmid = -1;
179 static gint ett_pcp_when = -1;
180 static gint ett_pcp_when_sec = -1;
181 static gint ett_pcp_when_usec = -1;
182 static gint ett_pcp_desc_req = -1;
183 static gint ett_pcp_units = -1;
184 static gint ett_pcp_units_dimspace = -1;
185 static gint ett_pcp_units_dimtime = -1;
186 static gint ett_pcp_units_dimcount = -1;
187 static gint ett_pcp_units_scalespace = -1;
188 static gint ett_pcp_units_scaletime = -1;
189 static gint ett_pcp_units_scalecount = -1;
190 static gint ett_pcp_instance = -1;
191 static gint ett_pcp_instance_req = -1;
192 static gint ett_pcp_instance_namelen = -1;
193 static gint ett_pcp_instance_name = -1;
194 static gint ett_pcp_instance_inst = -1;
195 static gint ett_pcp_instance_indom = -1;
196 static gint ett_pcp_instance_valoffset = -1;
197 static gint ett_pcp_instance_vallength = -1;
198 static gint ett_pcp_instance_value_insitu = -1;
199 static gint ett_pcp_instance_value_ptr = -1;
200 static gint ett_pcp_instance_value_int = -1;
201 static gint ett_pcp_instance_value_uint = -1;
202 static gint ett_pcp_instance_value_int64 = -1;
203 static gint ett_pcp_instance_value_uint64 = -1;
204 static gint ett_pcp_instance_value_float = -1;
205 static gint ett_pcp_instance_value_double = -1;
206 static gint ett_pcp_instance_value_aggr = -1;
207 static gint ett_pcp_instances = -1;
208 static gint ett_pcp_instances_numinst = -1;
209 static gint ett_pcp_results = -1;
210 static gint ett_pcp_results_numpmid = -1;
211 static gint ett_pcp_result = -1;
212 static gint ett_pcp_result_numval = -1;
213 static gint ett_pcp_result_valfmt = -1;
214 static gint ett_pcp_text_req = -1;
215 static gint ett_pcp_text_type = -1;
216 static gint ett_pcp_text_type_format = -1;
217 static gint ett_pcp_text_type_ident = -1;
218 static gint ett_pcp_text = -1;
219 static gint ett_pcp_text_ident = -1;
220 static gint ett_pcp_text_buflen = -1;
221 static gint ett_pcp_text_buffer = -1;
223 static expert_field ei_pcp_type_event_unimplemented = EI_INIT;
224 static expert_field ei_pcp_type_nosupport_unsupported = EI_INIT;
225 static expert_field ei_pcp_type_unknown_unknown_value = EI_INIT;
226 static expert_field ei_pcp_unimplemented_value = EI_INIT;
227 static expert_field ei_pcp_unimplemented_packet_type = EI_INIT;
229 /* packet types */
230 static const value_string packettypenames[] = {
231 #define START_OR_ERROR 0x7000
232 { 0x7000, "START/ERROR" },
233 #define RESULT 0x7001
234 { 0x7001, "RESULT" },
235 #define PROFILE 0x7002
236 { 0x7002, "PROFILE"},
237 #define FETCH 0x7003
238 { 0x7003, "FETCH"},
239 #define DESC_REQ 0x7004
240 { 0x7004, "DESC_REQ"},
241 #define DESC 0x7005
242 { 0x7005, "DESC"},
243 #define INSTANCE_REQ 0x7006
244 { 0x7006, "INSTANCE_REQ" },
245 #define INSTANCE 0x7007
246 { 0x7007, "INSTANCE" },
247 #define TEXT_REQ 0x7008
248 { 0x7008, "TEXT_REQ" },
249 #define TEXT 0x7009
250 { 0x7009, "TEXT" },
251 #define CONTROL_REQ 0x700a
252 { 0x700a, "CONTROL_REQ" }, /* unimplemented (pmlc/pmlogger only) */
253 #define DATA_X 0x700b
254 { 0x700b, "DATA_X" }, /* unimplemented (pmlc/pmlogger only) */
255 #define CREDS 0x700c
256 { 0x700c, "CREDS" },
257 #define PMNS_IDS 0x700d
258 { 0x700d, "PMNS_IDS" },
259 #define PMNS_NAMES 0x700e
260 { 0x700e, "PMNS_NAMES" },
261 #define PMNS_CHILD 0x700f
262 { 0x700f, "PMNS_CHILD" },
263 #define PMNS_TRAVERSE 0x7010 /*also type FINISH as per pcp headers, but I can not see it used */
264 { 0x7010, "PMNS_TRAVERSE" },
265 { 0, NULL }
268 static const value_string packettypenames_pm_units_space[] = {
269 { 0, "PM_SPACE_BYTE" },
270 { 1, "PM_SPACE_KBYTE" },
271 { 2, "PM_SPACE_MBYTE" },
272 { 3, "PM_SPACE_GBYTE" },
273 { 4, "PM_SPACE_TBYTE" },
274 { 5, "PM_SPACE_PBYTE" },
275 { 6, "PM_SPACE_EBYTE" },
276 { 0, NULL }
279 static const value_string packettypenames_pm_units_time[] = {
280 { 0, "PM_TIME_NSEC" },
281 { 1, "PM_TIME_USEC" },
282 { 2, "PM_TIME_MSEC" },
283 { 3, "PM_TIME_SEC" },
284 { 4, "PM_TIME_MIN" },
285 { 5, "PM_TIME_HOUR" },
286 { 0, NULL }
289 static const value_string packettypenames_pm_types[] = {
290 #define PM_TYPE_NOSUPPORT -1
291 { -1, "PM_TYPE_NOSUPPORT" },
292 #define PM_TYPE_32 0
293 { 0, "PM_TYPE_32" },
294 #define PM_TYPE_U32 1
295 { 1, "PM_TYPE_U32" },
296 #define PM_TYPE_64 2
297 { 2, "PM_TYPE_64" },
298 #define PM_TYPE_U64 3
299 { 3, "PM_TYPE_U64" },
300 #define PM_TYPE_FLOAT 4
301 { 4, "PM_TYPE_FLOAT" },
302 #define PM_TYPE_DOUBLE 5
303 { 5, "PM_TYPE_DOUBLE" },
304 #define PM_TYPE_STRING 6
305 { 6, "PM_TYPE_STRING" },
306 #define PM_TYPE_AGGREGATE 7
307 { 7, "PM_TYPE_AGGREGATE" },
308 #define PM_TYPE_AGGREGATE_STATIC 8
309 { 8, "PM_TYPE_AGGREGATE_STATIC" },
310 #define PM_TYPE_EVENT 9
311 { 9, "PM_TYPE_EVENT" },
312 #define PM_TYPE_UNKNOWN 255
313 { 255, "PM_TYPE_UNKNOWN" },
314 { 0, NULL }
317 static const value_string packettypenames_pm_types_sem[] = {
318 { 1, "PM_SEM_COUNTER" },
319 { 3, "PM_SEM_INSTANT" },
320 { 4, "PM_SEM_DISCRETE" },
321 { 0, NULL }
324 static const value_string packettypenames_text_type_format[] = {
325 #define PM_TEXT_ONELINE 1
326 { 1, "PM_TEXT_ONELINE" },
327 #define PM_TEXT_HELP 2
328 { 2, "PM_TEXT_HELP" },
329 { 0, NULL }
332 static const value_string packettypenames_text_type_ident[] = {
333 #define PM_TEXT_PMID 4
334 { 1, "PM_TEXT_PMID" },
335 #define PM_TEXT_INDOM 8
336 { 2, "PM_TEXT_INDOM" },
337 { 0, NULL }
340 static const value_string packettypenames_valfmt[] = {
341 #define PM_VAL_INSITU 0
342 { 0, "PM_VAL_INSITU" },
343 #define PM_VAL_DPTR 1
344 { 1, "PM_VAL_DPTR" },
345 #define PM_VAL_SPTR 2
346 { 2, "PM_VAL_SPTR" },
347 { 0, NULL }
350 static const value_string packettypenames_errors[] = {
351 { -12345, "PM_ERR_GENERIC" },
352 { -12346, "PM_ERR_PMNS" },
353 { -12347, "PM_ERR_NOPMNS" },
354 { -12348, "PM_ERR_DUPPMNS" },
355 { -12349, "PM_ERR_TEXT" },
356 { -12350, "PM_ERR_APPVERSION" },
357 { -12351, "PM_ERR_VALUE" },
358 { -12352, "PM_ERR_LICENSE" },
359 { -12353, "PM_ERR_TIMEOUT" },
360 { -12354, "PM_ERR_NODATA" },
361 { -12355, "PM_ERR_RESET" },
362 { -12356, "PM_ERR_FILE" },
363 { -12357, "PM_ERR_NAME" },
364 { -12358, "PM_ERR_PMID" },
365 { -12359, "PM_ERR_INDOM" },
366 { -12360, "PM_ERR_INST" },
367 { -12361, "PM_ERR_UNIT" },
368 { -12362, "PM_ERR_CONV" },
369 { -12363, "PM_ERR_TRUNC" },
370 { -12364, "PM_ERR_SIGN" },
371 { -12365, "PM_ERR_PROFILE" },
372 { -12366, "PM_ERR_IPC" },
373 { -12367, "PM_ERR_NOASCII" },
374 { -12368, "PM_ERR_EOF" },
375 { -12369, "PM_ERR_NOTHOST" },
376 { -12370, "PM_ERR_EOL" },
377 { -12371, "PM_ERR_MODE" },
378 { -12372, "PM_ERR_LABEL" },
379 { -12373, "PM_ERR_LOGREC" },
380 { -12374, "PM_ERR_NOTARCHIVE" },
381 { -12375, "PM_ERR_LOGFILE" },
382 { -12376, "PM_ERR_NOCONTEXT" },
383 { -12377, "PM_ERR_PROFILESPEC" },
384 { -12378, "PM_ERR_PMID_LOG" },
385 { -12379, "PM_ERR_INDOM_LOG" },
386 { -12380, "PM_ERR_INST_LOG" },
387 { -12381, "PM_ERR_NOPROFILE" },
388 { -12386, "PM_ERR_NOAGENT" },
389 { -12387, "PM_ERR_PERMISSION" },
390 { -12388, "PM_ERR_CONNLIMIT" },
391 { -12389, "PM_ERR_AGAIN" },
392 { -12390, "PM_ERR_ISCONN" },
393 { -12391, "PM_ERR_NOTCONN" },
394 { -12392, "PM_ERR_NEEDPORT" },
395 { -12393, "PM_ERR_WANTACK" },
396 { -12394, "PM_ERR_NONLEAF" },
397 { -12395, "PM_ERR_OBJSTYLE" },
398 { -12396, "PM_ERR_PMCDLICENSE" },
399 { -12397, "PM_ERR_TYPE" },
400 { -12442, "PM_ERR_CTXBUSY" },
401 { -12443, "PM_ERR_TOOSMALL" },
402 { -12444, "PM_ERR_TOOBIG" },
403 { -13393, "PM_ERR_PMDAREADY" },
404 { -13394, "PM_ERR_PMDANOTREADY" },
405 { -21344, "PM_ERR_NYI" },
406 { 0, NULL }
409 static const value_string packettypenames_creds[]= {
410 { 1, "CVERSION" },
411 { 2, "CAUTH" },
412 { 0, NULL }
415 /* function prototypes */
416 static guint get_pcp_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
417 static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
418 static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
419 static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
420 static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
421 static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
422 static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
423 static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
424 static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
425 static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
426 static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
427 static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
428 static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
429 static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
430 static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
431 static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
432 static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
433 static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
434 static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
436 /* message length for dissect_tcp */
437 static guint get_pcp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
439 /* length is at the very start of the packet, after tcp header */
440 return (guint)tvb_get_ntohl(tvb, offset);
443 static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
445 guint32 creds_length;
446 guint32 i;
448 /* append the type of packet */
449 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
450 val_to_str(CREDS, packettypenames, "Unknown Type:0x%02x"));
452 /* first is the number of creds */
453 proto_tree_add_item(tree, hf_pcp_creds_number_of, tvb, offset, 4, ENC_BIG_ENDIAN);
454 /* store the number of creds so we know how long to interate for */
455 creds_length = tvb_get_ntohl(tvb, offset);
456 offset += 4;
457 /* go through each __pmCreds struct */
458 for (i = 0; i < creds_length; i++) {
459 /* __pmCred.c_type */
460 proto_tree_add_item(tree, hf_pcp_creds_type, tvb, offset, 1, ENC_BIG_ENDIAN);
461 offset += 1;
462 /* __pmCred.c_vala - Usually the PDU version */
463 proto_tree_add_item(tree, hf_pcp_creds_vala, tvb, offset, 1, ENC_BIG_ENDIAN);
464 offset += 1;
465 /* __pmCred.c_valb - Unused */
466 proto_tree_add_item(tree, hf_pcp_creds_valb, tvb, offset, 1, ENC_BIG_ENDIAN);
467 offset += 1;
468 /* __pmCred.c_valc - Unused */
469 proto_tree_add_item(tree, hf_pcp_creds_valc, tvb, offset, 1, ENC_BIG_ENDIAN);
470 offset += 1;
472 return offset;
475 /* ERROR packet format:
476 signed int error
478 static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
480 gint32 error_num;
482 /* append the type of packet, we can't look this up as it clashes with START */
483 col_append_str(pinfo->cinfo, COL_INFO, "[ERROR] ");
485 /* add the error item to the tree and column */
486 proto_tree_add_item(tree, hf_pcp_pdu_error, tvb, offset, 4, ENC_BIG_ENDIAN);
487 error_num = tvb_get_ntohl(tvb, 4);
488 col_append_fstr(pinfo->cinfo, COL_INFO, "error=%s ",
489 val_to_str(error_num, packettypenames_errors, "Unknown Error:%i"));
490 offset += 4;
491 return offset;
494 /* START packet format:
495 unsigned int sts,
496 struct __pmPDUInfo
498 |> unsigned int zero : 1 bit
499 unsigned int version : 7 bits
500 unsigned int licensed : 8 bits
501 unsigned int authorize : 16 bits
503 static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
505 /* create a start tree tree to hold the information*/
506 proto_item *pcp_start_item;
507 proto_tree *pcp_start_tree;
508 guint32 bits_offset;
510 pcp_start_item = proto_tree_add_item(tree, hf_pcp_start, tvb, 0, -1, ENC_NA);
511 pcp_start_tree = proto_item_add_subtree(pcp_start_item, ett_pcp);
513 bits_offset = offset*8;
515 /* append the type of packet, we can't look this up as it clashes with ERROR */
516 col_append_str(pinfo->cinfo, COL_INFO, "[START]");
518 /* status */
519 proto_tree_add_item(pcp_start_tree, hf_pcp_start_status, tvb, offset, 4, ENC_BIG_ENDIAN);
520 offset += 4;
521 bits_offset += 32; /* 4 bytes */
522 /* zero bit and version bits */
523 proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_zero, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
524 proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_version, tvb, bits_offset+1, 7, ENC_BIG_ENDIAN);
525 offset += 1;
526 /*bits_offset += 8;*/
527 /* licensed */
528 proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN);
529 offset += 1;
530 /* authorize */
531 proto_tree_add_item(pcp_start_tree, hf_pcp_start_authorize, tvb, offset, 2, ENC_BIG_ENDIAN);
532 offset += 2;
533 return offset;
536 /* PMNS_TRAVERSE packet format:
537 guint32 subtype
538 guint32 namelen
539 char name[sizeof(namelen)] + padding
541 static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
543 proto_item *pcp_pmns_traverse_item;
544 proto_tree *pcp_pmns_traverse_tree;
545 guint32 name_len;
546 guint32 padding;
548 /* append the type of packet */
549 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
550 val_to_str(PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x"));
552 pcp_pmns_traverse_item = proto_tree_add_item(tree, hf_pcp_pmns_traverse, tvb, offset, -1, ENC_NA);
553 pcp_pmns_traverse_tree = proto_item_add_subtree(pcp_pmns_traverse_item, ett_pcp);
555 /* subtype */
556 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
557 offset += 4;
558 /* namelen */
559 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
560 name_len = tvb_get_ntohl(tvb, offset); /* get the actual length out so we can use it in the next item */
561 offset += 4;
562 /* name */
563 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
564 offset += name_len; /* increment by whatever the length of the name string was */
566 /* "padding" (not really padding, just what is left over in the old buffer) */
567 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
568 if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
569 padding = 4 - padding; /* we want the inverse of the remainder */
571 proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
572 offset += padding;
574 return offset;
577 /* PMNS_NAMES packet format:
578 guint32 nstrbytes (number of str bytes)
579 guint32 numstatus (0 if no status. Also, if 0, use name_t, otherwise use name_status_t )
580 guint32 numnames
581 __pmPDU names (if numstatus = 0, filled with name_t, otherwise name_status_t)
583 | |> -- name_t --
584 | int namelen
585 | char name[sizeof(namelen)]
587 |> -- name_status_t --
588 int status
589 int namelen
590 char name[sizeof(namelen)]
592 static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
594 proto_item *pcp_pmns_names_item;
595 proto_tree *pcp_pmns_names_tree;
596 proto_item *pcp_pmns_names_name_item;
597 proto_tree *pcp_pmns_names_name_tree;
598 guint32 is_pmns_names_status;
599 guint32 num_names;
600 guint32 name_len;
601 guint32 full_name_len;
602 guint32 padding;
603 guint32 i;
605 /* append the type of packet */
606 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_NAMES, packettypenames, "Unknown Type:0x%02x"));
608 pcp_pmns_names_item = proto_tree_add_item(tree, hf_pcp_pmns_names, tvb, offset, -1, ENC_NA);
609 pcp_pmns_names_tree = proto_item_add_subtree(pcp_pmns_names_item, ett_pcp);
611 /* nstrbytes */
612 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nstrbytes, tvb, offset, 4, ENC_BIG_ENDIAN);
613 offset += 4;
615 /* numstatus */
616 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numstatus, tvb, offset, 4, ENC_BIG_ENDIAN);
617 is_pmns_names_status = tvb_get_ntohl(tvb, offset); /* is the status also present in this PDU? */
618 offset += 4;
620 /* numnames */
621 proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numnames, tvb, offset, 4, ENC_BIG_ENDIAN);
622 num_names = tvb_get_ntohl(tvb, offset); /* get the number of names to iterate through */
623 offset += 4;
625 /* nametrees */
626 for (i=0; i < num_names; i++) {
627 /* find out the size of the name_t/name_status_t before we create the tree */
628 if (is_pmns_names_status) {
629 name_len = tvb_get_ntohl(tvb, offset+4);
630 full_name_len = name_len + 8;
631 } else {
632 name_len = tvb_get_ntohl(tvb, offset);
633 full_name_len = name_len + 4;
635 /* add a new subtree for each name */
636 pcp_pmns_names_name_item = proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nametree,
637 tvb, offset, full_name_len, ENC_NA);
638 pcp_pmns_names_name_tree = proto_item_add_subtree(pcp_pmns_names_name_item, ett_pcp);
640 if (is_pmns_names_status) {
641 /* print out the name status and increment if we're supposed to have it */
642 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_status,
643 tvb, offset, 4, ENC_BIG_ENDIAN);
644 offset += 4;
646 /* namelen */
647 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_namelen,
648 tvb, offset, 4, ENC_BIG_ENDIAN);
649 offset += 4;
650 /* name */
651 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_name,
652 tvb, offset, name_len, ENC_ASCII|ENC_NA);
653 offset += name_len;
654 /* padding */
655 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
656 if (padding != 0) {
657 padding = 4 - padding; /* we want the inverse of the remainder */
658 /* if there is padding, keep going till the remainder of mod 8 */
659 proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
660 offset += padding;
663 return offset;
666 /* PMNS_CHILD packet format:
667 guint32 subtype
668 guint32 namelen
669 char name[namelen]
671 static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
673 proto_item *pcp_pmns_child_item;
674 proto_tree *pcp_pmns_child_tree;
675 guint32 name_len;
677 pcp_pmns_child_item = proto_tree_add_item(tree, hf_pcp_pmns_child, tvb, offset, -1, ENC_NA);
678 pcp_pmns_child_tree = proto_item_add_subtree(pcp_pmns_child_item, ett_pcp);
680 /* append the type of packet */
681 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_CHILD, packettypenames, "Unknown Type:0x%02x"));
683 /* subtype */
684 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
685 offset += 4;
687 /* namelen */
688 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
689 name_len = tvb_get_ntohl(tvb, offset); /* length of the next value */
690 offset += 4;
692 /* name */
693 proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
694 offset += 4;
695 return offset;
698 /* PMNS_IDS packet format
699 guint32 status
700 guint32 numids
701 pmID idlist[numids] (where pmID = uint32)
704 static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
706 proto_item *pcp_pmns_ids_item;
707 proto_tree *pcp_pmns_ids_tree;
708 guint32 num_ids;
709 guint32 i;
711 /* append the type of packet */
712 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
713 val_to_str(PMNS_IDS, packettypenames, "Unknown Type:0x%02x"));
715 pcp_pmns_ids_item = proto_tree_add_item(tree, hf_pcp_pmns_ids, tvb, offset, -1, ENC_NA);
716 pcp_pmns_ids_tree = proto_item_add_subtree(pcp_pmns_ids_item, ett_pcp);
718 /* status */
719 proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_status, tvb, offset, 4, ENC_BIG_ENDIAN);
720 offset += 4;
722 /* numids */
723 proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_numids, tvb, offset, 4, ENC_BIG_ENDIAN);
724 num_ids = tvb_get_ntohl(tvb, offset);
725 offset += 4;
727 /* pmIDs */
728 for (i=0; i<num_ids; i++) {
729 /* pmID */
730 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_pmns_ids_tree, offset);
732 return offset;
735 /* PROFILE packet format
736 guint32 ctxnum;
737 guint32 g_state;
738 guint32 numprof;
739 guint32 pad;
740 pmProfile profiles[numprof]
742 |> pmInDom indom;
743 int state;
744 int numinst;
745 int pad;
747 static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
749 proto_item *pcp_profile_item;
750 proto_tree *pcp_profile_tree;
751 proto_item *pcp_profile_profile_item;
752 proto_tree *pcp_profile_profile_tree;
753 guint32 num_prof;
754 guint32 i;
756 /* append the type of packet */
757 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PROFILE, packettypenames, "Unknown Type:0x%02x"));
759 pcp_profile_item = proto_tree_add_item(tree, hf_pcp_profile, tvb, offset, -1, ENC_NA);
760 pcp_profile_tree = proto_item_add_subtree(pcp_profile_item, ett_pcp);
762 /* ctxnum */
763 proto_tree_add_item(pcp_profile_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
764 offset += 4;
766 /* g_state */
767 proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_g_state, tvb, offset, 4, ENC_BIG_ENDIAN);
768 offset += 4;
770 /* numprof */
771 proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_numprof, tvb, offset, 4, ENC_BIG_ENDIAN);
772 num_prof = tvb_get_ntohl(tvb, offset);
773 offset += 4;
775 /* pad */
776 proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
777 offset += 4;
779 /* iterate through each profile */
780 for (i=0; i<num_prof; i++) {
781 /* subtree for each profile */
782 pcp_profile_profile_item = proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_profile, tvb, offset, 32, ENC_NA);
783 pcp_profile_profile_tree = proto_item_add_subtree(pcp_profile_profile_item, ett_pcp);
785 /* indom */
786 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
787 offset += 4;
789 /* state - include/exclude */
790 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_state, tvb, offset, 4, ENC_BIG_ENDIAN);
791 offset += 4;
793 /* numinst - number of instances to follow */
794 proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
795 offset += 4;
797 /* padding */
798 proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
799 offset += 4;
801 return offset;
804 /* FETCH packet format
805 guint32 cxtnum
806 __pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
807 guint32 numpmid
808 pmID pmidlist[1-x] (unsigned int)
810 static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
812 proto_item *pcp_fetch_item;
813 proto_tree *pcp_fetch_tree;
814 guint32 num_pmid;
815 guint32 i;
817 /* append the type of packet */
818 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
819 val_to_str(FETCH, packettypenames, "Unknown Type:0x%02x"));
821 pcp_fetch_item = proto_tree_add_item(tree, hf_pcp_fetch, tvb, offset, -1, ENC_NA);
822 pcp_fetch_tree = proto_item_add_subtree(pcp_fetch_item, ett_pcp);
824 /* ctxnum */
825 proto_tree_add_item(pcp_fetch_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
826 offset += 4;
828 /* when */
829 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_fetch_tree, offset);
831 /* numpmid */
832 proto_tree_add_item(pcp_fetch_tree, hf_pcp_fetch_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
833 num_pmid = tvb_get_ntohl(tvb, offset);
834 offset += 4;
836 /* pmIDs*/
837 for (i=0; i<num_pmid; i++) {
838 /* decode partial PMID message */
839 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_fetch_tree, offset);
841 return offset;
844 /* RESULT packet format
846 __pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
847 int numpmid
848 _pmPDU data[1-n] (contains v_list types)
850 |> pmID pmid
851 int numval
852 int valfmt
853 __pmValue_PDU vlist[1-n] (contains pmValue PDUs)
855 |> int inst
856 int offset/value
857 (if valfmt == PTR type)
858 int8 type
859 int24 length
860 char value[length]
862 static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
864 proto_item *pcp_results_item;
865 proto_tree *pcp_results_tree;
866 proto_item *pcp_result_item;
867 proto_tree *pcp_result_tree;
868 proto_item *pcp_result_instance_item;
869 proto_tree *pcp_result_instance_tree;
870 guint32 num_pmid;
871 guint32 num_val;
872 guint32 offset_start;
873 guint32 valfmt_type;
874 guint32 value_type;
875 guint32 pmvalueblock_offset;
876 guint32 pmvalueblock_value_length;
877 guint32 i;
878 guint32 j;
880 /* append the type of packet */
881 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(RESULT, packettypenames, "Unknown Type:0x%02x"));
883 pcp_results_item = proto_tree_add_item(tree, hf_pcp_results, tvb, offset, -1, ENC_NA);
884 pcp_results_tree = proto_item_add_subtree(pcp_results_item, ett_pcp);
886 /* when */
887 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_results_tree, offset);
889 /* numpmid */
890 proto_tree_add_item(pcp_results_tree, hf_pcp_results_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
891 num_pmid = tvb_get_ntohl(tvb, offset);
892 offset += 4;
894 /* result */
895 for (i=0; i<num_pmid; i++) {
896 /* work out how long each result should be - set starting offset */
897 offset_start = offset;
899 pcp_result_item = proto_tree_add_item(pcp_results_tree, hf_pcp_result, tvb, offset, -1, ENC_NA);
900 pcp_result_tree = proto_item_add_subtree(pcp_result_item, ett_pcp);
902 /* pmID */
903 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_result_tree, offset);
905 /* numval */
906 proto_tree_add_item(pcp_result_tree, hf_pcp_result_numval, tvb, offset, 4, ENC_BIG_ENDIAN);
907 num_val = tvb_get_ntohl(tvb, offset);
908 offset += 4;
910 /* if there are no numvals, then the valfmt isn't sent */
911 if (num_val > 0) {
913 /* valfmt */
914 proto_tree_add_item(pcp_result_tree, hf_pcp_result_valfmt, tvb, offset, 4, ENC_BIG_ENDIAN);
915 valfmt_type = tvb_get_ntohl(tvb, offset);
916 offset += 4;
918 /* instance */
919 for (j=0; j<num_val; j++) {
920 /* give the subtree name length of inst (int) + offset/va (int) */
921 pcp_result_instance_item = proto_tree_add_item(pcp_result_tree, hf_pcp_instance,
922 tvb, offset, 8, ENC_NA);
923 pcp_result_instance_tree = proto_item_add_subtree(pcp_result_instance_item, ett_pcp);
925 /* inst */
926 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
927 offset += 4;
929 /* valoffset/value: depending on the format, the next 32 bits is the value _OR_ the offset to where
930 the value is */
931 if (valfmt_type == PM_VAL_INSITU) {
932 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_insitu,
933 tvb, offset, 4, ENC_BIG_ENDIAN);
934 } else {
935 /* offset in the packet to find pmValueBlock */
936 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_valoffset,
937 tvb, offset, 4, ENC_BIG_ENDIAN);
938 /* get the offset (not the offset of the count we are at) but where we should look */
939 pmvalueblock_offset = tvb_get_ntohl(tvb, offset);
940 pmvalueblock_offset = pmvalueblock_offset * 4; /* offset values are in 32bit units */
942 /* type */
943 value_type = tvb_get_guint8(tvb, pmvalueblock_offset);
944 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_type,
945 tvb, pmvalueblock_offset, 1, ENC_BIG_ENDIAN);
946 pmvalueblock_offset += 1;
948 /* length */
949 pmvalueblock_value_length = tvb_get_ntoh24(tvb, pmvalueblock_offset);
950 /* can't add a tree item the ususal way as it is outside of the tree */
951 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_vallength,
952 tvb, pmvalueblock_offset, 3, ENC_BIG_ENDIAN);
953 pmvalueblock_offset += 3;
955 /* value - note we go up to the pmvalueblock_value_length - 4,
956 as this value includes the previous 4 bytes */
957 switch (value_type) {
958 case PM_TYPE_32:
959 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int, tvb,
960 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
961 break;
962 case PM_TYPE_U32:
963 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint, tvb,
964 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
965 break;
966 case PM_TYPE_64:
967 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int64, tvb,
968 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
969 break;
970 case PM_TYPE_U64:
971 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint64, tvb,
972 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
973 break;
974 case PM_TYPE_FLOAT:
975 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_float, tvb,
976 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
977 break;
978 case PM_TYPE_DOUBLE:
979 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_double, tvb,
980 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
981 break;
982 case PM_TYPE_STRING:
983 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_ptr, tvb,
984 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_ASCII|ENC_NA);
985 break;
986 case PM_TYPE_AGGREGATE:
987 case PM_TYPE_AGGREGATE_STATIC:
988 proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_aggr, tvb,
989 pmvalueblock_offset, pmvalueblock_value_length-4, ENC_NA);
990 break;
991 case PM_TYPE_EVENT:
992 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_event_unimplemented);
993 break;
994 case PM_TYPE_NOSUPPORT:
995 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_nosupport_unsupported);
996 break;
997 case PM_TYPE_UNKNOWN:
998 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_unknown_unknown_value);
999 break;
1000 default:
1001 expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_unimplemented_value);
1002 break;
1005 /* bump the offset after the instance value _or_ the offset into
1006 the packet (pcp.instance.valoffset) , each being 4 bytes */
1007 offset += 4;
1011 /* we now know how long the field is */
1012 proto_item_set_len(pcp_result_tree, offset-offset_start);
1015 return offset;
1018 /* DESC_REQ pcaket format
1019 pmID pmid (32bit int)
1021 static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1023 proto_item *pcp_desc_req_item;
1024 proto_tree *pcp_desc_req_tree;
1025 proto_item *pcp_desc_req_pmid_item;
1026 proto_tree *pcp_desc_req_pmid_tree;
1027 guint32 bits_offset;
1029 /* append the type of packet */
1030 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC_REQ, packettypenames, "Unknown Type:0x%02x"));
1032 bits_offset = offset*8;
1033 /* subtree for packet type */
1034 pcp_desc_req_item = proto_tree_add_item(tree, hf_pcp_desc_req, tvb, offset, -1, ENC_NA);
1035 pcp_desc_req_tree = proto_item_add_subtree(pcp_desc_req_item, ett_pcp);
1037 /* subtree for pmid */
1038 pcp_desc_req_pmid_item = proto_tree_add_item(pcp_desc_req_tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1039 pcp_desc_req_pmid_tree = proto_item_add_subtree(pcp_desc_req_pmid_item, ett_pcp);
1041 /* flag - 1 bit */
1042 proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
1043 bits_offset += 1;
1044 /* domain - 9 bits */
1045 proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
1046 bits_offset += 9;
1047 /* cluster - 12 bits */
1048 proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
1049 bits_offset += 12;
1050 /* item - 10 bits */
1051 proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
1052 /*bits_offset += 10;*/
1053 offset += 4; /* the bytes offset should now be the same as the bits offset, not that we need this anymore */
1054 return offset;
1058 /* DESC packet format
1059 pmID pmid
1060 int type (base data type)
1061 pmInDom indom
1062 int sem (semantics of the value: instant? counter? etc..)
1063 pmUnits units
1066 signed int dimSpace : 4
1067 signed int dimTime : 4
1068 signed int dimCount : 4
1069 unsigned int scaleSpace : 4
1070 unsigned int scaleTime : 4
1071 signed int scaleCount : 4
1072 unsigned int pad : 8
1074 static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1076 proto_item *pcp_desc_item;
1077 proto_tree *pcp_desc_tree;
1078 proto_item *pcp_desc_units_item;
1079 proto_tree *pcp_desc_units_tree;
1080 guint32 bits_offset;
1082 /* append the type of packet */
1083 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC, packettypenames, "Unknown Type:0x%02x"));
1085 /* root desc tree */
1086 pcp_desc_item = proto_tree_add_item(tree, hf_pcp_desc, tvb, offset, 4, ENC_NA);
1087 pcp_desc_tree = proto_item_add_subtree(pcp_desc_item, ett_pcp);
1089 /* pmID */
1090 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_tree, offset);
1092 /* type */
1093 proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1094 offset += 4;
1096 /* indom */
1097 proto_tree_add_item(pcp_desc_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1098 offset += 4;
1100 /* sem */
1101 proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_sem, tvb, offset, 4, ENC_BIG_ENDIAN);
1102 offset += 4;
1104 /* pmUnits */
1105 bits_offset = offset*8; /* create the bits offset */
1106 pcp_desc_units_item = proto_tree_add_item(pcp_desc_tree, hf_pcp_units, tvb, offset, -1, ENC_NA);
1107 pcp_desc_units_tree = proto_item_add_subtree(pcp_desc_units_item, ett_pcp);
1109 /* dimspace */
1110 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimspace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1111 bits_offset += 4;
1112 /* dimtime */
1113 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimtime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1114 bits_offset += 4;
1115 /* dimcount */
1116 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimcount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1117 bits_offset += 4;
1118 /* scalespace */
1119 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalespace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1120 bits_offset += 4;
1121 /* scaletime */
1122 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scaletime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1123 bits_offset += 4;
1124 /* scalecount */
1125 proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalecount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
1126 /*bits_offset += 4;*/
1127 /* padding */
1128 offset += 3; /* total offset of pmunits before */
1129 proto_tree_add_item(pcp_desc_units_tree, hf_pcp_pdu_padding, tvb, offset, 1, ENC_NA);
1130 offset += 1;
1131 /*bits_offset += 8;*/
1132 return offset;
1136 /* INSTANCE_REQ packet format
1137 pmInDom indom
1138 __pmTimeval when
1139 int inst
1140 int namelen
1141 char name
1143 static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1145 proto_item *pcp_instance_req_item;
1146 proto_tree *pcp_instance_req_tree;
1147 guint32 name_len;
1149 /* append the type of packet */
1150 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x"));
1152 pcp_instance_req_item = proto_tree_add_item(tree, hf_pcp_instance_req, tvb, offset, -1, ENC_NA);
1153 pcp_instance_req_tree = proto_item_add_subtree(pcp_instance_req_item, ett_pcp);
1155 /* indom */
1156 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1157 offset += 4;
1159 /* when */
1160 offset = dissect_pcp_partial_when(tvb, pinfo, pcp_instance_req_tree, offset);
1162 /* inst */
1163 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1164 offset += 4;
1166 /* namelen */
1167 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1168 name_len = tvb_get_ntohl(tvb, offset);
1169 offset += 4;
1171 /* name */
1172 if (name_len > 0) {
1173 proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
1174 offset += name_len;
1176 return offset;
1179 /* TEXT_REQ packet format
1180 int ident
1181 int type
1183 static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1185 proto_item *pcp_text_req_item;
1186 proto_tree *pcp_text_req_tree;
1187 proto_item *pcp_text_req_type_item;
1188 proto_tree *pcp_text_req_type_tree;
1189 guint32 bits_offset;
1190 guint32 type;
1192 /* append the type of packet */
1193 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT_REQ, packettypenames, "Unknown Type:0x%02x"));
1195 pcp_text_req_item = proto_tree_add_item(tree, hf_pcp_text_req, tvb, offset, -1, ENC_NA);
1196 pcp_text_req_tree = proto_item_add_subtree(pcp_text_req_item, ett_pcp);
1198 /* peek at type to decode ident correctly */
1199 type = tvb_get_ntohl(tvb, offset + 4);
1201 /* ident */
1202 if (type & PM_TEXT_PMID) {
1203 offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_text_req_tree, offset);
1204 } else if (type & PM_TEXT_INDOM) {
1205 proto_tree_add_item(pcp_text_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1206 offset += 4;
1209 /* type */
1210 pcp_text_req_type_item = proto_tree_add_item(pcp_text_req_tree, hf_pcp_text_type, tvb, offset, 4, ENC_NA);
1211 pcp_text_req_type_tree = proto_item_add_subtree(pcp_text_req_type_item, ett_pcp);
1212 bits_offset = offset * 8 + 28;
1213 proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_ident, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1214 bits_offset += 2;
1215 proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_format, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
1217 offset += 4;
1218 return offset;
1221 /* TEXT packet format
1222 int ident
1223 int buflen
1224 char buffer
1226 static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1228 proto_item *pcp_text_item;
1229 proto_tree *pcp_text_tree;
1230 guint32 buflen;
1232 /* append the type of packet */
1233 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT, packettypenames, "Unknown Type:0x%02x"));
1235 pcp_text_item = proto_tree_add_item(tree, hf_pcp_text, tvb, offset, -1, ENC_NA);
1236 pcp_text_tree = proto_item_add_subtree(pcp_text_item, ett_pcp);
1238 /* ident */
1239 proto_tree_add_item(pcp_text_tree, hf_pcp_text_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
1240 offset += 4;
1242 /* buflen */
1243 buflen = tvb_get_ntohl(tvb, offset);
1244 proto_tree_add_item(pcp_text_tree, hf_pcp_text_buflen, tvb, offset, 4, ENC_BIG_ENDIAN);
1245 offset += 4;
1247 /* buffer */
1248 proto_tree_add_item(pcp_text_tree, hf_pcp_text_buffer, tvb, offset, buflen, ENC_ASCII|ENC_NA);
1249 offset += buflen;
1251 return offset;
1254 /* INSTANCE packet type
1255 pmInDom indom
1256 int numinst
1257 instlist_t instlist[numinst]
1259 |> int inst
1260 int namelen
1261 char name
1263 static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1265 proto_item *pcp_instances_item;
1266 proto_tree *pcp_instances_tree;
1267 proto_item *pcp_instance_item;
1268 proto_tree *pcp_instance_tree;
1269 guint32 num_inst;
1270 guint32 i;
1271 guint32 name_len;
1272 guint32 padding;
1274 /* append the type of packet */
1275 col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE, packettypenames, "Unknown Type:0x%02x"));
1277 pcp_instances_item = proto_tree_add_item(tree, hf_pcp_instances, tvb, offset, -1, ENC_NA);
1278 pcp_instances_tree = proto_item_add_subtree(pcp_instances_item, ett_pcp);
1280 /* indom */
1281 proto_tree_add_item(pcp_instances_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
1282 offset += 4;
1283 /* numinst */
1284 proto_tree_add_item(pcp_instances_tree, hf_pcp_instances_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
1285 num_inst = tvb_get_ntohl(tvb, offset);
1286 offset += 4;
1288 /* instlist */
1289 for (i=0; i<num_inst; i++) {
1290 /* get the size of the name first, so we know how much offset to give */
1291 name_len = tvb_get_ntohl(tvb, offset+4);
1293 /* give the subtree name length + 2 ints */
1294 pcp_instance_item = proto_tree_add_item(pcp_instances_tree, hf_pcp_instance, tvb, offset, name_len+8, ENC_NA);
1295 pcp_instance_tree = proto_item_add_subtree(pcp_instance_item, ett_pcp);
1297 /* inst */
1298 proto_tree_add_item(pcp_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
1299 offset += 4;
1301 /* namelen */
1302 proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
1303 offset += 4;
1305 /* name */
1306 if (name_len > 0) {
1307 proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
1308 offset += name_len;
1311 /* padding */
1312 padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
1313 if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
1314 padding = 4 - padding; /* we want the inverse of the remainder */
1316 proto_tree_add_item(pcp_instance_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
1317 offset += padding;
1320 return offset;
1323 /* PARTIAL DISSECTOR ROUTINES
1324 these routines are called by dissect_pcp_message_* as needed
1327 static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1329 proto_item *pcp_pmid_item;
1330 proto_tree *pcp_pmid_tree;
1331 guint32 bits_offset;
1333 bits_offset = offset * 8;
1335 /* subtree for pmid */
1336 pcp_pmid_item = proto_tree_add_item(tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
1337 pcp_pmid_tree = proto_item_add_subtree(pcp_pmid_item, ett_pcp);
1339 /* flag - 1 bit */
1340 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
1341 bits_offset += 1;
1342 /* domain - 9 bits */
1343 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
1344 bits_offset += 9;
1345 /* cluster - 12 bits */
1346 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
1347 bits_offset += 12;
1348 /* item - 10 bits */
1349 proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
1350 offset += 4;
1352 return offset;
1355 static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1357 proto_item *pcp_when_item;
1358 proto_tree *pcp_when_tree;
1360 /* when - create a new subtree for each val */
1361 pcp_when_item = proto_tree_add_item(tree, hf_pcp_when, tvb, offset, 8, ENC_NA);
1362 pcp_when_tree = proto_item_add_subtree(pcp_when_item, ett_pcp);
1364 /* when tv_sec */
1365 proto_tree_add_item(pcp_when_tree, hf_pcp_when_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
1366 offset += 4;
1367 /* when tv_usec */
1368 proto_tree_add_item(pcp_when_tree, hf_pcp_when_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
1369 offset += 4;
1371 return offset;
1374 /* MAIN DISSECTING ROUTINE (after passed from dissect_tcp, all packets hit function) */
1375 static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1377 proto_item *root_pcp_item;
1378 proto_tree *pcp_tree;
1379 guint32 packet_type;
1380 gint32 err_bytes;
1381 int offset = 0;
1383 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCP");
1384 col_clear(pinfo->cinfo, COL_INFO);
1387 root_pcp_item = proto_tree_add_item(tree, proto_pcp, tvb, 0, -1, ENC_NA);
1388 pcp_tree = proto_item_add_subtree(root_pcp_item, ett_pcp);
1390 packet_type = tvb_get_ntohl(tvb, 4);
1392 /* check if we are the client requesting or the server */
1393 if (pinfo->srcport == PCP_PORT) {
1394 col_set_str(pinfo->cinfo, COL_INFO, "Server > Client ");
1395 } else {
1396 col_set_str(pinfo->cinfo, COL_INFO, "Client > Server ");
1399 /* PCP packet length */
1400 proto_tree_add_item(pcp_tree, hf_pcp_pdu_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1401 offset += 4;
1402 /* PCP Packet type */
1403 proto_tree_add_item(pcp_tree, hf_pcp_pdu_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1404 offset += 4;
1405 /* PCP Remote PID */
1406 proto_tree_add_item(pcp_tree, hf_pcp_pdu_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
1407 offset += 4;
1409 /* dissect the rest of the packet depending on the type */
1410 switch (packet_type) {
1411 case CREDS:
1412 dissect_pcp_message_creds(tvb, pinfo, pcp_tree, offset);
1413 break;
1415 case START_OR_ERROR:
1416 err_bytes = tvb_get_ntohl(tvb, offset); /* get the first 4 bytes, determine if this is an error or not */
1417 /* errors are signed and are all negative so check for a negative number.
1418 It's the only way we can differentiate between start/error packets */
1419 if (err_bytes < 0) {
1420 dissect_pcp_message_error(tvb, pinfo, pcp_tree, offset);
1421 } else {
1422 dissect_pcp_message_start(tvb, pinfo, pcp_tree, offset);
1424 break;
1426 case PMNS_TRAVERSE:
1427 dissect_pcp_message_pmns_traverse(tvb, pinfo, pcp_tree, offset);
1428 break;
1430 case PMNS_NAMES:
1431 dissect_pcp_message_pmns_names(tvb, pinfo, pcp_tree, offset);
1432 break;
1434 case PMNS_CHILD:
1435 dissect_pcp_message_pmns_child(tvb, pinfo, pcp_tree, offset);
1436 break;
1438 case PMNS_IDS:
1439 dissect_pcp_message_pmns_ids(tvb, pinfo, pcp_tree, offset);
1440 break;
1442 case PROFILE:
1443 dissect_pcp_message_profile(tvb, pinfo, pcp_tree, offset);
1444 break;
1446 case FETCH:
1447 dissect_pcp_message_fetch(tvb, pinfo, pcp_tree, offset);
1448 break;
1450 case RESULT:
1451 dissect_pcp_message_result(tvb, pinfo, pcp_tree, offset);
1452 break;
1454 case DESC_REQ:
1455 dissect_pcp_message_desc_req(tvb, pinfo, pcp_tree, offset);
1456 break;
1458 case DESC:
1459 dissect_pcp_message_desc(tvb, pinfo, pcp_tree, offset);
1460 break;
1462 case INSTANCE_REQ:
1463 dissect_pcp_message_instance_req(tvb, pinfo, pcp_tree, offset);
1464 break;
1466 case INSTANCE:
1467 dissect_pcp_message_instance(tvb, pinfo, pcp_tree, offset);
1468 break;
1470 case TEXT_REQ:
1471 dissect_pcp_message_text_req(tvb, pinfo, pcp_tree, offset);
1472 break;
1474 case TEXT:
1475 dissect_pcp_message_text(tvb, pinfo, pcp_tree, offset);
1476 break;
1478 default:
1479 /* append the type of packet */
1480 col_append_str(pinfo->cinfo, COL_INFO, "[UNIMPLEMENTED TYPE]");
1481 /* if we got here, then we didn't get a packet type that we know of */
1482 expert_add_info(pinfo, pcp_tree, &ei_pcp_unimplemented_packet_type);
1483 break;
1485 return tvb_length(tvb);
1488 static int dissect_pcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1490 /* pass all packets through TCP-reassembally */
1491 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, PCP_HEADER_LEN, get_pcp_message_len, dissect_pcp_message, data);
1492 return tvb_length(tvb);
1495 /* setup the dissecting */
1496 void proto_register_pcp(void)
1498 static hf_register_info hf[] = {
1499 { &hf_pcp_pdu_length,
1500 { "PDU Length", "pcp.length",
1501 FT_UINT32, BASE_DEC,
1502 NULL, 0x0,
1503 NULL, HFILL
1506 { &hf_pcp_pdu_type,
1507 { "Type", "pcp.type",
1508 FT_UINT32, BASE_HEX,
1509 VALS(packettypenames), 0x0,
1510 NULL, HFILL
1513 { &hf_pcp_pdu_pid,
1514 { "From", "pcp.from",
1515 FT_UINT32, BASE_DEC,
1516 NULL, 0x0,
1517 NULL, HFILL
1520 { &hf_pcp_pdu_error,
1521 { "Error", "pcp.error",
1522 FT_INT32, BASE_DEC,
1523 VALS(packettypenames_errors), 0x0,
1524 NULL, HFILL
1527 { &hf_pcp_pdu_padding,
1528 { "Padding", "pcp.padding",
1529 FT_NONE, BASE_NONE,
1530 NULL, 0x0,
1531 NULL, HFILL
1534 { &hf_pcp_creds_number_of,
1535 { "Number of Credentials", "pcp.creds.number",
1536 FT_UINT32, BASE_DEC,
1537 NULL, 0x0,
1538 NULL, HFILL
1541 { &hf_pcp_creds_type,
1542 { "Credentials Type", "pcp.creds.type",
1543 FT_UINT8, BASE_DEC,
1544 VALS(packettypenames_creds), 0x0,
1545 NULL, HFILL
1548 { &hf_pcp_creds_vala,
1549 { "Credentials Value A", "pcp.creds.vala",
1550 FT_UINT8, BASE_DEC,
1551 NULL, 0x0,
1552 NULL, HFILL
1555 { &hf_pcp_creds_valb,
1556 { "Credentials Value B", "pcp.creds.valb",
1557 FT_UINT8, BASE_DEC,
1558 NULL, 0x0,
1559 NULL, HFILL
1562 { &hf_pcp_creds_valc,
1563 { "Credentials Value C", "pcp.creds.valc",
1564 FT_UINT8, BASE_DEC,
1565 NULL, 0x0,
1566 NULL, HFILL
1569 { &hf_pcp_start,
1570 { "Start", "pcp.start",
1571 FT_NONE, BASE_NONE,
1572 NULL, 0x0,
1573 NULL, HFILL
1576 { &hf_pcp_start_zero,
1577 { "Start Compatibility Bit", "pcp.start.zero",
1578 FT_BOOLEAN, BASE_NONE,
1579 NULL, 0x0,
1580 NULL, HFILL
1583 { &hf_pcp_start_version,
1584 { "Version", "pcp.start.version",
1585 FT_UINT8, BASE_DEC, /* not a real 8 bit int, only uses 7 bits */
1586 NULL, 0x0,
1587 NULL, HFILL
1590 { &hf_pcp_start_status,
1591 { "Start Status", "pcp.start.status",
1592 FT_UINT32, BASE_DEC,
1593 NULL, 0x0,
1594 NULL, HFILL
1597 { &hf_pcp_start_licensed,
1598 { "Licensed", "pcp.start.licensed",
1599 FT_UINT8, BASE_DEC,
1600 NULL, 0x0,
1601 NULL, HFILL
1604 { &hf_pcp_start_authorize,
1605 { "Authorize", "pcp.start.authorize",
1606 FT_UINT16, BASE_DEC,
1607 NULL, 0x0,
1608 NULL, HFILL
1611 { &hf_pcp_pmns_traverse,
1612 { "PMNS Traverse", "pcp.pmns_traverse",
1613 FT_NONE, BASE_NONE,
1614 NULL, 0x0,
1615 NULL, HFILL
1618 { &hf_pcp_pmns_subtype,
1619 { "Subtype", "pcp.pmns.subtype",
1620 FT_UINT32, BASE_DEC,
1621 NULL, 0x0,
1622 NULL, HFILL
1625 { &hf_pcp_pmns_namelen,
1626 { "Name Length", "pcp.pmns.namelen",
1627 FT_UINT32, BASE_DEC,
1628 NULL, 0x0,
1629 NULL, HFILL
1632 { &hf_pcp_pmns_name,
1633 { "Name", "pcp.pmns.name",
1634 FT_STRING, BASE_NONE,
1635 NULL, 0x0,
1636 NULL, HFILL
1639 { &hf_pcp_pmns_names,
1640 { "PMNS Names", "pcp.pmns_names",
1641 FT_NONE, BASE_NONE,
1642 NULL, 0x0,
1643 NULL, HFILL
1646 { &hf_pcp_pmns_names_nstrbytes,
1647 { "String Bytes", "pcp.pmns_names.nstrbytes",
1648 FT_UINT32, BASE_DEC,
1649 NULL, 0x0,
1650 NULL, HFILL
1653 { &hf_pcp_pmns_names_numstatus,
1654 { "Status", "pcp.pmns_names.numstatus",
1655 FT_UINT32, BASE_DEC,
1656 NULL, 0x0,
1657 NULL, HFILL
1660 { &hf_pcp_pmns_names_numnames,
1661 { "Number of Names", "pcp.pmns_names.numnames",
1662 FT_UINT32, BASE_DEC,
1663 NULL, 0x0,
1664 NULL, HFILL
1667 { &hf_pcp_pmns_names_nametree,
1668 { "Names", "pcp.pmns_names.nametree",
1669 FT_NONE, BASE_NONE,
1670 NULL, 0x0,
1671 NULL, HFILL
1674 { &hf_pcp_pmns_names_nametree_status,
1675 { "Status", "pcp.pmns_names.nametree.status",
1676 FT_UINT32, BASE_DEC,
1677 NULL, 0x0,
1678 NULL, HFILL
1681 { &hf_pcp_pmns_names_nametree_namelen,
1682 { "Length", "pcp.pmns_names.nametree.namelen",
1683 FT_UINT32, BASE_DEC,
1684 NULL, 0x0,
1685 NULL, HFILL
1688 { &hf_pcp_pmns_names_nametree_name,
1689 { "Name", "pcp.pmns_names.nametree.name",
1690 FT_STRING, BASE_NONE,
1691 NULL, 0x0,
1692 NULL, HFILL
1695 { &hf_pcp_pmns_ids,
1696 { "PMNS IDs", "pcp.pmns_ids",
1697 FT_NONE, BASE_NONE,
1698 NULL, 0x0,
1699 NULL, HFILL
1702 { &hf_pcp_pmns_ids_status,
1703 { "Status", "pcp.pmns_ids.status",
1704 FT_UINT32, BASE_DEC,
1705 NULL, 0x0,
1706 NULL, HFILL
1709 { &hf_pcp_pmns_ids_numids,
1710 { "Number of IDs", "pcp.pmns_ids.numids",
1711 FT_UINT32, BASE_DEC,
1712 NULL, 0x0,
1713 NULL, HFILL
1716 { &hf_pcp_pmns_child,
1717 { "PMID Child", "pcp.pmns.child",
1718 FT_NONE, BASE_NONE,
1719 NULL, 0x0,
1720 NULL, HFILL
1723 { &hf_pcp_pmid,
1724 { "PMID", "pcp.pmid",
1725 FT_UINT32, BASE_DEC,
1726 NULL, 0x0,
1727 NULL, HFILL
1730 { &hf_pcp_pmid_flag,
1731 { "Flag", "pcp.pmid.flag",
1732 FT_BOOLEAN, BASE_NONE,
1733 NULL, 0x0,
1734 NULL, HFILL
1737 { &hf_pcp_pmid_domain,
1738 { "Domain", "pcp.pmid.domain",
1739 FT_UINT16, BASE_DEC, /* uses 9 bits */
1740 NULL, 0x0,
1741 NULL, HFILL
1744 { &hf_pcp_pmid_cluster,
1745 { "Cluster", "pcp.pmid.cluster",
1746 FT_UINT16, BASE_DEC, /* uses 12 bits */
1747 NULL, 0x0,
1748 NULL, HFILL
1751 { &hf_pcp_pmid_item,
1752 { "Item", "pcp.pmid.item",
1753 FT_UINT16, BASE_DEC, /* uses 10 bits */
1754 NULL, 0x0,
1755 NULL, HFILL
1758 { &hf_pcp_pmid_type,
1759 { "Type", "pcp.pmid.type",
1760 FT_INT8, BASE_DEC,
1761 VALS(packettypenames_pm_types), 0x0,
1762 NULL, HFILL
1765 { &hf_pcp_pmid_sem,
1766 { "Type Semantics", "pcp.pmid.sem",
1767 FT_UINT32, BASE_DEC,
1768 VALS(packettypenames_pm_types_sem), 0x0,
1769 NULL, HFILL
1772 { &hf_pcp_pmid_inst,
1773 { "Instance", "pcp.pmid.inst",
1774 FT_UINT32, BASE_DEC,
1775 NULL, 0x0,
1776 NULL, HFILL
1779 { &hf_pcp_profile,
1780 { "Profile", "pcp.profile",
1781 FT_NONE, BASE_NONE,
1782 NULL, 0x0,
1783 NULL, HFILL
1786 { &hf_pcp_ctxnum,
1787 { "Context Number", "pcp.ctxnum",
1788 FT_UINT32, BASE_DEC,
1789 NULL, 0x0,
1790 NULL, HFILL
1793 { &hf_pcp_profile_g_state,
1794 { "Global Include/Exclude State", "pcp.profile.g_state",
1795 FT_UINT32, BASE_DEC,
1796 NULL, 0x0,
1797 NULL, HFILL
1800 { &hf_pcp_profile_numprof,
1801 { "Number of Profiles", "pcp.profile.numprof",
1802 FT_UINT32, BASE_DEC,
1803 NULL, 0x0,
1804 NULL, HFILL
1807 { &hf_pcp_profile_profile,
1808 { "Each Profile", "pcp.profile.profile",
1809 FT_NONE, BASE_NONE,
1810 NULL, 0x0,
1811 NULL, HFILL
1814 { &hf_pcp_profile_profile_state,
1815 { "Include/Exclude State", "pcp.profile.profile.state",
1816 FT_UINT32, BASE_DEC,
1817 NULL, 0x0,
1818 NULL, HFILL
1821 { &hf_pcp_profile_profile_numinst,
1822 { "Number Instances to Follow", "pcp.profile.profile.numinst",
1823 FT_UINT32, BASE_DEC,
1824 NULL, 0x0,
1825 NULL, HFILL
1828 { &hf_pcp_fetch,
1829 { "Fetch", "pcp.fetch",
1830 FT_NONE, BASE_NONE,
1831 NULL, 0x0,
1832 NULL, HFILL
1835 { &hf_pcp_fetch_numpmid,
1836 { "Number PMIDs", "pcp.fetch.numpmid",
1837 FT_UINT32, BASE_DEC,
1838 NULL, 0x0,
1839 NULL, HFILL
1842 { &hf_pcp_when,
1843 { "Time Value", "pcp.when",
1844 FT_NONE, BASE_NONE,
1845 NULL, 0x0,
1846 NULL, HFILL
1849 { &hf_pcp_when_sec,
1850 { "Seconds", "pcp.when.sec",
1851 FT_UINT32, BASE_DEC,
1852 NULL, 0x0,
1853 NULL, HFILL
1856 { &hf_pcp_when_usec,
1857 { "Microseconds", "pcp.when.usec",
1858 FT_UINT32, BASE_DEC,
1859 NULL, 0x0,
1860 NULL, HFILL
1863 { &hf_pcp_desc_req,
1864 { "Description Request", "pcp.desc_req",
1865 FT_NONE, BASE_NONE,
1866 NULL, 0x0,
1867 NULL, HFILL
1870 { &hf_pcp_desc,
1871 { "Description Response", "pcp.desc",
1872 FT_NONE, BASE_NONE,
1873 NULL, 0x0,
1874 NULL, HFILL
1877 { &hf_pcp_units,
1878 { "PMID Units", "pcp.units",
1879 FT_NONE, BASE_NONE,
1880 NULL, 0x0,
1881 NULL, HFILL
1884 { &hf_pcp_units_dimspace,
1885 { "Dimension Space", "pcp.units.dimspace",
1886 FT_UINT8, BASE_DEC,
1887 NULL, 0x0,
1888 NULL, HFILL
1891 { &hf_pcp_units_dimtime,
1892 { "Dimension Time", "pcp.units.dimtime",
1893 FT_UINT8, BASE_DEC,
1894 NULL, 0x0,
1895 NULL, HFILL
1898 { &hf_pcp_units_dimcount,
1899 { "Dimension Count", "pcp.units.dimcount",
1900 FT_UINT8, BASE_DEC,
1901 NULL, 0x0,
1902 NULL, HFILL
1905 { &hf_pcp_units_scalespace,
1906 { "Scale Space", "pcp.units.scalespace",
1907 FT_UINT8, BASE_DEC,
1908 VALS(packettypenames_pm_units_space), 0x0,
1909 NULL, HFILL
1912 { &hf_pcp_units_scaletime,
1913 { "Scale Time", "pcp.units.scalespace",
1914 FT_UINT8, BASE_DEC,
1915 VALS(packettypenames_pm_units_time), 0x0,
1916 NULL, HFILL
1919 { &hf_pcp_units_scalecount,
1920 { "Scale Count", "pcp.units.scalecount",
1921 FT_UINT8, BASE_DEC,
1922 NULL, 0x0,
1923 NULL, HFILL
1926 { &hf_pcp_instance_req,
1927 { "Instance Request", "pcp.instance_req",
1928 FT_NONE, BASE_NONE,
1929 NULL, 0x0,
1930 NULL, HFILL
1933 { &hf_pcp_instances,
1934 { "Instance Response", "pcp.instances",
1935 FT_NONE, BASE_NONE,
1936 NULL, 0x0,
1937 NULL, HFILL
1940 { &hf_pcp_instances_numinst,
1941 { "Number of Instances", "pcp.instance_resp.numinst",
1942 FT_UINT32, BASE_DEC,
1943 NULL, 0x0,
1944 NULL, HFILL
1947 { &hf_pcp_instance,
1948 { "Instance", "pcp.instance",
1949 FT_NONE, BASE_NONE,
1950 NULL, 0x0,
1951 NULL, HFILL
1954 { &hf_pcp_instance_namelen,
1955 { "Name Length", "pcp.instance.namelen",
1956 FT_UINT32, BASE_DEC,
1957 NULL, 0x0,
1958 NULL, HFILL
1961 { &hf_pcp_instance_name,
1962 { "Name", "pcp.instance.name",
1963 FT_STRING, BASE_NONE,
1964 NULL, 0x0,
1965 NULL, HFILL
1968 { &hf_pcp_instance_indom,
1969 { "Instance Domain", "pcp.instance.indom",
1970 FT_UINT32, BASE_DEC,
1971 NULL, 0x0,
1972 NULL, HFILL
1975 { &hf_pcp_instance_valoffset,
1976 { "Instance Offset", "pcp.instance.valoffset",
1977 FT_UINT32, BASE_DEC,
1978 NULL, 0x0,
1979 NULL, HFILL
1982 { &hf_pcp_instance_vallength,
1983 { "Instance Value Length", "pcp.instance.vallength",
1984 FT_INT24, BASE_DEC,
1985 NULL, 0x0,
1986 NULL, HFILL
1989 { &hf_pcp_instance_value_insitu,
1990 { "Instance Value", "pcp.instance.value.uint",
1991 FT_UINT32, BASE_DEC,
1992 NULL, 0x0,
1993 NULL, HFILL
1996 { &hf_pcp_instance_value_ptr,
1997 { "Instance Value", "pcp.instance.value.string",
1998 FT_STRING, BASE_NONE,
1999 NULL, 0x0,
2000 NULL, HFILL
2003 { &hf_pcp_instance_value_int,
2004 { "Instance Value", "pcp.instance.value.int",
2005 FT_INT32, BASE_DEC,
2006 NULL, 0x0,
2007 NULL, HFILL
2010 { &hf_pcp_instance_value_uint,
2011 { "Instance Value", "pcp.instance.value.uint",
2012 FT_UINT32, BASE_DEC,
2013 NULL, 0x0,
2014 NULL, HFILL
2017 { &hf_pcp_instance_value_int64,
2018 { "Instance Value", "pcp.instance.value.int64",
2019 FT_INT64, BASE_DEC,
2020 NULL, 0x0,
2021 NULL, HFILL
2024 { &hf_pcp_instance_value_uint64,
2025 { "Instance Value", "pcp.instance.value.uint64",
2026 FT_UINT64, BASE_DEC,
2027 NULL, 0x0,
2028 NULL, HFILL
2031 { &hf_pcp_instance_value_float,
2032 { "Instance Value", "pcp.instance.value.float",
2033 FT_FLOAT, BASE_NONE,
2034 NULL, 0x0,
2035 NULL, HFILL
2038 { &hf_pcp_instance_value_double,
2039 { "Instance Value", "pcp.instance.value.float",
2040 FT_DOUBLE, BASE_NONE,
2041 NULL, 0x0,
2042 NULL, HFILL
2045 { &hf_pcp_instance_value_aggr,
2046 { "Instance Value", "pcp.instance.value.bytes",
2047 FT_BYTES, BASE_NONE,
2048 NULL, 0x0,
2049 NULL, HFILL
2052 { &hf_pcp_results,
2053 { "Fetch Results", "pcp.results",
2054 FT_NONE, BASE_NONE,
2055 NULL, 0x0,
2056 NULL, HFILL
2059 { &hf_pcp_results_numpmid,
2060 { "Number of PMIDs", "pcp.results.numpmid",
2061 FT_UINT32, BASE_DEC,
2062 NULL, 0x0,
2063 NULL, HFILL
2066 { &hf_pcp_result,
2067 { "Result", "pcp.result",
2068 FT_NONE, BASE_NONE,
2069 NULL, 0x0,
2070 NULL, HFILL
2073 { &hf_pcp_result_numval,
2074 { "Number of Values", "pcp.result.numval",
2075 FT_UINT32, BASE_DEC,
2076 NULL, 0x0,
2077 NULL, HFILL
2080 { &hf_pcp_result_valfmt,
2081 { "Value Encoding Format", "pcp.result.valfmt",
2082 FT_UINT32, BASE_DEC,
2083 VALS(packettypenames_valfmt), 0x0,
2084 NULL, HFILL
2087 { &hf_pcp_text_req,
2088 { "Text Request", "pcp.text_req",
2089 FT_NONE, BASE_NONE,
2090 NULL, 0x0,
2091 NULL, HFILL
2094 { &hf_pcp_text_type,
2095 { "Help Text Type", "pcp.text.type",
2096 FT_NONE, BASE_NONE,
2097 NULL, 0x0,
2098 NULL, HFILL
2101 { &hf_pcp_text_type_format,
2102 { "Text Type Format", "pcp.text.type.format",
2103 FT_UINT8, BASE_DEC,
2104 VALS(packettypenames_text_type_format), 0x0,
2105 NULL, HFILL
2108 { &hf_pcp_text_type_ident,
2109 { "Text Type Ident", "pcp.text.type.ident",
2110 FT_UINT8, BASE_DEC,
2111 VALS(packettypenames_text_type_ident), 0x0,
2112 NULL, HFILL
2115 { &hf_pcp_text,
2116 { "Text Response", "pcp.text",
2117 FT_NONE, BASE_NONE,
2118 NULL, 0x0,
2119 NULL, HFILL
2122 { &hf_pcp_text_ident,
2123 { "Text Ident (raw)", "pcp.text.ident",
2124 FT_UINT32, BASE_DEC,
2125 NULL, 0x0,
2126 NULL, HFILL
2129 { &hf_pcp_text_buflen,
2130 { "Text Buffer Length", "pcp.text.buflen",
2131 FT_UINT32, BASE_DEC,
2132 NULL, 0x0,
2133 NULL, HFILL
2136 { &hf_pcp_text_buffer,
2137 { "Text Buffer", "pcp.text.buffer",
2138 FT_STRING, BASE_NONE,
2139 NULL, 0x0,
2140 NULL, HFILL
2145 static gint *ett[] = {
2146 &ett_pcp,
2147 &ett_pcp_pdu_length,
2148 &ett_pcp_pdu_type,
2149 &ett_pcp_pdu_pid,
2150 &ett_pcp_pdu_error,
2151 &ett_pcp_pdu_padding,
2152 &ett_pcp_creds_number_of,
2153 &ett_pcp_creds_type,
2154 &ett_pcp_creds_vala,
2155 &ett_pcp_creds_valb,
2156 &ett_pcp_creds_valc,
2157 &ett_pcp_start,
2158 &ett_pcp_start_status,
2159 &ett_pcp_start_zero,
2160 &ett_pcp_start_version,
2161 &ett_pcp_start_licensed,
2162 &ett_pcp_start_authorize,
2163 &ett_pcp_pmns_traverse,
2164 &ett_pcp_pmns_subtype,
2165 &ett_pcp_pmns_namelen,
2166 &ett_pcp_pmns_name,
2167 &ett_pcp_pmns_names,
2168 &ett_pcp_pmns_names_nstrbytes,
2169 &ett_pcp_pmns_names_numstatus,
2170 &ett_pcp_pmns_names_numnames,
2171 &ett_pcp_pmns_names_nametree,
2172 &ett_pcp_pmns_names_nametree_status,
2173 &ett_pcp_pmns_names_nametree_namelen,
2174 &ett_pcp_pmns_names_nametree_name,
2175 &ett_pcp_pmns_ids,
2176 &ett_pcp_pmns_ids_status,
2177 &ett_pcp_pmns_ids_numids,
2178 &ett_pcp_pmns_child,
2179 &ett_pcp_pmid,
2180 &ett_pcp_pmid_flag,
2181 &ett_pcp_pmid_domain,
2182 &ett_pcp_pmid_cluster,
2183 &ett_pcp_pmid_item,
2184 &ett_pcp_pmid_type,
2185 &ett_pcp_pmid_sem,
2186 &ett_pcp_profile,
2187 &ett_pcp_ctxnum,
2188 &ett_pcp_profile_g_state,
2189 &ett_pcp_profile_numprof,
2190 &ett_pcp_profile_profile,
2191 &ett_pcp_profile_profile_state,
2192 &ett_pcp_profile_profile_numinst,
2193 &ett_pcp_fetch,
2194 &ett_pcp_fetch_numpmid,
2195 &ett_pcp_when,
2196 &ett_pcp_when_sec,
2197 &ett_pcp_when_usec,
2198 &ett_pcp_desc_req,
2199 &ett_pcp_units,
2200 &ett_pcp_units_dimspace,
2201 &ett_pcp_units_dimtime,
2202 &ett_pcp_units_dimcount,
2203 &ett_pcp_units_scalespace,
2204 &ett_pcp_units_scaletime,
2205 &ett_pcp_units_scalecount,
2206 &ett_pcp_instance,
2207 &ett_pcp_instance_req,
2208 &ett_pcp_instance_namelen,
2209 &ett_pcp_instance_name,
2210 &ett_pcp_instance_indom,
2211 &ett_pcp_instance_inst,
2212 &ett_pcp_instance_valoffset,
2213 &ett_pcp_instance_vallength,
2214 &ett_pcp_instance_value_insitu,
2215 &ett_pcp_instance_value_ptr,
2216 &ett_pcp_instance_value_int,
2217 &ett_pcp_instance_value_uint,
2218 &ett_pcp_instance_value_int64,
2219 &ett_pcp_instance_value_uint64,
2220 &ett_pcp_instance_value_float,
2221 &ett_pcp_instance_value_double,
2222 &ett_pcp_instance_value_aggr,
2223 &ett_pcp_instances,
2224 &ett_pcp_instances_numinst,
2225 &ett_pcp_results,
2226 &ett_pcp_results_numpmid,
2227 &ett_pcp_result,
2228 &ett_pcp_result_numval,
2229 &ett_pcp_result_valfmt,
2230 &ett_pcp_text_req,
2231 &ett_pcp_text_type,
2232 &ett_pcp_text_type_format,
2233 &ett_pcp_text_type_ident,
2234 &ett_pcp_text,
2235 &ett_pcp_text_ident,
2236 &ett_pcp_text_buflen,
2237 &ett_pcp_text_buffer,
2240 static ei_register_info ei[] = {
2241 { &ei_pcp_type_event_unimplemented, { "pcp.pmid.type.event.unimplemented", PI_UNDECODED, PI_WARN, "PM_TYPE_EVENT: Unimplemented Value Type", EXPFILL }},
2242 { &ei_pcp_type_nosupport_unsupported, { "pcp.pmid.type.nosupport.unsupported", PI_UNDECODED, PI_WARN, "PM_TYPE_NOSUPPORT: Unsupported Value Type", EXPFILL }},
2243 { &ei_pcp_type_unknown_unknown_value, { "pcp.pmid.type.unknown.unknown_value", PI_UNDECODED, PI_WARN, "PM_TYPE_UNKNOWN: Unknown Value Type", EXPFILL }},
2244 { &ei_pcp_unimplemented_value, { "pcp.pmid.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Value Type", EXPFILL }},
2245 { &ei_pcp_unimplemented_packet_type, { "pcp.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Packet Type", EXPFILL }},
2248 expert_module_t* expert_pcp;
2250 expert_pcp = expert_register_protocol(proto_pcp);
2251 expert_register_field_array(expert_pcp, ei, array_length(ei));
2253 proto_pcp = proto_register_protocol("Performance Co-Pilot", "PCP", "pcp");
2255 proto_register_field_array(proto_pcp, hf, array_length(hf));
2256 proto_register_subtree_array(ett, array_length(ett));
2259 void proto_reg_handoff_pcp(void)
2261 dissector_handle_t pcp_handle;
2263 pcp_handle = new_create_dissector_handle(dissect_pcp, proto_pcp);
2264 dissector_add_uint("tcp.port", PCP_PORT, pcp_handle);
2268 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2270 * Local variables:
2271 * c-basic-offset: 4
2272 * tab-width: 8
2273 * indent-tabs-mode: nil
2274 * End:
2276 * vi: set shiftwidth=4 tabstop=4 expandtab:
2277 * :indentSize=4:tabSize=8:noTabs=true: