Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-sapenqueue.c
Line
Count
Source
1
/* packet-sapenqueue.c
2
 * Routines for SAP Enqueue (Enqueue Server) dissection
3
 * Copyright 2022, Martin Gallo <martin.gallo [AT] gmail.com>
4
 * Code contributed by SecureAuth Corp.
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*
14
 * This is a dissector for the SAP Enqueue Server protocol.
15
 *
16
 * Some details and example requests can be found in pysap's documentation: https://pysap.readthedocs.io/en/latest/protocols/SAPEnqueue.html.
17
 */
18
19
#include <config.h>
20
21
#include <epan/packet.h>
22
#include <epan/prefs.h>
23
#include <epan/expert.h>
24
#include <epan/conversation.h>
25
26
27
/* Enqueue Server Type values */
28
static const value_string sapenqueue_type_vals[] = {
29
  {  0, "SYNC_REQUEST" },
30
  {  1, "ASYNC_REQUEST" },
31
  {  2, "RESPONSE" },
32
  /* NULL */
33
  {  0, NULL }
34
};
35
36
37
/* Enqueue Server Destination values */
38
static const value_string sapenqueue_dest_vals[] = {
39
  {  1, "SYNC_ENQUEUE" },
40
  {  2, "ASYNC_ENQUEUE" },
41
  {  3, "SERVER_ADMIN" },
42
  {  5, "STAT_QUERY" },
43
  {  6, "CONNECTION_ADMIN" },
44
  {  7, "ENQ_TO_REP" },
45
  {  8, "REP_TO_ENQ" },
46
  /* NULL */
47
  {  0, NULL },
48
};
49
50
51
/* Enqueue Server Admin Opcode values */
52
static const value_string sapenqueue_server_admin_opcode_vals[] = {
53
  {  1, "EnAdmDummyRequest" },
54
  {  2, "EnAdmShutdownRequest" },
55
  {  4, "EnAdmGetReplInfoRequest" },
56
  {  6, "EnAdmTraceRequest" },
57
  /* NULL */
58
  {  0, NULL },
59
};
60
61
/* Enqueue Server Connection Admin Trace Action values */
62
static const value_string sapenqueue_server_admin_trace_action_vals[] = {
63
  {  1, "Raise level" },
64
  {  2, "Lower level" },
65
  {  3, "Get trace state" },
66
  {  4, "Set trace status" },
67
  {  5, "Reset trace files" },
68
  /* NULL */
69
  {  0, NULL }
70
};
71
72
/* Enqueue Server Connection Admin Trace Limit values */
73
static const value_string sapenqueue_server_admin_trace_limit_vals[] = {
74
  {  0, "Globally" },
75
  {  1, "Only in enserver" },
76
  {  2, "Only in repserver" },
77
  {  3, "Only in threads of type" },
78
  {  4, "Only in one thread of type" },
79
  /* NULL */
80
  {  0, NULL }
81
};
82
83
/* Enqueue Server Connection Admin Trace Thread values */
84
static const value_string sapenqueue_server_admin_trace_thread_vals[] = {
85
  {  0, "All threads" },
86
  {  1, "All I/O threads" },
87
  {  2, "Enqueue Worker thread" },
88
  {  3, "Replication thread" },
89
  {  4, "ADM thread" },
90
  {  5, "Signal thread" },
91
  {  6, "Listener thread" },
92
  /* NULL */
93
  {  0, NULL }
94
};
95
96
/* Enqueue Server Connection Admin Opcode values */
97
static const value_string sapenqueue_conn_admin_opcode_vals[] = {
98
  {  0, "Loopback packet" },
99
  {  1, "Parameter Request" },
100
  {  2, "Parameter Response" },
101
  {  3, "Shutdown Read" },
102
  {  4, "Shutdown Write" },
103
  {  5, "Shutdown Both" },
104
  {  6, "Keepalive" },
105
  /* NULL */
106
  {  0, NULL }
107
};
108
109
/* Enqueue Server Connection Admin Parameter values */
110
static const value_string sapenqueue_conn_admin_param_vals[] = {
111
  {  0, "ENCPARAM_RECV_LEN" },
112
  {  1, "ENCPARAM_SEND_LEN" },
113
  {  2, "ENCPARAM_MSG_TYPE" },
114
  {  3, "ENCPARAM_SET_NAME" },
115
  {  4, "ENCPARAM_SET_NOSUPP" },
116
  {  5, "ENCPARAM_SET_VERSION" },
117
  {  6, "ENCPARAM_SET_UCSUPPORT" },
118
  /* NULL */
119
  {  0, NULL }
120
};
121
122
static int proto_sapenqueue;
123
124
static int hf_sapenqueue_magic;
125
static int hf_sapenqueue_id;
126
static int hf_sapenqueue_length;
127
static int hf_sapenqueue_length_frag;
128
static int hf_sapenqueue_dest;
129
static int hf_sapenqueue_conn_admin_opcode;
130
static int hf_sapenqueue_more_frags;
131
static int hf_sapenqueue_type;
132
133
static int hf_sapenqueue_server_admin;
134
static int hf_sapenqueue_server_admin_eyecatcher;
135
static int hf_sapenqueue_server_admin_version;
136
static int hf_sapenqueue_server_admin_flag;
137
static int hf_sapenqueue_server_admin_length;
138
static int hf_sapenqueue_server_admin_opcode;
139
static int hf_sapenqueue_server_admin_flags;
140
static int hf_sapenqueue_server_admin_rc;
141
static int hf_sapenqueue_server_admin_value;
142
143
static int hf_sapenqueue_server_admin_trace_request;
144
static int hf_sapenqueue_server_admin_trace_protocol_version;
145
static int hf_sapenqueue_server_admin_trace_action;
146
static int hf_sapenqueue_server_admin_trace_limit;
147
static int hf_sapenqueue_server_admin_trace_thread;
148
static int hf_sapenqueue_server_admin_trace_level;
149
static int hf_sapenqueue_server_admin_trace_logging;
150
static int hf_sapenqueue_server_admin_trace_max_file_size;
151
static int hf_sapenqueue_server_admin_trace_nopatterns;
152
static int hf_sapenqueue_server_admin_trace_eyecatcher;
153
static int hf_sapenqueue_server_admin_trace_patterns;
154
static int hf_sapenqueue_server_admin_trace_unknown;
155
156
static int hf_sapenqueue_server_admin_trace_pattern;
157
static int hf_sapenqueue_server_admin_trace_pattern_len;
158
static int hf_sapenqueue_server_admin_trace_pattern_value;
159
160
static int hf_sapenqueue_conn_admin;
161
static int hf_sapenqueue_conn_admin_params_count;
162
static int hf_sapenqueue_conn_admin_params;
163
static int hf_sapenqueue_conn_admin_param;
164
static int hf_sapenqueue_conn_admin_param_id;
165
static int hf_sapenqueue_conn_admin_param_len;
166
static int hf_sapenqueue_conn_admin_param_value;
167
static int hf_sapenqueue_conn_admin_param_name;
168
169
static int ett_sapenqueue;
170
171
/* Expert info */
172
static expert_field ei_sapenqueue_pattern_invalid_length;
173
static expert_field ei_sapenqueue_support_invalid_offset;
174
static expert_field ei_sapenqueue_support_invalid_length;
175
176
/* Protocol handle */
177
static dissector_handle_t sapenqueue_handle;
178
179
180
/*
181
 *
182
 */
183
void proto_reg_handoff_sapenqueue(void);
184
void proto_register_sapenqueue(void);
185
186
187
static void
188
0
dissect_sapenqueue_server_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset){
189
0
  uint8_t opcode = 0;
190
0
  proto_item *server_admin = NULL;
191
0
  proto_tree *server_admin_tree = NULL;
192
193
0
  server_admin = proto_tree_add_item(tree, hf_sapenqueue_server_admin, tvb, offset, -1, ENC_NA);
194
0
  server_admin_tree = proto_item_add_subtree(server_admin, ett_sapenqueue);
195
196
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, ENC_ASCII);
197
0
  offset += 4;
198
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_version, tvb, offset, 1, ENC_BIG_ENDIAN);
199
0
  offset += 1;
200
0
  offset += 3;  /* Unknown bytes */
201
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, ENC_ASCII);
202
0
  offset += 4;
203
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
204
0
  offset += 1;
205
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_length, tvb, offset, 4, ENC_BIG_ENDIAN);
206
0
  offset += 4;
207
0
  opcode = tvb_get_uint8(tvb, offset);
208
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
209
0
  offset += 1;
210
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
211
0
  offset += 1;
212
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_rc, tvb, offset, 4, ENC_BIG_ENDIAN);
213
0
  offset += 4;
214
0
  proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, ENC_ASCII);
215
0
  offset += 4;
216
217
0
  if (tvb_reported_length_remaining(tvb, offset) > 0){
218
0
    switch(opcode){
219
0
      case 0x06:{   /* EnAdmTraceRequest */
220
0
        uint8_t pattern_length = 0;
221
0
        uint32_t nopatterns = 0, total_length = 0;
222
0
        proto_item *trace_request = NULL, *trace_request_patterns = NULL, *trace_request_pattern = NULL;
223
0
        proto_tree *trace_request_tree = NULL, *trace_request_patterns_tree = NULL, *trace_request_pattern_tree = NULL;
224
225
0
        trace_request = proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_trace_request, tvb, offset, -1, ENC_NA);
226
0
        trace_request_tree = proto_item_add_subtree(trace_request, ett_sapenqueue);
227
228
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_protocol_version, tvb, offset, 1, ENC_BIG_ENDIAN);
229
0
        offset += 1;
230
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_action, tvb, offset, 1, ENC_BIG_ENDIAN);
231
0
        offset += 1;
232
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_limit, tvb, offset, 1, ENC_BIG_ENDIAN);
233
0
        offset += 1;
234
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_thread, tvb, offset, 1, ENC_BIG_ENDIAN);
235
0
        offset += 1;
236
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_unknown, tvb, offset, 4, ENC_NA);
237
0
        offset += 4;
238
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_level, tvb, offset, 4, ENC_BIG_ENDIAN);
239
0
        offset += 4;
240
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_unknown, tvb, offset, 4, ENC_NA);
241
0
        offset += 4;
242
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_logging, tvb, offset, 1, ENC_BIG_ENDIAN);
243
0
        offset += 1;
244
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_max_file_size, tvb, offset, 4, ENC_BIG_ENDIAN);
245
0
        offset += 4;
246
247
0
        nopatterns = tvb_get_ntohl(tvb, offset);
248
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_nopatterns, tvb, offset, 4, ENC_BIG_ENDIAN);
249
0
        offset += 4;
250
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_unknown, tvb, offset, 8, ENC_NA);
251
0
        offset += 8;
252
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_eyecatcher, tvb, offset, 4, ENC_ASCII);
253
0
        offset += 4;
254
255
        /* As we don't have the right size yet, start with 1 byte */
256
0
        trace_request_patterns = proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_patterns, tvb, offset, 1, ENC_NA);
257
0
        trace_request_patterns_tree = proto_item_add_subtree(trace_request_patterns, ett_sapenqueue);
258
259
0
        while (nopatterns > 0 && tvb_offset_exists(tvb, offset)){
260
          /* As we don't have the right size yet, start with 1 byte */
261
0
          trace_request_pattern = proto_tree_add_item(trace_request_patterns_tree, hf_sapenqueue_server_admin_trace_pattern, tvb, offset, 1, ENC_NA);
262
0
          trace_request_pattern_tree = proto_item_add_subtree(trace_request_pattern, ett_sapenqueue);
263
264
0
          pattern_length = tvb_get_uint8(tvb, offset) + 1; /* Pattern string is null terminated */
265
0
          proto_tree_add_item(trace_request_pattern_tree, hf_sapenqueue_server_admin_trace_pattern_len, tvb, offset, 1, ENC_BIG_ENDIAN);
266
0
          offset += 1;
267
268
          /* Set the max length to the remaining of the packet, just in case a malformed packet arrives */
269
0
          if (!tvb_offset_exists(tvb, offset + pattern_length)) {
270
0
            pattern_length = (uint8_t)tvb_reported_length_remaining(tvb, offset);
271
0
            expert_add_info(pinfo, trace_request_pattern, &ei_sapenqueue_pattern_invalid_length);
272
0
          }
273
0
          proto_tree_add_item(trace_request_pattern_tree, hf_sapenqueue_server_admin_trace_pattern_value, tvb, offset, pattern_length, ENC_ASCII);
274
0
          offset += pattern_length;
275
276
          /* Set the right size for the pattern tree */
277
0
          pattern_length += 1; /* Add also the length field */
278
0
          proto_item_set_len(trace_request_pattern, pattern_length);
279
280
0
          nopatterns -= 1;
281
0
          total_length += pattern_length;
282
0
        }
283
0
        proto_item_set_len(trace_request_patterns, total_length);
284
285
0
        proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_eyecatcher, tvb, offset, 4, ENC_ASCII);
286
0
        break;
287
0
      }
288
0
      default:{
289
0
        proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_value, tvb, offset, -1, ENC_NA);
290
0
        break;
291
0
      }
292
0
    }
293
0
  }
294
295
0
}
296
297
298
static void
299
0
dissect_sapenqueue_conn_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t opcode){
300
0
  proto_item *conn_admin = NULL;
301
0
  proto_tree *conn_admin_tree = NULL;
302
303
0
  conn_admin = proto_tree_add_item(tree, hf_sapenqueue_conn_admin, tvb, offset, -1, ENC_NA);
304
0
  conn_admin_tree = proto_item_add_subtree(conn_admin, ett_sapenqueue);
305
306
0
  switch (opcode){
307
0
    case 0x01:    /* Parameter Request */
308
0
    case 0x02:{   /* Parameter Response */
309
0
      int name_length_remaining = 0;
310
0
      uint8_t length = 0, total_length = 0;
311
0
      uint32_t count = 0, id = 0, name_length = 0;
312
0
      proto_item *params = NULL, *param = NULL;
313
0
      proto_tree *params_tree = NULL, *param_tree = NULL;
314
315
0
      count = tvb_get_ntohl(tvb, offset);
316
0
      proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params_count, tvb, offset, 4, ENC_BIG_ENDIAN);
317
0
      offset += 4;
318
319
0
      params = proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params, tvb, offset, 1, ENC_NA);
320
0
      params_tree = proto_item_add_subtree(params, ett_sapenqueue);
321
322
0
      while (count > 0 && tvb_offset_exists(tvb, offset)){
323
        /* As we don't have the right size yet, start with 1 byte */
324
0
        param = proto_tree_add_item(params_tree, hf_sapenqueue_conn_admin_param, tvb, offset, 1, ENC_NA);
325
0
        param_tree = proto_item_add_subtree(param, ett_sapenqueue);
326
327
0
        id = tvb_get_ntohl(tvb, offset);
328
0
        proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_id, tvb, offset, 4, ENC_BIG_ENDIAN);
329
0
        offset += 4;
330
0
        length = 4;
331
332
0
        switch(id){
333
0
          case 0x03:{ /* Set Name parameter */
334
0
            name_length = tvb_strsize(tvb, offset);
335
0
            if (name_length > 0) {
336
0
              proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_name, tvb, offset, name_length, ENC_ASCII);
337
0
              offset += name_length;
338
0
              length += name_length;
339
0
            }
340
0
            break;
341
342
0
          } case 0x04:{  /* No support parameter */
343
            /* This parameter appears to have more fields only for responses */
344
0
            if (opcode == 0x02) {
345
0
              proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, ENC_BIG_ENDIAN);
346
0
              offset += 4;
347
0
              length += 4;
348
0
            }
349
0
            break;
350
351
0
          } case 0x06:{  /* Set Unicode Support Parameter */
352
0
            name_length = tvb_get_ntohl(tvb, offset);
353
0
            proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_len, tvb, offset, 4, ENC_BIG_ENDIAN);
354
0
            offset += 4;
355
356
            /* If the reported length is not correct, use the remaining of the packet as length */
357
0
            name_length_remaining = tvb_reported_length_remaining(tvb, offset);
358
0
            if (name_length_remaining < 0){
359
0
              expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_offset);
360
0
              break;
361
0
            }
362
0
            if ((uint32_t)name_length_remaining < name_length) {
363
0
              name_length = (uint32_t)name_length_remaining;
364
0
              expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_length);
365
0
            }
366
367
0
            proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, name_length, ENC_BIG_ENDIAN);
368
0
            offset += name_length;
369
0
            length += 4 + name_length;
370
0
            break;
371
372
0
          } default: {
373
            /* The rest of the parameters have an integer value field */
374
0
            proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, ENC_BIG_ENDIAN);
375
0
            offset += 4;
376
0
            length += 4;
377
0
          }
378
0
        }
379
380
        /* Set the right size for the parameter tree */
381
0
        proto_item_set_len(param, length);
382
383
0
        count -= 1;
384
0
        total_length += length;
385
0
      }
386
387
0
      proto_item_set_len(params, total_length);
388
0
      break;
389
0
    }
390
0
  }
391
392
0
}
393
394
395
static int
396
dissect_sapenqueue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
397
0
{
398
0
  uint8_t dest = 0, type = 0, opcode = 0;
399
0
  uint32_t offset = 4;
400
0
  proto_item *ti = NULL;
401
0
  proto_tree *sapenqueue_tree = NULL;
402
403
  /* If the packet has less than 20 bytes we can be sure that is not an
404
   * Enqueue server packet.
405
   */
406
0
  if (tvb_reported_length(tvb) < 20){
407
0
    return 0;
408
0
  }
409
410
  /* Add the protocol to the column */
411
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SAPENQUEUE");
412
  /* Clear out stuff in the info column */
413
0
  col_clear(pinfo->cinfo,COL_INFO);
414
415
0
  dest = tvb_get_uint8(tvb, offset + 16);
416
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "Dest=%s", val_to_str_const(dest, sapenqueue_dest_vals, "Unknown"));
417
418
0
  opcode = tvb_get_uint8(tvb, offset + 17);
419
0
  type = tvb_get_uint8(tvb, offset + 19);
420
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ",Type=%s", val_to_str_const(type, sapenqueue_type_vals, "Unknown"));
421
422
0
  if (dest == 0x06){
423
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ",Opcode=%s", val_to_str_const(opcode, sapenqueue_conn_admin_opcode_vals, "Unknown"));
424
0
  }
425
426
  /* Add the main sapenqueue subtree */
427
0
  ti = proto_tree_add_item(tree, proto_sapenqueue, tvb, 0, -1, ENC_NA);
428
0
  sapenqueue_tree = proto_item_add_subtree(ti, ett_sapenqueue);
429
430
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_magic, tvb, offset, 4, ENC_NA);
431
0
  offset += 4;
432
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_id, tvb, offset, 4, ENC_BIG_ENDIAN);
433
0
  offset += 4;
434
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_length, tvb, offset, 4, ENC_BIG_ENDIAN);
435
0
  offset += 4;
436
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_length_frag, tvb, offset, 4, ENC_BIG_ENDIAN);
437
0
  offset += 4;
438
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_dest, tvb, offset, 1, ENC_BIG_ENDIAN);
439
0
  offset += 1;
440
0
  if (dest == 0x06){  /* This field is only relevant if the destination is Connection Admin */
441
0
    proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_conn_admin_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
442
0
  }
443
0
  offset += 1;
444
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_more_frags, tvb, offset, 1, ENC_BIG_ENDIAN);
445
0
  offset += 1;
446
0
  proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
447
0
  offset += 1;
448
449
0
  switch (dest){
450
0
    case 0x03:{   /* Server Admin */
451
0
      dissect_sapenqueue_server_admin(tvb, pinfo, sapenqueue_tree, offset);
452
0
      break;
453
0
    }
454
0
    case 0x06:{   /* Connection Admin */
455
0
      dissect_sapenqueue_conn_admin(tvb, pinfo, sapenqueue_tree, offset, opcode);
456
0
      break;
457
0
    }
458
0
  }
459
460
0
  return tvb_reported_length(tvb);
461
0
}
462
463
464
static bool
465
2.71k
dissect_sapenqueue_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_){
466
2.71k
  conversation_t *conversation = NULL;
467
468
  /* If the first 4 bytes are the magic bytes, we can guess that the
469
   * packet is a Enqueue server packet.
470
   */
471
2.71k
  if (tvb_get_ntohl(tvb, 0) != 0xabcde123){
472
2.55k
    return false;
473
2.55k
  }
474
475
  /* From now on this conversation is dissected as SAP Enqueue traffic */
476
161
  conversation = find_or_create_conversation(pinfo);
477
161
  conversation_set_dissector(conversation, sapenqueue_handle);
478
479
  /* Now dissect the packet */
480
161
  dissect_sapenqueue(tvb, pinfo, tree, data);
481
482
161
  return true;
483
2.71k
}
484
485
486
void
487
proto_register_sapenqueue(void)
488
14
{
489
14
  static hf_register_info hf[] = {
490
    /* General Header fields */
491
14
    { &hf_sapenqueue_magic,
492
14
      { "Magic Bytes", "sapenqueue.magic", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
493
14
    { &hf_sapenqueue_id,
494
14
      { "ID", "sapenqueue.id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
495
14
    { &hf_sapenqueue_length,
496
14
      { "Length", "sapenqueue.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
497
14
    { &hf_sapenqueue_length_frag,
498
14
      { "Fragment Length", "sapenqueue.fragment_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
499
14
    { &hf_sapenqueue_dest,
500
14
      { "Destination", "sapenqueue.destination", FT_UINT8, BASE_DEC, VALS(sapenqueue_dest_vals), 0x0, NULL, HFILL }},
501
14
    { &hf_sapenqueue_conn_admin_opcode,
502
14
      { "Opcode", "sapenqueue.opcode", FT_UINT8, BASE_DEC, VALS(sapenqueue_conn_admin_opcode_vals), 0x0, NULL, HFILL }},
503
14
    { &hf_sapenqueue_more_frags,
504
14
      { "More Fragments", "sapenqueue.more_frags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
505
14
    { &hf_sapenqueue_type,
506
14
      { "Type", "sapenqueue.type", FT_UINT8, BASE_DEC, VALS(sapenqueue_type_vals), 0x0, NULL, HFILL }},
507
508
    /* Server Admin fields */
509
14
    { &hf_sapenqueue_server_admin,
510
14
      { "Server Admin", "sapenqueue.server_admin", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
511
14
    { &hf_sapenqueue_server_admin_eyecatcher,
512
14
      { "Eye Catcher", "sapenqueue.server_admin.eyecatcher", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
513
14
    { &hf_sapenqueue_server_admin_version,
514
14
      { "Version", "sapenqueue.server_admin.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
515
14
    { &hf_sapenqueue_server_admin_flag,
516
14
      { "Flag", "sapenqueue.server_admin.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
517
14
    { &hf_sapenqueue_server_admin_length,
518
14
      { "Length", "sapenqueue.server_admin.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
519
14
    { &hf_sapenqueue_server_admin_opcode,
520
14
      { "Opcode", "sapenqueue.server_admin.opcode", FT_UINT8, BASE_DEC, VALS(sapenqueue_server_admin_opcode_vals), 0x0, NULL, HFILL }},
521
14
    { &hf_sapenqueue_server_admin_flags,
522
14
      { "Flags", "sapenqueue.server_admin.flags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
523
14
    { &hf_sapenqueue_server_admin_rc,
524
14
      { "Return Code", "sapenqueue.server_admin.rc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
525
14
    { &hf_sapenqueue_server_admin_value,
526
14
      { "Value", "sapenqueue.server_admin.value", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
527
528
    /* Trace Request fields */
529
14
    { &hf_sapenqueue_server_admin_trace_request,
530
14
      { "Trace Request", "sapenqueue.server_admin.trace", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
531
14
    { &hf_sapenqueue_server_admin_trace_protocol_version,
532
14
      { "Trace Protocol Version", "sapenqueue.server_admin.trace.protocol", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
533
14
    { &hf_sapenqueue_server_admin_trace_action,
534
14
      { "Trace Action", "sapenqueue.server_admin.trace.action", FT_UINT8, BASE_DEC, VALS(sapenqueue_server_admin_trace_action_vals), 0x0, NULL, HFILL }},
535
14
    { &hf_sapenqueue_server_admin_trace_limit,
536
14
      { "Trace Limit", "sapenqueue.server_admin.trace.limit", FT_UINT8, BASE_DEC, VALS(sapenqueue_server_admin_trace_limit_vals), 0x0, NULL, HFILL }},
537
14
    { &hf_sapenqueue_server_admin_trace_thread,
538
14
      { "Trace Thread", "sapenqueue.server_admin.trace.thread", FT_UINT8, BASE_DEC, VALS(sapenqueue_server_admin_trace_thread_vals), 0x0, NULL, HFILL }},
539
14
    { &hf_sapenqueue_server_admin_trace_level,
540
14
      { "Trace Level", "sapenqueue.server_admin.trace.level", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
541
14
    { &hf_sapenqueue_server_admin_trace_logging,
542
14
      { "Trace Logging", "sapenqueue.server_admin.trace.logging", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
543
14
    { &hf_sapenqueue_server_admin_trace_max_file_size,
544
14
      { "Trace Max File Size", "sapenqueue.server_admin.trace.max_file_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
545
14
    { &hf_sapenqueue_server_admin_trace_nopatterns,
546
14
      { "Trace No Patterns", "sapenqueue.server_admin.trace.nopatterns", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
547
14
    { &hf_sapenqueue_server_admin_trace_eyecatcher,
548
14
      { "Trace Eye Catcher", "sapenqueue.server_admin.trace.eyecatcher", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
549
14
    { &hf_sapenqueue_server_admin_trace_patterns,
550
14
      { "Trace Patterns", "sapenqueue.server_admin.trace.patterns", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
551
14
    { &hf_sapenqueue_server_admin_trace_unknown,
552
14
      { "Unknown field", "sapenqueue.server_admin.trace.unknown", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
553
554
    /* Trace Request Pattern fields */
555
14
    { &hf_sapenqueue_server_admin_trace_pattern,
556
14
      { "Trace Pattern", "sapenqueue.server_admin.trace.pattern", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
557
14
    { &hf_sapenqueue_server_admin_trace_pattern_len,
558
14
      { "Trace Pattern Length", "sapenqueue.server_admin.trace.pattern.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
559
14
    { &hf_sapenqueue_server_admin_trace_pattern_value,
560
14
      { "Trace Pattern Value", "sapenqueue.server_admin.trace.pattern.value", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
561
562
    /* Connection Admin fields */
563
14
    { &hf_sapenqueue_conn_admin,
564
14
      { "Connection Admin", "sapenqueue.conn_admin", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
565
14
    { &hf_sapenqueue_conn_admin_params_count,
566
14
      { "Parameters Count", "sapenqueue.conn_admin.params.count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
567
14
    { &hf_sapenqueue_conn_admin_params,
568
14
      { "Parameters", "sapenqueue.conn_admin.params", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
569
14
    { &hf_sapenqueue_conn_admin_param,
570
14
      { "Parameter", "sapenqueue.conn_admin.params.param", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
571
14
    { &hf_sapenqueue_conn_admin_param_id,
572
14
      { "Parameter ID", "sapenqueue.conn_admin.params.param.id", FT_UINT32, BASE_DEC, VALS(sapenqueue_conn_admin_param_vals), 0x0, NULL, HFILL }},
573
14
    { &hf_sapenqueue_conn_admin_param_len,
574
14
      { "Parameter Length", "sapenqueue.conn_admin.params.param.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
575
14
    { &hf_sapenqueue_conn_admin_param_value,
576
14
      { "Parameter Value", "sapenqueue.conn_admin.params.param.value", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
577
14
    { &hf_sapenqueue_conn_admin_param_name,
578
14
      { "Parameter Name", "sapenqueue.conn_admin.params.param.name", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
579
580
14
  };
581
582
  /* Setup protocol subtree array */
583
14
  static int *ett[] = {
584
14
    &ett_sapenqueue
585
14
  };
586
587
  /* Register the expert info */
588
14
  static ei_register_info ei[] = {
589
14
    { &ei_sapenqueue_pattern_invalid_length, { "sapenqueue.server_admin.trace.pattern.length.invalid", PI_MALFORMED, PI_WARN, "The reported length is incorrect", EXPFILL }},
590
14
    { &ei_sapenqueue_support_invalid_offset, { "sapenqueue.conn_admin.params.param.offset.invalid", PI_MALFORMED, PI_ERROR, "Invalid offset", EXPFILL }},
591
14
    { &ei_sapenqueue_support_invalid_length, { "sapenqueue.conn_admin.params.param.length.invalid", PI_MALFORMED, PI_WARN, "The reported length is incorrect", EXPFILL }},
592
14
  };
593
594
14
  expert_module_t* sapenqueue_expert;
595
596
  /* Register the protocol */
597
14
  proto_sapenqueue = proto_register_protocol("SAP Enqueue Protocol", "SAPENQUEUE", "sapenqueue");
598
599
14
  proto_register_field_array(proto_sapenqueue, hf, array_length(hf));
600
14
  proto_register_subtree_array(ett, array_length(ett));
601
602
14
  sapenqueue_expert = expert_register_protocol(proto_sapenqueue);
603
14
  expert_register_field_array(sapenqueue_expert, ei, array_length(ei));
604
605
14
  register_dissector("sapenqueue", dissect_sapenqueue, proto_sapenqueue);
606
607
14
}
608
609
610
void
611
proto_reg_handoff_sapenqueue(void)
612
14
{
613
14
  sapenqueue_handle = create_dissector_handle(dissect_sapenqueue, proto_sapenqueue);
614
615
  /* Register the heuristic dissector. We need to use a heuristic dissector
616
   * here as the Enqueue Server uses the same port number that the Dispatcher
617
   * Service (32NN/tcp). */
618
14
  heur_dissector_add("sapni", dissect_sapenqueue_heur, "SAP Enqueue Protocol", "sapenqueue", proto_sapenqueue, HEURISTIC_ENABLE);
619
14
}
620
621
/*
622
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
623
 *
624
 * Local variables:
625
 * c-basic-offset: 8
626
 * tab-width: 8
627
 * indent-tabs-mode: t
628
 * End:
629
 *
630
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
631
 * :indentSize=8:tabSize=8:noTabs=false:
632
 */