2 * Routines for IBM WebSphere MQ PCF packet dissection
4 * metatech <metatech@flashmail.com>
5 * robionekenobi <robionekenobi@bluewin.ch>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* MQ PCF in a nutshell
30 * The MQ Programmable Command Formats API allows remotely configuring a queue manager.
32 * MQ PCF documentation is called "WebSphere MQ Programmable Command Formats and Administration Interface"
41 #include <epan/packet.h>
42 #include <epan/proto.h>
43 #include <epan/expert.h>
44 #include <epan/prefs.h>
45 #include <epan/value_string.h>
46 #include <epan/strutil.h>
47 #include "packet-mq.h"
48 #include "wmem/wmem.h"
50 #define PCF_MAX_PARM 999
51 #define PCF_MAX_LIST 20000
53 guint mq_pcf_maxprm = PCF_MAX_PARM;
54 guint mq_pcf_maxlst = PCF_MAX_LIST;
56 static int proto_mqpcf = -1;
58 static int hf_mqpcf_cfh_type = -1;
59 static int hf_mqpcf_cfh_length = -1;
60 static int hf_mqpcf_cfh_version = -1;
61 static int hf_mqpcf_cfh_command = -1;
62 static int hf_mqpcf_cfh_MsgSeqNbr = -1;
63 static int hf_mqpcf_cfh_control = -1;
64 static int hf_mqpcf_cfh_compcode = -1;
65 static int hf_mqpcf_cfh_reason = -1;
66 static int hf_mqpcf_cfh_ParmCount = -1;
68 static int hf_mq_pcf_prmtyp = -1;
69 static int hf_mq_pcf_prmlen = -1;
70 static int hf_mq_pcf_prmid = -1;
71 static int hf_mq_pcf_filterop = -1;
72 static int hf_mq_pcf_prmccsid = -1;
73 static int hf_mq_pcf_prmstrlen = -1;
74 static int hf_mq_pcf_prmcount = -1;
75 static int hf_mq_pcf_prmunused = -1;
77 static int hf_mq_pcf_string = -1;
78 static int hf_mq_pcf_stringlist = -1;
79 static int hf_mq_pcf_int = -1;
80 static int hf_mq_pcf_intlist = -1;
81 static int hf_mq_pcf_bytestring = -1;
82 static int hf_mq_pcf_int64 = -1;
83 static int hf_mq_pcf_int64list = -1;
85 static expert_field ei_mq_pcf_prmln0 = EI_INIT;
86 static expert_field ei_mq_pcf_MaxInt = EI_INIT;
87 static expert_field ei_mq_pcf_MaxStr = EI_INIT;
88 static expert_field ei_mq_pcf_MaxI64 = EI_INIT;
89 static expert_field ei_mq_pcf_MaxPrm = EI_INIT;
91 static gint ett_mqpcf_prm = -1;
92 static gint ett_mqpcf = -1;
93 static gint ett_mqpcf_cfh = -1;
95 #define MQ_TEXT_CFH "MQ Command Format Header"
97 guint32 dissect_mqpcf_getDigits(guint uCnt)
99 return (guint) log10(uCnt) + 1;
102 guint8 *dissect_mqpcf_parm_getintval(guint uPrm,guint uVal)
104 value_string *pVs=NULL;
105 pVs=(value_string *)try_val_to_str(uPrm,GET_VALSV(MQCFINT_Parse));
109 return (guint8 *)try_val_to_str(uVal,pVs);
114 void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset, guint uPrm,
115 guint uVal, int hfindex, guint iCnt, guint iMaxCnt, guint iDigit)
117 header_field_info *hfinfo;
120 pVal=dissect_mqpcf_parm_getintval(uPrm,uVal);
121 hfinfo=proto_registrar_get_nth(hfindex);
127 proto_tree_add_int_format(tree, hfindex, tvb, offset , 4, uVal,
128 "%s[%*d]: %8d-%s", hfinfo->name, iDigit, iCnt, uVal, pVal);
132 proto_tree_add_int_format(tree, hfindex, tvb, offset , 4, uVal,
133 "%s[%*d]: %8x-%d", hfinfo->name, iDigit, iCnt, uVal, uVal);
140 proto_tree_add_int_format_value(tree, hfindex, tvb, offset , 4, uVal,
141 "%8d-%s", uVal, pVal);
145 proto_tree_add_int_format_value(tree, hfindex, tvb, offset , 4, uVal,
146 "%8x-%d", uVal, uVal);
151 static void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree, guint offset,guint32 uCount,guint bLittleEndian)
167 const char sMaxLst[] = " Max # of List reached. DECODE interrupted (actual %u of %u)";
168 const char sPrmLn0[] = " MQPrm[%3u] has a zero length. DECODE Failed (MQPrm Count: %u)";
169 const char sMaxPrm[] = " Max # of Parm reached. DECODE interrupted (actual %u of %u)";
172 proto_tree *tree=NULL;
174 uDig=dissect_mqpcf_getDigits(uCount);
176 for (u = 0; u < uCount && u < mq_pcf_maxprm; u++)
179 uTyp = tvb_get_guint32_endian(tvb, offset , bLittleEndian);
180 uLen = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
183 ti = proto_tree_add_text(mq_tree, tvb, offset, 12, sPrmLn0, u+1, uCount);
184 expert_add_info(pinfo, ti, &ei_mq_pcf_prmln0);
188 uPrm=tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
191 g_snprintf(strPrm,(gulong)sizeof(strPrm)-1," %-s[%*u] {%2d-%-15.15s} %8x/%5d-%-30.30s",
193 uTyp,val_to_str_const(uTyp,GET_VALSV(PrmTyp)," Unknown")+6,
194 uPrm,uPrm,val_to_str_const(uPrm,GET_VALSV(PrmId),"Unknown"));
200 case MQ_MQCFT_COMMAND:
202 case MQ_MQCFT_RESPONSE:
204 case MQ_MQCFT_INTEGER:
207 uVal = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
208 pVal = dissect_mqpcf_parm_getintval(uPrm,uVal);
211 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %d-%s",
216 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %8x-%d",
219 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
220 proto_tree_add_item(tree, hf_mq_pcf_prmtyp, tvb, offset , 4, bLittleEndian);
221 proto_tree_add_item(tree, hf_mq_pcf_prmlen, tvb, offset + 4, 4, bLittleEndian);
222 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
224 dissect_mqpcf_parm_int(tvb, tree, offset+uLenF, uPrm, uVal, hf_mq_pcf_int, 0, 0, 0);
227 case MQ_MQCFT_STRING:
231 uCCS = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
232 uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
233 sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8,
234 uSLn, (uCCS!=500)?ENC_ASCII:ENC_EBCDIC);
236 strip_trailing_blanks(sStr,uSLn);
238 format_text_chr(sStr, strlen(sStr), '.');
240 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s", strPrm, sStr);
241 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
243 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
244 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
245 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
246 proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
247 proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);
249 proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 8, uSLn, (uCCS!=500)?ENC_ASCII:ENC_EBCDIC);
252 case MQ_MQCFT_INTEGER_LIST:
257 uCnt = tvb_get_guint32_endian(tvb, offset+uLenF, bLittleEndian);
258 uDigit=dissect_mqpcf_getDigits(uCnt);
260 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)",strPrm,uCnt);
261 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
263 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
264 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
265 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
266 proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);
269 for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
271 uVal = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
272 dissect_mqpcf_parm_int(tvb, tree, offset, uPrm, uVal, hf_mq_pcf_intlist, u2+1, uCnt, uDigit);
277 ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
278 expert_add_info(pinfo, ti, &ei_mq_pcf_MaxInt);
282 case MQ_MQCFT_STRING_LIST:
287 header_field_info *hfinfo;
289 hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist);
291 uCCS = tvb_get_guint32_endian(tvb, offset + uLenF , bLittleEndian);
292 uCnt = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
293 uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian);
295 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen,"%s Cnt(%d)",strPrm,uCnt);
297 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
298 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
299 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
300 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
301 proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
302 proto_tree_add_item(tree, hf_mq_pcf_prmcount , tvb, offset + 16, 4, bLittleEndian);
303 proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);
305 uDigit=dissect_mqpcf_getDigits(uCnt);
308 for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
310 sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
311 uSLn, (uCCS!=500)?ENC_ASCII:ENC_EBCDIC);
313 strip_trailing_blanks(sStr,uSLn);
315 format_text_chr(sStr, strlen(sStr), '.');
317 proto_tree_add_string_format(tree, hf_mq_pcf_stringlist, tvb, offset, uSLn, sStr,
318 "%s[%*d]: %s",hfinfo->name, uDigit, u2+1, sStr);
323 ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
324 expert_add_info(pinfo, ti, &ei_mq_pcf_MaxStr);
332 case MQ_MQCFT_BYTE_STRING:
334 uSLn = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
337 guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.');
338 guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.');
341 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE);
345 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s A(%s) E(%s)", strPrm, sStrA, sStrE);
350 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s <MISSING>", strPrm);
352 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
354 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
355 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
356 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
357 proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 12, 4, bLittleEndian);
359 proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 4 , uSLn, bLittleEndian);
362 case MQ_MQCFT_TRACE_ROUTE:
364 case MQ_MQCFT_REPORT:
366 case MQ_MQCFT_INTEGER_FILTER:
370 uOpe = tvb_get_guint32_endian(tvb, offset + uLenF , bLittleEndian);
371 uVal = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
373 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %d",
374 strPrm, val_to_str(uOpe, GET_VALSV(FilterOP)," Unknown (0x%02x)")+7, uVal);
375 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
377 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
378 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
379 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
380 proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
382 proto_tree_add_item(tree, hf_mq_pcf_int, tvb, offset + uLenF + 4, 4, bLittleEndian);
385 case MQ_MQCFT_STRING_FILTER:
390 uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
391 uCCS = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
392 uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian);
393 sStr = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 12, uSLn, (uCCS!=500)?ENC_ASCII:ENC_EBCDIC), uSLn, '.');
394 strip_trailing_blanks(sStr,uSLn);
396 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %s",
397 strPrm, val_to_str(uOpe, GET_VALSV(FilterOP)," Unknown (0x%02x)")+7, sStr);
398 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
400 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
401 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
402 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
403 proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
404 proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 16, 4, bLittleEndian);
405 proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);
407 proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 12, uSLn, (uCCS!=500)?ENC_ASCII:ENC_EBCDIC);
410 case MQ_MQCFT_BYTE_STRING_FILTER:
413 uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
414 uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
417 guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8,uSLn,ENC_ASCII) , uSLn, '.');
418 guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8,uSLn,ENC_EBCDIC), uSLn, '.');
419 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s A(%s) E(%s)",
420 strPrm, val_to_str(uOpe, GET_VALSV(FilterOP)," Unknown (0x%02x)")+7, sStrA, sStrE);
424 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s <MISSING>",
425 strPrm, val_to_str(uOpe, GET_VALSV(FilterOP)," Unknown (0x%02x)")+7);
427 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
429 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
430 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
431 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
432 proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
433 proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);
435 proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 8 , uSLn,bLittleEndian);
438 case MQ_MQCFT_COMMAND_XR:
440 case MQ_MQCFT_XR_MSG:
442 case MQ_MQCFT_XR_ITEM:
444 case MQ_MQCFT_XR_SUMMARY:
448 case MQ_MQCFT_STATISTICS:
450 case MQ_MQCFT_ACCOUNTING:
452 case MQ_MQCFT_INTEGER64:
454 uVal64 = tvb_get_guint64_endian(tvb, offset + uLenF + 4, bLittleEndian);
455 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)",
456 strPrm, uVal64, uVal64);
457 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
459 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
460 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
461 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
462 proto_tree_add_item(tree, hf_mq_pcf_prmunused, tvb, offset + 12, 4, bLittleEndian);
464 proto_tree_add_item(tree, hf_mq_pcf_int64, tvb, offset + uLenF + 4, 8, bLittleEndian);
467 case MQ_MQCFT_INTEGER64_LIST:
471 header_field_info *hfinfo;
473 hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list);
475 uCnt = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
476 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt);
477 tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
478 uDigit=dissect_mqpcf_getDigits(uCnt);
480 proto_tree_add_item(tree, hf_mq_pcf_prmtyp , tvb, offset , 4, bLittleEndian);
481 proto_tree_add_item(tree, hf_mq_pcf_prmlen , tvb, offset + 4, 4, bLittleEndian);
482 proto_tree_add_item(tree, hf_mq_pcf_prmid , tvb, offset + 8, 4, bLittleEndian);
483 proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);
486 for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
488 uVal64 = tvb_get_guint64_endian(tvb, offset, bLittleEndian);
489 proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64,
490 "%s[%*d]: %" G_GINT64_MODIFIER "d",hfinfo->name, uDigit, u2+1, uVal64);
495 ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
496 expert_add_info(pinfo, ti, &ei_mq_pcf_MaxI64);
505 ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, sMaxPrm, u, uCount);
506 expert_add_info(pinfo, ti, &ei_mq_pcf_MaxPrm);
510 static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, struct mqinfo* mqinfo)
513 gboolean bLittleEndian;
515 bLittleEndian = ((mqinfo->encoding & MQ_MQENC_INTEGER_MASK)==MQ_MQENC_INTEGER_REVERSED)?ENC_LITTLE_ENDIAN:ENC_BIG_ENDIAN;
517 if (tvb_length(tvb) >= 36)
519 gint iSizeMQCFH = 36;
520 guint32 iCommand = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
526 proto_tree *mqroot_tree;
534 uTyp=tvb_get_guint32_endian(tvb, offset , bLittleEndian);
535 uCmd=tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
536 uCC =tvb_get_guint32_endian(tvb, offset + 24, bLittleEndian);
537 uRC =tvb_get_guint32_endian(tvb, offset + 28, bLittleEndian);
538 uCnt=tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian);
542 g_snprintf(sTmp,(gulong)sizeof(sTmp)-1," %-s [%d-%s] {%d-%s} PrmCnt(%d) CC(%d-%s) RC(%d-%s)",
544 uTyp,val_to_str_const(uTyp,GET_VALSV(mqcft),"Unknown"),
545 uCmd,val_to_str_const(uCmd,GET_VALSV(mqcmd),"Unknown"),
547 uCC,val_to_str_const(uCC,GET_VALSV(mqcc),"Unknown"),
548 uRC,val_to_str_const(uRC,GET_VALSV(mqrc),"Unknown"));
552 g_snprintf(sTmp,(gulong)sizeof(sTmp)-1," %-s [%d-%s] {%d-%s} PrmCnt(%d)",
554 uTyp,val_to_str_const(uTyp,GET_VALSV(mqcft),"Unknown"),
555 uCmd,val_to_str_const(uCmd,GET_VALSV(mqcmd),"Unknown"),
559 ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, ENC_NA);
561 proto_item_append_text(ti, " (%s)", val_to_str(iCommand, GET_VALSV(mqcmd), "Unknown (0x%02x)"));
562 mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);
564 ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMQCFH, "%s",sTmp);
565 mq_tree = proto_item_add_subtree(ti, ett_mqpcf_cfh);
567 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type , tvb, offset + 0, 4, bLittleEndian);
568 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length , tvb, offset + 4, 4, bLittleEndian);
569 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version , tvb, offset + 8, 4, bLittleEndian);
570 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command , tvb, offset + 12, 4, bLittleEndian);
571 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian);
572 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control , tvb, offset + 20, 4, bLittleEndian);
573 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian);
574 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason , tvb, offset + 28, 4, bLittleEndian);
575 proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian);
576 dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian);
581 static gboolean dissect_mqpcf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
583 if (tvb_length(tvb) >= 36)
585 struct mqinfo* mqinfo = (struct mqinfo *)data;
586 if (strncmp((const char*)mqinfo->format, MQ_MQFMT_ADMIN, 8) == 0
587 || strncmp((const char*)mqinfo->format, MQ_MQFMT_EVENT, 8) == 0
588 || strncmp((const char*)mqinfo->format, MQ_MQFMT_PCF, 8) == 0)
590 /* Dissect the packet */
591 dissect_mqpcf(tvb, pinfo, tree, mqinfo);
598 void proto_register_mqpcf(void)
600 expert_module_t* expert_mqpcf;
602 static hf_register_info hf[] =
604 { &hf_mqpcf_cfh_type , { "Type.....", "mqpcf.cfh.type", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(mqcft)), 0x0, "CFH type", HFILL }},
605 { &hf_mqpcf_cfh_length , { "Length...", "mqpcf.cfh.length", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH length", HFILL }},
606 { &hf_mqpcf_cfh_version , { "Version..", "mqpcf.cfh.version", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH version", HFILL }},
607 { &hf_mqpcf_cfh_command , { "Command..", "mqpcf.cfh.command", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(mqcmd)), 0x0, "CFH command", HFILL }},
608 { &hf_mqpcf_cfh_MsgSeqNbr, { "MsgSeqNbr", "mqpcf.cfh.MsgSeqNbr", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH message sequence number", HFILL }},
609 { &hf_mqpcf_cfh_control , { "Control..", "mqpcf.cfh.control", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH control", HFILL }},
610 { &hf_mqpcf_cfh_compcode , { "CompCode.", "mqpcf.cfh.compcode", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(mqcc)), 0x0, "CFH completion code", HFILL }},
611 { &hf_mqpcf_cfh_reason , { "ReasCode.", "mqpcf.cfh.reasoncode", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(mqrc)), 0x0, "CFH reason code", HFILL }},
612 { &hf_mqpcf_cfh_ParmCount, { "ParmCount", "mqpcf.cfh.ParmCount", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH parameter count", HFILL }},
614 { &hf_mq_pcf_prmtyp , { "ParmTyp..", "mqpcf.parm.type", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(PrmTyp)), 0x0, "MQPCF parameter type", HFILL }},
615 { &hf_mq_pcf_prmlen , { "ParmLen..", "mqpcf.parm.len", FT_UINT32, BASE_DEC, NULL, 0x0, "MQPCF parameter length", HFILL }},
616 { &hf_mq_pcf_prmid , { "ParmID...", "mqpcf.parm.id", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(PrmId)), 0x0, "MQPCF parameter id", HFILL }},
617 { &hf_mq_pcf_filterop , { "FilterOP.", "mqpcf.filter.op", FT_UINT32, BASE_DEC, VALS(&GET_VALSV(FilterOP)), 0x0, "MQPCF Filter operator", HFILL }},
618 { &hf_mq_pcf_prmccsid , { "ParmCCSID", "mqpcf.parm.ccsid", FT_UINT32, BASE_DEC, NULL, 0x0, "MQPCF parameter ccsid", HFILL }},
619 { &hf_mq_pcf_prmstrlen , { "ParmStrLn", "mqpcf.parm.strlen", FT_UINT32, BASE_DEC, NULL, 0x0, "MQPCF parameter strlen", HFILL }},
620 { &hf_mq_pcf_prmcount , { "ParmCount", "mqpcf.parm.count", FT_UINT32, BASE_DEC, NULL, 0x0, "MQPCF parameter count", HFILL }},
621 { &hf_mq_pcf_prmunused , { "ParmUnuse", "mqpcf.parm.unused", FT_UINT32, BASE_DEC, NULL, 0x0, "MQPCF parameter unused", HFILL }},
622 { &hf_mq_pcf_string , { "String...", "mqpcf.parm.string", FT_STRINGZ, BASE_NONE, NULL, 0x0, "MQPCF parameter string", HFILL }},
623 { &hf_mq_pcf_stringlist , { "StrList..", "mqpcf.parm.stringlist", FT_STRINGZ, BASE_NONE, NULL, 0x0, "MQPCF parameter string list", HFILL }},
624 { &hf_mq_pcf_int , { "Integer..", "mqpcf.parm.int", FT_INT32, BASE_DEC, NULL, 0x0, "MQPCF parameter int", HFILL }},
625 { &hf_mq_pcf_intlist , { "IntList..", "mqpcf.parm.intlist", FT_INT32, BASE_DEC, NULL, 0x0, "MQPCF parameter int list", HFILL }},
626 { &hf_mq_pcf_bytestring , { "ByteStr..", "mqpcf.parm.bytestring", FT_BYTES, BASE_NONE, NULL, 0x0, "MQPCF parameter byte string", HFILL }},
627 { &hf_mq_pcf_int64 , { "Int64....", "mqpcf.parm.int64", FT_INT64, BASE_DEC, NULL, 0x0, "MQPCF parameter int64", HFILL }},
628 { &hf_mq_pcf_int64list , { "Int64List", "mqpcf.parm.int64list", FT_INT64, BASE_DEC, NULL, 0x0, "MQPCF parameter int64 list", HFILL }},
636 static ei_register_info ei[] =
638 { &ei_mq_pcf_prmln0, { "mqpcf.parm.len0", PI_MALFORMED, PI_ERROR, "MQPCF Parameter length is 0", EXPFILL }},
639 { &ei_mq_pcf_MaxInt, { "mqpcf.parm.IntList", PI_UNDECODED, PI_WARN, "MQPCF Parameter Integer list exhausted", EXPFILL }},
640 { &ei_mq_pcf_MaxStr, { "mqpcf.parm.StrList", PI_UNDECODED, PI_WARN, "MQPCF Parameter String list exhausted", EXPFILL }},
641 { &ei_mq_pcf_MaxI64, { "mqpcf.parm.Int64List", PI_UNDECODED, PI_WARN, "MQPCF Parameter Int64 list exhausted", EXPFILL }},
642 { &ei_mq_pcf_MaxPrm, { "mqpcf.parm.MaxPrm", PI_UNDECODED, PI_WARN, "MQPCF Max number of parameter exhausted", EXPFILL }},
645 module_t *mq_pcf_module;
647 proto_mqpcf = proto_register_protocol("WebSphere MQ Programmable Command Formats", "MQ PCF", "mqpcf");
648 proto_register_field_array(proto_mqpcf, hf, array_length(hf));
649 proto_register_subtree_array(ett, array_length(ett));
651 expert_mqpcf = expert_register_protocol(proto_mqpcf);
652 expert_register_field_array(expert_mqpcf, ei, array_length(ei));
654 mq_pcf_module = prefs_register_protocol(proto_mqpcf, NULL);
655 prefs_register_uint_preference(mq_pcf_module,"maxprm",
656 "Set the maximun number of parameter in the PCF to decode",
657 "When dissecting PCF there can be a lot of parameters."
658 " You can limit the number of parameter decoded, before it continue with the next PCF.",
660 prefs_register_uint_preference(mq_pcf_module,"maxlst",
661 "Set the maximun number of Parameter List that are displayed",
662 "When dissecting a parameter of a PCFm, if it is a StringList, IntegerList or Integer64 List, "
663 " You can limit the number of element displayed, before it continue with the next Parameter.",
668 void proto_reg_handoff_mqpcf(void)
670 heur_dissector_add("mq", dissect_mqpcf_heur, proto_mqpcf);
674 * Editor modelines - http://www.wireshark.org/tools/modelines.html
679 * indent-tabs-mode: t
682 * vi: set shiftwidth=4 tabstop=4 noexpandtab:
683 * :indentSize=4:tabSize=4:noTabs=false: