Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-pdc.c
Line
Count
Source
1
/* packet-pdc.c
2
 * Routines for PDC dissection
3
 * Copyright 2014, Antony Bridle <antony.bridle@nats.co.uk>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include "packet-tcp.h"
16
17
void proto_register_pdc(void);
18
void proto_reg_handoff_pdc(void);
19
20
/* PDC version */
21
#define PDC_VERSION 2
22
23
0
#define SIMPDU  1
24
0
#define RSMPDU  2
25
0
#define DRMPDU  3
26
0
#define DTMPDU  4
27
0
#define ADMPDU  5
28
0
#define EDMPDU  6
29
0
#define AKMPDU  8
30
31
/*Variable length Parameter Codes*/
32
0
#define PARAM_CODE_VERSION  2
33
0
#define PARAM_CODE_REFERENCES 3
34
0
#define PARAM_CODE_TRANSPORT  4
35
36
/* required for the TCP split packet combining */
37
#define PDC_MSG_SIZE_FIELD_LENGTH 2 /* minimum amount of data to find out how big the split packet should be when recombined */
38
#define FRAME_HEADER_LEN 8
39
40
/* global handle for our dissector */
41
static dissector_handle_t pdc_tcp_handle;
42
43
/* global handle for calling asterix decoder if required */
44
static dissector_handle_t asterix_handle;
45
46
static int      proto_pdc;
47
48
/*HF Declarations*/
49
static int hf_pdc_len;
50
static int hf_pdc_mpdu_code;
51
static int hf_pdc_credit;
52
static int hf_pdc_simpdu_state;
53
static int hf_pdc_yr_admu_nr;
54
static int hf_pdc_akmpdu_mns;
55
static int hf_pdc_akmpdu_cdt;
56
static int hf_pdc_simpdu_var;
57
static int hf_pdc_simpdu_var_len;
58
static int hf_pdc_simpdu_param;
59
static int hf_pdc_simpdu_var_version;
60
static int hf_pdc_simpdu_var_REFSRC;
61
static int hf_pdc_simpdu_var_REFDEST;
62
static int hf_pdc_simpdu_var_TSEL;
63
static int hf_pdc_drmpdu_abort;
64
static int hf_pdc_drmpdu_reason;
65
static int hf_pdc_drmpdu_mode;
66
static int hf_pdc_drmpdu_init;
67
static int hf_pdc_dtmpdu_user_size;
68
static int hf_pdc_admpdu_admpdunr;
69
static int hf_pdc_admpdu_size;
70
71
/*Tree Declarations*/
72
static int ett_pdc;
73
static int ett_pdc_simpdu_var;
74
75
76
/*Value String Declarations*/
77
static const value_string valstr_simpdu_state[] = {
78
  { 1, "Operational" },
79
  { 2, "Standby" },
80
  { 3, "Master" },
81
  { 4, "Slave" },
82
  { 5, "Single" },
83
  { 0, NULL }
84
};
85
86
static const value_string valstr_simpdu_param[] = {
87
  { 2, "Version Number" },
88
  { 3, "References" },
89
  { 4, "Transport Selector" },
90
  { 0, NULL }
91
};
92
93
static const value_string valstr_mpdus[] = {
94
  { 1, "State Information" },
95
  { 2, "Request State" },
96
  { 3, "Disconnect Request" },
97
  { 4, "Data" },
98
  { 5, "Acknowledged Data" },
99
  { 6, "Expedited Data" },
100
  { 8, "Data Acknowledgement" },
101
  { 0, NULL }
102
};
103
104
static const value_string valstr_drmpdu_abort[] = {
105
  { 0, "Orderly Release" },
106
  { 1, "Abortive Release" },
107
  { 0, NULL }
108
};
109
110
static const value_string valstr_drmpdu_mode[] = {
111
  { 0, "Node Shutdown" },
112
  { 7, "PDC Release"},
113
  { 0, NULL }
114
};
115
116
static const value_string valstr_drmpdu_initatior[] = {
117
  { 0, "Server" },
118
  { 15, "Client"},
119
  { 0, NULL }
120
};
121
122
static const value_string valstr_drmpdu_reason[] = {
123
  { 0, "Reason Not Specified" },
124
  { 1, "Normal Disconnect Initiated by the MS-User" },
125
  { 2, "Protocol Error" },
126
  { 3, "Connection Request Refused" },
127
  { 4, "The Remote Operational MS Entity Does Not Respond" },
128
  { 5, "The Protocol Version Is Not Supported" },
129
  { 6, "Mismatched References" },
130
  { 0, NULL }
131
};
132
133
/* start of functions here */
134
static int dissect_simpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset, uint8_t lenIndicator)
135
0
{
136
0
  int     bytesProcessed;
137
0
  uint8_t     paramCode;
138
0
  proto_item *simpduItem;
139
0
  proto_tree *simpduVarTree;
140
0
  proto_tree *simpduVarTree1;
141
142
0
  bytesProcessed = 0;
143
144
  /*Add the Credit allocation*/
145
0
  proto_tree_add_item(tree, hf_pdc_credit, tvb, offset, 1, ENC_BIG_ENDIAN);
146
0
  bytesProcessed += 1;
147
148
  /*Add the State*/
149
0
  proto_tree_add_item(tree, hf_pdc_simpdu_state, tvb, offset + bytesProcessed , 1, ENC_BIG_ENDIAN);
150
0
  bytesProcessed += 1;
151
152
  /*Add the YR-ADMU-NR*/
153
0
  proto_tree_add_item(tree, hf_pdc_yr_admu_nr, tvb, offset + bytesProcessed , 4, ENC_BIG_ENDIAN);
154
0
  bytesProcessed += 4;
155
156
  /*Determine what's in the variable part*/
157
0
  if (lenIndicator > 7)
158
0
  {
159
    /*Add the Variable Length Tree*/
160
0
    simpduItem = proto_tree_add_item (tree, hf_pdc_simpdu_var, tvb, offset + bytesProcessed, lenIndicator - 7, ENC_NA);
161
0
    simpduVarTree = proto_item_add_subtree (simpduItem, ett_pdc_simpdu_var);
162
163
0
    while ((offset + bytesProcessed) < ( lenIndicator + 1 ))
164
0
    {
165
      /*Get the parameter code*/
166
0
      paramCode  = tvb_get_uint8(tvb, offset + bytesProcessed);
167
0
      simpduItem = proto_tree_add_item (simpduVarTree, hf_pdc_simpdu_param, tvb, offset + bytesProcessed,      1, ENC_BIG_ENDIAN);
168
0
      simpduVarTree1 = proto_item_add_subtree (simpduItem, ett_pdc_simpdu_var);
169
0
      bytesProcessed += 1;
170
0
      switch (paramCode)
171
0
      {
172
0
      case PARAM_CODE_VERSION:
173
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len,     tvb, offset + bytesProcessed,     1, ENC_BIG_ENDIAN);
174
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_version, tvb, offset + bytesProcessed + 1, 1, ENC_BIG_ENDIAN);
175
0
        bytesProcessed += 2;
176
0
        break;
177
0
      case PARAM_CODE_REFERENCES:
178
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len,     tvb, offset + bytesProcessed,     1, ENC_BIG_ENDIAN);
179
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_REFSRC,  tvb, offset + bytesProcessed + 1, 2, ENC_BIG_ENDIAN);
180
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_REFDEST, tvb, offset + bytesProcessed + 3, 2, ENC_BIG_ENDIAN);
181
0
        bytesProcessed += 5;
182
0
        break;
183
0
      case PARAM_CODE_TRANSPORT:
184
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len,     tvb, offset + bytesProcessed,     1, ENC_BIG_ENDIAN);
185
0
        proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_TSEL,    tvb, offset + bytesProcessed + 1, 2, ENC_BIG_ENDIAN);
186
0
        bytesProcessed += 3;
187
0
        break;
188
0
      }
189
0
    } /* end of whileloop */
190
0
  }
191
0
  return (bytesProcessed);
192
0
}
193
194
static int dissect_rsmpdu(void)
195
0
{
196
0
  return 0;
197
0
}
198
199
static int dissect_drmpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset)
200
0
{
201
  /*DR-MPDU*/
202
0
  proto_tree_add_item(tree, hf_pdc_drmpdu_abort,  tvb, offset,     1, ENC_BIG_ENDIAN);
203
0
  proto_tree_add_item(tree, hf_pdc_drmpdu_mode,   tvb, offset,     1, ENC_BIG_ENDIAN);
204
0
  proto_tree_add_item(tree, hf_pdc_drmpdu_init,   tvb, offset,     1, ENC_BIG_ENDIAN);
205
0
  proto_tree_add_item(tree, hf_pdc_drmpdu_reason, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
206
207
0
  return 2;
208
0
}
209
210
#if (PDC_VERSION == 2)
211
static int dissect_admpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo)
212
0
{
213
0
  uint16_t    userDataLen;
214
0
  uint16_t    returnLen;
215
0
  tvbuff_t *asterixTVB;
216
217
  /*Add the ad*/
218
0
  proto_tree_add_item(tree, hf_pdc_admpdu_admpdunr, tvb, offset, 4, ENC_BIG_ENDIAN);
219
0
  offset += 4;
220
221
0
  proto_tree_add_item(tree, hf_pdc_admpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN);
222
  /* length of user data field */
223
0
  userDataLen = tvb_get_ntohs(tvb, offset);
224
0
  offset += 2;
225
226
0
  returnLen = userDataLen + 6;
227
0
  asterixTVB = tvb_new_subset_length(tvb, offset, userDataLen);
228
229
0
  if (asterix_handle != NULL)
230
0
    call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree);
231
232
0
  return (returnLen);
233
0
}
234
#else
235
static int dissect_admpdu(tvbuff_t *tvb, proto_tree *parent_tree _U_, proto_tree *tree, uint16_t offset, packet_info *pinfo _U_)
236
{
237
  /*Add the ad*/
238
  proto_tree_add_item(tree, hf_pdc_admpdu_admpdunr, tvb, offset, 4, ENC_BIG_ENDIAN);
239
240
  return 2;
241
}
242
#endif
243
244
#if (PDC_VERSION == 2)
245
static int dissect_dtmpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo)
246
0
{
247
0
  uint16_t    userDataLen;
248
0
  uint16_t    returnLen;
249
0
  tvbuff_t *asterixTVB;
250
251
0
  proto_tree_add_item(tree, hf_pdc_dtmpdu_user_size, tvb, offset, 2, ENC_BIG_ENDIAN);
252
  /* length of user data field */
253
0
  userDataLen = tvb_get_ntohs(tvb, 2);
254
0
  returnLen  = userDataLen + 2;
255
0
  asterixTVB = tvb_new_subset_length(tvb, offset + 2, userDataLen);
256
257
0
  if (asterix_handle != NULL)
258
0
    call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree);
259
260
0
  return (returnLen);
261
0
}
262
#else
263
static int dissect_dtmpdu(tvbuff_t *tvb _U_, proto_tree *parent_tree _U_, proto_tree *tree _U_, uint16_t offset _U_, packet_info *pinfo _U_)
264
{
265
  return 2;
266
}
267
#endif
268
269
270
#if (PDC_VERSION == 2)
271
static int dissect_edmpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo)
272
0
{
273
0
  uint16_t    userDataLen;
274
0
  uint16_t    returnLen;
275
0
  tvbuff_t *asterixTVB;
276
277
0
  proto_tree_add_item(tree, hf_pdc_dtmpdu_user_size, tvb, offset, 2, ENC_BIG_ENDIAN);
278
  /* length of user data field */
279
0
  userDataLen = tvb_get_ntohs(tvb, 2);
280
0
  returnLen   = userDataLen + 2;
281
0
  asterixTVB  = tvb_new_subset_length(tvb, offset + 2, userDataLen);
282
283
0
  if (asterix_handle != NULL)
284
0
    call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree);
285
286
0
  return (returnLen);
287
0
}
288
#else
289
static int dissect_edmpdu(tvbuff_t *tvb _U_, proto_tree *parent_tree _U_, proto_tree *tree _U_, uint16_t offset _U_, packet_info *pinfo _U_)
290
{
291
  return 2;
292
}
293
#endif
294
295
static int dissect_akmpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset)
296
0
{
297
0
  proto_tree_add_item(tree, hf_pdc_akmpdu_mns, tvb, offset,     2, ENC_BIG_ENDIAN);
298
0
  proto_tree_add_item(tree, hf_pdc_akmpdu_cdt, tvb, offset,     2, ENC_BIG_ENDIAN);
299
0
  proto_tree_add_item(tree, hf_pdc_yr_admu_nr, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
300
0
  return (6);
301
0
}
302
303
static int dissect_pdc_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo)
304
0
{
305
0
  unsigned      i = 0;
306
0
  uint8_t     len_indicator;
307
0
  uint8_t     mpduCode;
308
0
  uint16_t      length;
309
0
  proto_item *pdcPacketItem;
310
0
  proto_tree *pdcPacketTree;
311
312
0
  length = 0;
313
314
  /*Get the length indictor and the MPDU Code*/
315
0
  len_indicator  = tvb_get_uint8 (tvb, i);
316
0
  mpduCode       = tvb_get_uint8 (tvb, i + 1);
317
0
  length        += 2;
318
319
  /*Add the PDC Tree*/
320
0
  pdcPacketItem = proto_tree_add_item (tree, proto_pdc, tvb, i, len_indicator + 1, ENC_NA);
321
0
  pdcPacketTree = proto_item_add_subtree (pdcPacketItem, ett_pdc);
322
323
  /*Add the Length and packet type*/
324
0
  proto_tree_add_item(pdcPacketTree, hf_pdc_len, tvb, i, 1, ENC_BIG_ENDIAN);
325
0
  proto_tree_add_item(pdcPacketTree, hf_pdc_mpdu_code, tvb, i + 1, 1, ENC_BIG_ENDIAN);
326
327
  /*Call the correct dissecting function*/
328
0
  switch (mpduCode)
329
0
  {
330
0
  case SIMPDU:
331
0
    length += dissect_simpdu(tvb, pdcPacketTree, length, len_indicator);
332
0
    col_set_str(pinfo->cinfo, COL_INFO, "SIMPDU");
333
0
    break;
334
0
  case RSMPDU:
335
0
    length += dissect_rsmpdu();
336
0
    col_set_str(pinfo->cinfo, COL_INFO, "RSMPDU");
337
0
    break;
338
0
  case DRMPDU:
339
0
    length += dissect_drmpdu(tvb, pdcPacketTree, length);
340
0
    col_set_str(pinfo->cinfo, COL_INFO, "DRMPDU");
341
0
    break;
342
0
  case DTMPDU:
343
0
    length += dissect_dtmpdu(tvb, tree, pdcPacketTree, length, pinfo);
344
0
    col_set_str(pinfo->cinfo, COL_INFO, "DTMPDU");
345
0
    break;
346
0
  case ADMPDU:
347
0
    length += dissect_admpdu(tvb, tree, pdcPacketTree, length, pinfo);
348
0
    col_set_str(pinfo->cinfo, COL_INFO, "ADMPDU");
349
0
    break;
350
0
  case EDMPDU:
351
0
    length += dissect_edmpdu(tvb, tree, pdcPacketTree, length, pinfo);
352
0
    col_set_str(pinfo->cinfo, COL_INFO, "EDMPDU");
353
0
    break;
354
0
  case AKMPDU:
355
0
    length += dissect_akmpdu(tvb, pdcPacketTree, length);
356
0
    col_set_str(pinfo->cinfo, COL_INFO, "AKMPDU");
357
0
    break;
358
0
  default:
359
0
    break;
360
0
  };
361
0
  return (length);  /* XXX: returned length ignored by caller: Remove keeping track of data processed ?         */
362
        /*      col_set_str() could then be done separately with 'if (tree)' around the dissection */
363
0
}
364
365
/* Actual dissector bits and bytes done here */
366
static int dissect_pdc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
367
0
{
368
  /*Set the Column*/
369
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDC");
370
0
  col_clear(pinfo->cinfo, COL_INFO);
371
372
0
  dissect_pdc_packet(tvb, tree, pinfo);
373
374
0
  return tvb_reported_length(tvb);
375
0
}
376
377
/* function to provide TCP split packet combiner with size of packet */
378
static unsigned get_pdc_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
379
                                 int offset, void *data _U_)
380
0
{
381
0
  unsigned  size;
382
0
  unsigned  extra;
383
0
  uint8_t mpdu_type;
384
385
0
  mpdu_type = tvb_get_uint8(tvb, offset+1);
386
0
  switch (mpdu_type)
387
0
  {
388
0
  case SIMPDU:
389
0
    size  = tvb_get_uint8(tvb, offset);
390
0
    extra = 1;
391
0
    break;
392
0
  case RSMPDU:
393
0
    size  = tvb_get_uint8(tvb, offset);
394
0
    extra = 1;
395
0
    break;
396
0
  case DRMPDU:
397
0
    size  = tvb_get_uint8(tvb, offset);
398
0
    extra = 1;
399
0
    break;
400
0
  case DTMPDU:
401
0
    size  = tvb_get_ntohs(tvb, offset+2);
402
0
    extra = 4;
403
0
    break;
404
0
  case ADMPDU:
405
0
    size  = tvb_get_ntohs(tvb, offset+6);
406
0
    extra = 8;
407
0
    break;
408
0
  case EDMPDU:
409
0
    size  = tvb_get_uint8(tvb, offset);
410
0
    extra = 1;
411
0
    break;
412
0
  case AKMPDU:
413
0
    size  = tvb_get_uint8(tvb, offset)+1;
414
0
    extra = 0;
415
0
    break;
416
0
  default:
417
0
    size  = 0;
418
0
    extra = 0;
419
0
  }
420
0
  return size + extra;
421
0
}
422
423
/* top level call to recombine split tcp packets */
424
425
static int tcp_dissect_pdc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
426
0
{
427
0
  uint8_t mpdu_type;
428
0
  uint8_t minimum_bytes;
429
430
0
  mpdu_type = tvb_get_uint8(tvb,1);
431
0
  switch (mpdu_type)
432
0
  {
433
0
  case SIMPDU:
434
0
    minimum_bytes = 2;
435
0
    break;
436
0
  case RSMPDU:
437
0
    minimum_bytes = 2;
438
0
    break;
439
0
  case DRMPDU:
440
0
    minimum_bytes = 2;
441
0
    break;
442
0
  case DTMPDU:
443
0
    minimum_bytes = 4;
444
0
    break;
445
0
  case ADMPDU:
446
0
    minimum_bytes = 8;
447
0
    break;
448
0
  case EDMPDU:
449
0
    minimum_bytes = 2;
450
0
    break;
451
0
  case AKMPDU:
452
0
    minimum_bytes = 2;
453
0
    break;
454
0
  default:
455
0
    minimum_bytes = 2;
456
0
    break;
457
0
  }
458
0
  tcp_dissect_pdus(tvb, pinfo, tree, true, minimum_bytes, get_pdc_message_len, dissect_pdc, NULL);
459
0
  return tvb_captured_length(tvb);
460
0
}
461
462
void proto_register_pdc(void)
463
16
{
464
16
  static hf_register_info hf[] =
465
16
  {
466
16
    { &hf_pdc_len,
467
16
      { "Length Indicator", "pdc.li",
468
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
469
470
16
    { &hf_pdc_mpdu_code,
471
16
      { "MPDU code", "pdc.mpducode",
472
16
        FT_UINT8, BASE_DEC, VALS(valstr_mpdus), 0x0, NULL, HFILL }},
473
474
16
    { &hf_pdc_credit,
475
16
      { "Credit", "pdc.cdt",
476
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
477
478
16
    { &hf_pdc_yr_admu_nr,
479
16
      { "YR-ADMU-NR", "pdc.yradmunr",
480
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL , HFILL }},
481
482
16
    { &hf_pdc_simpdu_state,
483
16
      { "State", "pdc.state",
484
16
        FT_UINT8, BASE_DEC, VALS(valstr_simpdu_state), 0x0, NULL, HFILL }},
485
486
16
    { &hf_pdc_akmpdu_mns,
487
16
      { "MNS", "pdc.akmpdu.mns",
488
16
        FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL }},
489
490
16
    { &hf_pdc_akmpdu_cdt,
491
16
      { "CDT", "pdc.akmpdu.cdt",
492
16
        FT_UINT16, BASE_DEC, NULL, 0x07FF, NULL, HFILL }},
493
494
16
    { &hf_pdc_simpdu_var,
495
16
      { "Variable Part", "pdc.simpdu.variable",
496
16
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
497
498
16
    { &hf_pdc_simpdu_param,
499
16
      { "Parameter", "pdc.simpdu.param",
500
16
        FT_UINT8, BASE_DEC, VALS(valstr_simpdu_param), 0x0, NULL, HFILL }},
501
502
16
    { &hf_pdc_simpdu_var_len,
503
16
      { "Length", "pdc.simpdu.variable.length",
504
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
505
506
16
    { &hf_pdc_simpdu_var_version,
507
16
      { "PDC Version Number", "pdc.simpdu.variable.version",
508
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
509
510
16
    { &hf_pdc_simpdu_var_REFSRC,
511
16
      { "Reference Source", "pdc.simpdu.variable.refsrc",
512
16
        FT_UINT32, BASE_DEC, NULL, 0x0,NULL, HFILL }},
513
514
16
    { &hf_pdc_simpdu_var_REFDEST,
515
16
      { "Reference Destination", "pdc.simpdu.variable.refdst",
516
16
        FT_UINT32, BASE_DEC, NULL, 0x0,NULL, HFILL }},
517
518
16
    { &hf_pdc_simpdu_var_TSEL,
519
16
      { "Transport Selector", "pdc.simpdu.tsel",
520
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
521
522
16
    { &hf_pdc_drmpdu_abort,
523
16
      { "Abort", "pdc.drmpdu.abort",
524
16
        FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_abort), 0x80, NULL, HFILL }},
525
526
16
    { &hf_pdc_drmpdu_reason,
527
16
      { "Reason", "pdc.drmpdu.reason",
528
16
        FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_reason), 0x0, NULL, HFILL }},
529
530
16
    { &hf_pdc_drmpdu_mode,
531
16
      { "Mode", "pdc.drmpdu.mode",
532
16
        FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_mode), 0x70, NULL, HFILL }},
533
534
16
    { &hf_pdc_drmpdu_init,
535
16
      { "Reason", "pdc.drmpdu.init",
536
16
        FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_initatior), 0x0F, NULL, HFILL }},
537
538
16
    { &hf_pdc_dtmpdu_user_size,
539
16
      { "User Data Length", "pdc.dtmpdu.usersize",
540
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL , HFILL }},
541
542
16
    { &hf_pdc_admpdu_admpdunr,
543
16
      { "AD-MPDU-NR", "pdc.admpdu.admpdunr",
544
16
        FT_UINT32,  BASE_DEC, NULL, 0x0, NULL , HFILL }},
545
546
16
    { &hf_pdc_admpdu_size,
547
16
      { "User Data Size", "pdc.admpdu.usersize",
548
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL , HFILL }},
549
16
  };
550
551
  /* Setup protocol subtree array */
552
16
  static int *ett[] = {
553
16
    &ett_pdc,
554
16
    &ett_pdc_simpdu_var
555
16
  };
556
557
16
  proto_pdc = proto_register_protocol ("PDC Protocol", "PDC", "pdc");
558
559
  /*Required Function Calls to register the header fields and subtrees used*/
560
16
  proto_register_field_array(proto_pdc, hf, array_length(hf));
561
16
  proto_register_subtree_array(ett, array_length(ett));
562
563
  /* Register our dissector handle */
564
16
  pdc_tcp_handle = register_dissector("pdc", tcp_dissect_pdc, proto_pdc);
565
16
}
566
567
/* Function to add pdc dissector to tcp.port dissector table and to get handle for asterix dissector */
568
void proto_reg_handoff_pdc(void)
569
16
{
570
16
  asterix_handle = find_dissector_add_dependency("asterix", proto_pdc);
571
16
  dissector_add_for_decode_as_with_preference("tcp.port", pdc_tcp_handle);
572
16
}
573
574
/*
575
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
576
 *
577
 * Local variables:
578
 * c-basic-offset: 8
579
 * tab-width: 8
580
 * indent-tabs-mode: t
581
 * End:
582
 *
583
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
584
 * :indentSize=8:tabSize=8:noTabs=false:
585
 */