1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
/* packet-mq-pcf.c
* Routines for IBM WebSphere MQ PCF packet dissection
*
* metatech <metatech@flashmail.com>
*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* MQ PCF in a nutshell
*
* The MQ Programmable Command Formats API allows remotely configuring a queue manager.
*
* MQ PCF documentation is called "WebSphere MQ Programmable Command Formats and Administration Interface"
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>
#include "packet-mq.h"
static int proto_mqpcf = -1;
static int hf_mqpcf_cfh_type = -1;
static int hf_mqpcf_cfh_length = -1;
static int hf_mqpcf_cfh_version = -1;
static int hf_mqpcf_cfh_command = -1;
static int hf_mqpcf_cfh_msgseqnumber = -1;
static int hf_mqpcf_cfh_control = -1;
static int hf_mqpcf_cfh_compcode = -1;
static int hf_mqpcf_cfh_reason = -1;
static int hf_mqpcf_cfh_paramcount = -1;
static gint ett_mqpcf = -1;
static gint ett_mqpcf_cfh = -1;
#define MQ_FMT_ADMIN "MQADMIN "
#define MQ_FMT_EVENT "MQEVENT "
#define MQ_FMT_PCF "MQPCF "
#define MQ_ENC_INTEGER_NORMAL 0x00000001
#define MQ_ENC_INTEGER_REVERSED 0x00000002
#define MQ_CMD_NONE 0
#define MQ_CMD_CHANGE_Q_MGR 1
#define MQ_CMD_INQUIRE_Q_MGR 2
#define MQ_CMD_CHANGE_PROCESS 3
#define MQ_CMD_COPY_PROCESS 4
#define MQ_CMD_CREATE_PROCESS 5
#define MQ_CMD_DELETE_PROCESS 6
#define MQ_CMD_INQUIRE_PROCESS 7
#define MQ_CMD_CHANGE_Q 8
#define MQ_CMD_CLEAR_Q 9
#define MQ_CMD_COPY_Q 10
#define MQ_CMD_CREATE_Q 11
#define MQ_CMD_DELETE_Q 12
#define MQ_CMD_INQUIRE_Q 13
#define MQ_CMD_RESET_Q_STATS 17
#define MQ_CMD_INQUIRE_Q_NAMES 18
#define MQ_CMD_INQUIRE_PROCESS_NAMES 19
#define MQ_CMD_INQUIRE_CHANNEL_NAMES 20
#define MQ_CMD_CHANGE_CHANNEL 21
#define MQ_CMD_COPY_CHANNEL 22
#define MQ_CMD_CREATE_CHANNEL 23
#define MQ_CMD_DELETE_CHANNEL 24
#define MQ_CMD_INQUIRE_CHANNEL 25
#define MQ_CMD_PING_CHANNEL 26
#define MQ_CMD_RESET_CHANNEL 27
#define MQ_CMD_START_CHANNEL 28
#define MQ_CMD_STOP_CHANNEL 29
#define MQ_CMD_START_CHANNEL_INIT 30
#define MQ_CMD_START_CHANNEL_LISTENER 31
#define MQ_CMD_CHANGE_NAMELIST 32
#define MQ_CMD_COPY_NAMELIST 33
#define MQ_CMD_CREATE_NAMELIST 34
#define MQ_CMD_DELETE_NAMELIST 35
#define MQ_CMD_INQUIRE_NAMELIST 36
#define MQ_CMD_INQUIRE_NAMELIST_NAMES 37
#define MQ_CMD_ESCAPE 38
#define MQ_CMD_RESOLVE_CHANNEL 39
#define MQ_CMD_PING_Q_MGR 40
#define MQ_CMD_INQUIRE_Q_STATUS 41
#define MQ_CMD_INQUIRE_CHANNEL_STATUS 42
#define MQ_CMD_CONFIG_EVENT 43
#define MQ_CMD_Q_MGR_EVENT 44
#define MQ_CMD_PERFM_EVENT 45
#define MQ_CMD_CHANNEL_EVENT 46
#define MQ_CMD_DELETE_PUBLICATION 60
#define MQ_CMD_DEREGISTER_PUBLISHER 61
#define MQ_CMD_DEREGISTER_SUBSCRIBER 62
#define MQ_CMD_PUBLISH 63
#define MQ_CMD_REGISTER_PUBLISHER 64
#define MQ_CMD_REGISTER_SUBSCRIBER 65
#define MQ_CMD_REQUEST_UPDATE 66
#define MQ_CMD_BROKER_INTERNAL 67
#define MQ_CMD_INQUIRE_CLUSTER_Q_MGR 70
#define MQ_CMD_RESUME_Q_MGR_CLUSTER 71
#define MQ_CMD_SUSPEND_Q_MGR_CLUSTER 72
#define MQ_CMD_REFRESH_CLUSTER 73
#define MQ_CMD_RESET_CLUSTER 74
#define MQ_CMD_REFRESH_SECURITY 78
#define MQ_CMD_CHANGE_AUTH_INFO 79
#define MQ_CMD_COPY_AUTH_INFO 80
#define MQ_CMD_CREATE_AUTH_INFO 81
#define MQ_CMD_DELETE_AUTH_INFO 82
#define MQ_CMD_INQUIRE_AUTH_INFO 83
#define MQ_CMD_INQUIRE_AUTH_INFO_NAMES 84
#define MQ_TEXT_CFH "MQ Command Format Header"
static const value_string mqpcf_opcode_vals[] = {
{ MQ_CMD_NONE, "NONE" },
{ MQ_CMD_CHANGE_Q_MGR, "CHANGE_Q_MGR" },
{ MQ_CMD_INQUIRE_Q_MGR, "INQUIRE_Q_MGR" },
{ MQ_CMD_CHANGE_PROCESS, "CHANGE_PROCESS" },
{ MQ_CMD_COPY_PROCESS, "COPY_PROCESS" },
{ MQ_CMD_CREATE_PROCESS, "CREATE_PROCESS" },
{ MQ_CMD_DELETE_PROCESS, "DELETE_PROCESS" },
{ MQ_CMD_INQUIRE_PROCESS, "INQUIRE_PROCESS" },
{ MQ_CMD_CHANGE_Q, "CHANGE_Q" },
{ MQ_CMD_CLEAR_Q, "CLEAR_Q" },
{ MQ_CMD_COPY_Q, "COPY_Q" },
{ MQ_CMD_CREATE_Q, "CREATE_Q" },
{ MQ_CMD_DELETE_Q, "DELETE_Q" },
{ MQ_CMD_INQUIRE_Q, "INQUIRE_Q" },
{ MQ_CMD_RESET_Q_STATS, "RESET_Q_STATS" },
{ MQ_CMD_INQUIRE_Q_NAMES, "INQUIRE_Q_NAMES" },
{ MQ_CMD_INQUIRE_PROCESS_NAMES, "INQUIRE_PROCESS_NAMES" },
{ MQ_CMD_INQUIRE_CHANNEL_NAMES, "INQUIRE_CHANNEL_NAMES" },
{ MQ_CMD_CHANGE_CHANNEL, "CHANGE_CHANNEL" },
{ MQ_CMD_COPY_CHANNEL, "COPY_CHANNEL" },
{ MQ_CMD_CREATE_CHANNEL, "CREATE_CHANNEL" },
{ MQ_CMD_DELETE_CHANNEL, "DELETE_CHANNEL" },
{ MQ_CMD_INQUIRE_CHANNEL, "INQUIRE_CHANNEL" },
{ MQ_CMD_PING_CHANNEL, "PING_CHANNEL" },
{ MQ_CMD_RESET_CHANNEL, "RESET_CHANNEL" },
{ MQ_CMD_START_CHANNEL, "START_CHANNEL" },
{ MQ_CMD_STOP_CHANNEL, "STOP_CHANNEL" },
{ MQ_CMD_START_CHANNEL_INIT, "START_CHANNEL_INIT" },
{ MQ_CMD_START_CHANNEL_LISTENER, "START_CHANNEL_LISTENER" },
{ MQ_CMD_CHANGE_NAMELIST, "CHANGE_NAMELIST" },
{ MQ_CMD_CREATE_NAMELIST, "CREATE_NAMELIST" },
{ MQ_CMD_DELETE_NAMELIST, "DELETE_NAMELIST" },
{ MQ_CMD_INQUIRE_NAMELIST, "INQUIRE_NAMELIST" },
{ MQ_CMD_INQUIRE_NAMELIST_NAMES, "INQUIRE_NAMELIST_NAMES" },
{ MQ_CMD_ESCAPE, "ESCAPE" },
{ MQ_CMD_RESOLVE_CHANNEL, "RESOLVE_CHANNEL" },
{ MQ_CMD_PING_Q_MGR, "PING_Q_MGR" },
{ MQ_CMD_INQUIRE_Q_STATUS, "INQUIRE_Q_STATUS" },
{ MQ_CMD_INQUIRE_CHANNEL_STATUS, "INQUIRE_CHANNEL_STATUS" },
{ MQ_CMD_CONFIG_EVENT, "CONFIG_EVENT" },
{ MQ_CMD_Q_MGR_EVENT, "Q_MGR_EVENT" },
{ MQ_CMD_PERFM_EVENT, "PERFM_EVENT" },
{ MQ_CMD_CHANNEL_EVENT, "CHANNEL_EVENT" },
{ MQ_CMD_DELETE_PUBLICATION, "DELETE_PUBLICATION" },
{ MQ_CMD_DEREGISTER_PUBLISHER, "DEREGISTER_PUBLISHER" },
{ MQ_CMD_DEREGISTER_SUBSCRIBER, "DEREGISTER_SUBSCRIBER" },
{ MQ_CMD_PUBLISH, "PUBLISH" },
{ MQ_CMD_REGISTER_PUBLISHER, "REGISTER_PUBLISHER" },
{ MQ_CMD_REGISTER_SUBSCRIBER, "REGISTER_SUBSCRIBER" },
{ MQ_CMD_REQUEST_UPDATE, "REQUEST_UPDATE" },
{ MQ_CMD_BROKER_INTERNAL, "BROKER_INTERNAL" },
{ MQ_CMD_INQUIRE_CLUSTER_Q_MGR, "INQUIRE_CLUSTER_Q_MGR" },
{ MQ_CMD_RESUME_Q_MGR_CLUSTER, "RESUME_Q_MGR_CLUSTER" },
{ MQ_CMD_SUSPEND_Q_MGR_CLUSTER, "SUSPEND_Q_MGR_CLUSTER" },
{ MQ_CMD_REFRESH_CLUSTER, "REFRESH_CLUSTER" },
{ MQ_CMD_REFRESH_SECURITY, "REFRESH_SECURITY" },
{ MQ_CMD_CHANGE_AUTH_INFO, "CHANGE_AUTH_INFO" },
{ MQ_CMD_COPY_AUTH_INFO, "COPY_AUTH_INFO" },
{ MQ_CMD_CREATE_AUTH_INFO, "CREATE_AUTH_INFO" },
{ MQ_CMD_DELETE_AUTH_INFO, "DELETE_AUTH_INFO" },
{ MQ_CMD_INQUIRE_AUTH_INFO, "INQUIRE_AUTH_INFO" },
{ MQ_CMD_INQUIRE_AUTH_INFO_NAMES, "INQUIRE_AUTH_INFO_NAMES" },
{ 0, NULL }
};
static guint32 tvb_get_guint32_endian(tvbuff_t *a_tvb, gint a_iOffset, gboolean a_bLittleEndian)
{
guint32 iResult;
if (a_bLittleEndian)
iResult = tvb_get_letohl(a_tvb, a_iOffset);
else
iResult = tvb_get_ntohl(a_tvb, a_iOffset);
return iResult;
}
static void
dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *mq_tree = NULL;
proto_tree *mqroot_tree = NULL;
proto_item *ti = NULL;
gint offset = 0;
struct mqinfo* mqinfo = pinfo->private_data;
gboolean bLittleEndian;
bLittleEndian = ((mqinfo->encoding & MQ_ENC_INTEGER_REVERSED) != 0) ? TRUE : FALSE;
if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQ PCF");
if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO);
if (tvb_length(tvb) >= 36)
{
gint iSizeMQCFH = 36;
guint32 iCommand = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(iCommand, mqpcf_opcode_vals, "Unknown (0x%02x)"));
}
if (tree)
{
ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, FALSE);
proto_item_append_text(ti, " (%s)", val_to_str(iCommand, mqpcf_opcode_vals, "Unknown (0x%02x)"));
mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);
ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMQCFH, MQ_TEXT_CFH);
mq_tree = proto_item_add_subtree(ti, ett_mqpcf_cfh);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type, tvb, offset + 0, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length, tvb, offset + 4, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version, tvb, offset + 8, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command, tvb, offset + 12, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_msgseqnumber, tvb, offset + 16, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control, tvb, offset + 20, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode, tvb, offset + 24, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason, tvb, offset + 28, 4, bLittleEndian);
proto_tree_add_item(mq_tree, hf_mqpcf_cfh_paramcount, tvb, offset + 32, 4, bLittleEndian);
}
offset += iSizeMQCFH;
}
}
static gboolean
dissect_mqpcf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
if (tvb_length(tvb) >= 36)
{
struct mqinfo* mqinfo = pinfo->private_data;
if (strncmp((const char*)mqinfo->format, MQ_FMT_ADMIN, 8) == 0
|| strncmp((const char*)mqinfo->format, MQ_FMT_EVENT, 8) == 0
|| strncmp((const char*)mqinfo->format, MQ_FMT_PCF, 8) == 0)
{
/* Dissect the packet */
dissect_mqpcf(tvb, pinfo, tree);
return TRUE;
}
}
return FALSE;
}
void
proto_register_mqpcf(void)
{
static hf_register_info hf[] = {
{ &hf_mqpcf_cfh_type,
{ "Type", "mqpcf.cfh.type", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH type", HFILL }},
{ &hf_mqpcf_cfh_length,
{ "Length", "mqpcf.cfh.length", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH length", HFILL }},
{ &hf_mqpcf_cfh_version,
{ "Version", "mqpcf.cfh.version", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH version", HFILL }},
{ &hf_mqpcf_cfh_command,
{ "Command", "mqpcf.cfh.command", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH command", HFILL }},
{ &hf_mqpcf_cfh_msgseqnumber,
{ "Message sequence number", "mqpcf.cfh.msgseqnumber", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH message sequence number", HFILL }},
{ &hf_mqpcf_cfh_control,
{ "Control", "mqpcf.cfh.control", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH control", HFILL }},
{ &hf_mqpcf_cfh_compcode,
{ "Completion code", "mqpcf.cfh.compcode", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH completion code", HFILL }},
{ &hf_mqpcf_cfh_reason,
{ "Reason code", "mqpcf.cfh.reasoncode", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH reason code", HFILL }},
{ &hf_mqpcf_cfh_paramcount,
{ "Parameter count", "mqpcf.cfh.paramcount", FT_UINT32, BASE_DEC, NULL, 0x0, "CFH parameter count", HFILL }}
};
static gint *ett[] = {
&ett_mqpcf,
&ett_mqpcf_cfh,
};
proto_mqpcf = proto_register_protocol("WebSphere MQ Programmable Command Formats", "MQ PCF", "mqpcf");
proto_register_field_array(proto_mqpcf, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_mqpcf(void)
{
heur_dissector_add("mq", dissect_mqpcf_heur, proto_mqpcf);
}
|