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-dmp.c
Line
Count
Source
1
/* packet-dmp.c
2
 *
3
 * Routines for STANAG 4406 Direct Message Profile packet disassembly.
4
 * A protocol for optimised transfer of time-critical short messages
5
 * for use with a reliable bearer service.  Checksum and retransmission
6
 * mechanisms are activated when using unreliable bearer services.
7
 *
8
 * Copyright 2006, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
9
 *
10
 * Wireshark - Network traffic analyzer
11
 * By Gerald Combs <gerald@wireshark.org>
12
 * Copyright 1998 Gerald Combs
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 *
16
 * Ref:  http://jcs.dtic.mil/j6/cceb/acps/acp123/
17
 *       https://web.archive.org/web/20100326015412/http://jcs.dtic.mil/j6/cceb/acps/acp123/ACP123A.pdf
18
 */
19
20
/*
21
 * TODO:
22
 * - Dissect extended Restrictive security categories
23
 * - Add Transmission/Retransmission statistics
24
 */
25
26
#include "config.h"
27
28
#include <math.h>
29
30
#include <epan/packet.h>
31
#include <epan/to_str.h>
32
#include <epan/prefs.h>
33
#include <epan/expert.h>
34
#include <epan/crc16-tvb.h>
35
#include <epan/asn1.h>
36
#include <epan/uat.h>
37
#include <epan/proto_data.h>
38
#include <epan/tfs.h>
39
#include <epan/exceptions.h>
40
41
#include <wsutil/str_util.h>
42
#include <wsutil/array.h>
43
44
#include "packet-p1.h"
45
#include "packet-p22.h"
46
#include "packet-s5066sis.h"
47
48
void proto_register_dmp(void);
49
void proto_reg_handoff_dmp(void);
50
51
14
#define PNAME  "Direct Message Profile"
52
14
#define PSNAME "DMP"
53
28
#define PFNAME "dmp"
54
55
/* Default UDP Port Number */
56
14
#define DEFAULT_DMP_PORT_RANGE "5031"
57
58
/* Protocol Identifier */
59
16.0k
#define PROT_NAT 0x0D
60
518
#define PROT_DMP 0x1D
61
62
/* Versions supported */
63
22.3k
#define DMP_VERSION_1  1
64
3.36k
#define DMP_VERSION_2  2
65
66
/* Message Type (dmp.msg_type) */
67
15.2k
#define STANAG   0x0
68
8.86k
#define IPM      0x1
69
2.93k
#define REPORT   0x2
70
1.01k
#define NOTIF    0x3
71
3.43k
#define ACK      0x4
72
73
/* Message Identifier Type (dmp.msg_id_type) */
74
622
#define ONLY_DMP_ID  0x0
75
1.02k
#define X400_MSG_ID  0x1
76
388
#define NAT_MSG_ID   0x2
77
78
/* Report Type (dmp.report_type) */
79
3.25k
#define DR       0x0
80
#define NDR      0x1
81
82
/* Notification Type (dmp.notif_type) */
83
56
#define RN       0x0
84
17
#define NRN      0x1
85
48
#define ON       0x2
86
87
/* Address Encoding (dmp.addr_enc) */
88
11.2k
#define DIRECT_ADDR   0x0
89
#define EXTENDED_ADDR 0x1
90
91
/* Address type (internal values) */
92
270
#define ORIGINATOR   1
93
1.38k
#define P1_ADDRESS   2
94
1.29k
#define P2_ADDRESS   3
95
17
#define ORIG_P2_ADDRESS   4
96
97
/* Extended Address Form (dmp_addr_form) */
98
831
#define P1_DIRECT             0x0
99
581
#define P2_DIRECT             0x1
100
139
#define P1_EXTENDED           0x2
101
318
#define P2_EXTENDED           0x3
102
1.92k
#define P1_P2_DIRECT          0x4
103
1.48k
#define P1_DIRECT_P2_EXTENDED 0x5
104
1.09k
#define P1_EXTENDED_P2_DIRECT 0x6
105
719
#define P1_P2_EXTENDED        0x7
106
107
/* Extended Address Type */
108
722
#define ASN1_BER 0x0
109
629
#define ASN1_PER 0x1
110
111
/* Security Policy (dmp_sec_pol) */
112
1.03k
#define NATO              0x4
113
1.74k
#define NATIONAL          0x5
114
976
#define EXTENDED_NATIONAL 0x6
115
231
#define EXTENDED_MISSION  0x7
116
117
81
#define SEC_CAT_EXT_NONE        0x0
118
769
#define SEC_CAT_EXT_PERMISSIVE  0x1
119
334
#define SEC_CAT_EXT_RESTRICTIVE 0x2
120
121
/* Body Format (dmp.body_format) */
122
346
#define FREE_TEXT         0x0
123
182
#define FREE_TEXT_SUBJECT 0x1
124
100
#define STRUCTURED        0x2
125
126
/* Encoded Information Types */
127
104
#define EIT_BILATERAL     0x3
128
129
/* Compression Algorithm */
130
143
#define ALGORITHM_NONE    0x0
131
208
#define ALGORITHM_ZLIB    0x1
132
133
/* National Decoding */
134
#define NAT_DECODE_NONE    0
135
26
#define NAT_DECODE_DMP     1
136
899
#define NAT_DECODE_THALES  2
137
138
46
#define IPM_MODIFIER_X400  0
139
140
/* Internal values for not present and reserved time values */
141
296
#define DMP_TIME_NOT_PRESENT  -1
142
3.19k
#define DMP_TIME_RESERVED     -2
143
144
0
#define ILLEGAL_FORMAT "<Illegal format>"
145
0
#define TIME_NOT_REPRESENTABLE "<Time not representable>"
146
147
/* Maximum lengths */
148
499
#define MAX_SIC_LEN         30
149
150
static int proto_dmp;
151
152
static int hf_dmp_id;
153
static int hf_mts_id;
154
static int hf_ipm_id;
155
156
static int hf_envelope;
157
static int hf_envelope_protocol_id;
158
static int hf_envelope_version;
159
static int hf_envelope_version_value;
160
static int hf_envelope_hop_count;
161
static int hf_envelope_hop_count_value;
162
static int hf_envelope_rec_present;
163
static int hf_envelope_addr_enc;
164
static int hf_envelope_checksum;
165
static int hf_envelope_extensions;
166
static int hf_envelope_msg_id_type;
167
static int hf_envelope_msg_id_length;
168
static int hf_envelope_mts_id_length;
169
static int hf_envelope_ipm_id_modifier;
170
static int hf_envelope_ipm_id_length;
171
static int hf_envelope_mts_id;
172
static int hf_envelope_ipm_id;
173
static int hf_envelope_type;
174
static int hf_envelope_msg_id;
175
static int hf_envelope_msg_id_12bit;
176
static int hf_envelope_subm_time;
177
static int hf_envelope_subm_time_value;
178
static int hf_envelope_time_diff_present;
179
static int hf_envelope_time_diff;
180
static int hf_envelope_time_diff_value;
181
static int hf_envelope_flags;
182
static int hf_envelope_content_id_discarded;
183
static int hf_envelope_recip_reassign_prohib;
184
static int hf_envelope_dl_expansion_prohib;
185
static int hf_envelope_recipients;
186
static int hf_envelope_ext_recipients;
187
188
static int hf_thales_ipm_id_modifier;
189
190
static int hf_extensions;
191
static int hf_extension;
192
static int hf_extension_header;
193
static int hf_extension_more;
194
static int hf_extension_length;
195
static int hf_extension_data;
196
197
static int hf_message_content;
198
static int hf_report_content;
199
static int hf_notif_content;
200
201
static int hf_addr_recipient;
202
static int hf_addr_originator;
203
static int hf_addr_reporting_name;
204
static int hf_addr_dl_expanded;
205
static int hf_addr_int_rec;
206
static int hf_addr_dir_addr_ext;
207
static int hf_addr_dir_rec_no;
208
static int hf_addr_dir_rec_no1;
209
static int hf_addr_dir_rec_no2;
210
static int hf_addr_dir_rec_no3;
211
static int hf_addr_dir_rec_no_generated;
212
static int hf_addr_dir_rep_req1;
213
static int hf_addr_dir_rep_req2;
214
static int hf_addr_dir_rep_req3;
215
static int hf_addr_dir_not_req1;
216
static int hf_addr_dir_not_req2;
217
static int hf_addr_dir_not_req3;
218
static int hf_addr_dir_action;
219
static int hf_addr_dir_address;
220
static int hf_addr_dir_address1;
221
static int hf_addr_dir_address2;
222
static int hf_addr_dir_address3;
223
static int hf_addr_dir_address_generated;
224
225
static int hf_addr_ext_form;
226
static int hf_addr_ext_form_orig_v1;
227
static int hf_addr_ext_form_orig;
228
static int hf_addr_ext_action;
229
static int hf_addr_ext_rep_req;
230
static int hf_addr_ext_not_req;
231
static int hf_addr_ext_rec_ext;
232
static int hf_addr_ext_rec_no;
233
static int hf_addr_ext_rec_no1;
234
static int hf_addr_ext_rec_no2;
235
static int hf_addr_ext_rec_no_generated;
236
static int hf_addr_ext_address;
237
static int hf_addr_ext_type;
238
static int hf_addr_ext_type_ext;
239
static int hf_addr_ext_length;
240
static int hf_addr_ext_length1;
241
static int hf_addr_ext_length2;
242
static int hf_addr_ext_length_generated;
243
static int hf_addr_ext_asn1_ber;
244
static int hf_addr_ext_asn1_per;
245
static int hf_addr_ext_unknown;
246
247
static int hf_message_body;
248
static int hf_message_st_type;
249
static int hf_message_precedence;
250
static int hf_message_importance;
251
static int hf_message_body_format;
252
static int hf_message_sec_class_val;
253
static int hf_message_sec_pol;
254
static int hf_message_heading_flags;
255
static int hf_message_auth_users;
256
static int hf_message_subject_disc;
257
static int hf_message_national_policy_id;
258
static int hf_message_mission_policy_id;
259
static int hf_message_sec_label;
260
static int hf_message_sec_cat_nat;
261
static int hf_message_sec_cat_val;
262
static int hf_message_sec_cat_cl;
263
static int hf_message_sec_cat_cs;
264
static int hf_message_sec_cat_ex;
265
static int hf_message_sec_cat_ne;
266
static int hf_message_sec_cat_permissive;
267
static int hf_message_sec_cat_country_code;
268
static int hf_message_sec_cat_restrictive;
269
static int hf_message_sec_cat_extended;
270
static int hf_message_sec_cat_bit0;
271
static int hf_message_sec_cat_bit1;
272
static int hf_message_sec_cat_bit2;
273
static int hf_message_sec_cat_bit3;
274
static int hf_message_sec_cat_bit4;
275
static int hf_message_sec_cat_bit5;
276
static int hf_message_sec_cat_bit6;
277
static int hf_message_sec_cat_bit7;
278
static int hf_message_exp_time;
279
static int hf_message_exp_time_val;
280
static int hf_message_dtg;
281
static int hf_message_dtg_sign;
282
static int hf_message_dtg_val;
283
static int hf_message_sic;
284
static int hf_message_sic_key;
285
static int hf_message_sic_key_values;
286
static int hf_message_sic_key_type;
287
static int hf_message_sic_key_chars;
288
static int hf_message_sic_key_num;
289
static int hf_message_sic_bitmap;
290
static int hf_message_sic_bits;
291
static int hf_message_sic_bits_any;
292
static int hf_message_subj_id;
293
static int hf_message_subj_mts_id;
294
static int hf_message_subj_ipm_id;
295
296
static int hf_message_subject;
297
static int hf_message_eit;
298
static int hf_message_compr;
299
static int hf_message_body_data;
300
static int hf_message_body_compressed;
301
static int hf_message_body_plain;
302
static int hf_message_body_structured;
303
304
static int hf_delivery_report;
305
static int hf_non_delivery_report;
306
static int hf_report_type;
307
static int hf_report_info_present_dr;
308
static int hf_report_addr_enc_dr;
309
static int hf_report_del_time;
310
static int hf_report_del_time_val;
311
static int hf_report_addr_enc_ndr;
312
static int hf_report_reason;
313
static int hf_report_info_present_ndr;
314
static int hf_report_diagn;
315
static int hf_report_suppl_info_len;
316
static int hf_report_suppl_info;
317
318
static int hf_receipt_notif;
319
static int hf_non_receipt_notif;
320
static int hf_other_notif;
321
static int hf_notif_type;
322
static int hf_notif_rec_time;
323
static int hf_notif_rec_time_val;
324
static int hf_notif_suppl_info_len;
325
static int hf_notif_suppl_info;
326
static int hf_notif_non_rec_reason;
327
static int hf_notif_discard_reason;
328
static int hf_notif_on_type;
329
static int hf_notif_acp127;
330
static int hf_notif_acp127recip;
331
332
static int hf_ack;
333
static int hf_ack_reason;
334
static int hf_ack_diagnostic;
335
static int hf_ack_recips;
336
337
static int hf_checksum;
338
static int hf_checksum_status;
339
340
static int hf_analysis_ack_time;
341
static int hf_analysis_total_time;
342
static int hf_analysis_retrans_time;
343
static int hf_analysis_total_retrans_time;
344
static int hf_analysis_msg_num;
345
static int hf_analysis_acks_msg_num;
346
static int hf_analysis_retrans_no;
347
static int hf_analysis_ack_num;
348
static int hf_analysis_ack_missing;
349
static int hf_analysis_ack_dup_no;
350
/* static int hf_analysis_rep_num; */
351
static int hf_analysis_acks_rep_num;
352
static int hf_analysis_rep_time;
353
/* static int hf_analysis_not_num; */
354
static int hf_analysis_acks_not_num;
355
static int hf_analysis_not_time;
356
static int hf_analysis_msg_resend_from;
357
static int hf_analysis_rep_resend_from;
358
static int hf_analysis_not_resend_from;
359
static int hf_analysis_ack_resend_from;
360
361
static int hf_reserved_0x01;
362
static int hf_reserved_0x02;
363
static int hf_reserved_0x04;
364
static int hf_reserved_0x07;
365
static int hf_reserved_0x08;
366
static int hf_reserved_0x0F;
367
static int hf_reserved_0x1F;
368
static int hf_reserved_0x20;
369
static int hf_reserved_0x40;
370
static int hf_reserved_0xC0;
371
static int hf_reserved_0xE0;
372
static int hf_reserved_0x8000;
373
374
static int ett_dmp;
375
static int ett_envelope;
376
static int ett_envelope_version;
377
static int ett_envelope_hop_count;
378
static int ett_envelope_rec_present;
379
static int ett_envelope_addr_enc;
380
static int ett_envelope_checksum;
381
static int ett_envelope_extensions;
382
static int ett_envelope_msg_id_type;
383
static int ett_envelope_msg_id;
384
static int ett_envelope_mts_id_length;
385
static int ett_envelope_ipm_id_length;
386
static int ett_envelope_cont_type;
387
static int ett_envelope_subm_time;
388
static int ett_envelope_time_diff;
389
static int ett_envelope_flags;
390
static int ett_envelope_recipients;
391
static int ett_envelope_ext_recipients;
392
static int ett_envelope_addresses;
393
394
static int ett_address;
395
static int ett_address_direct;
396
static int ett_address_rec_no;
397
static int ett_address_extended;
398
static int ett_address_ext_form;
399
static int ett_address_ext_rec_no;
400
static int ett_address_ext_action;
401
static int ett_address_ext_rep_req;
402
static int ett_address_ext_not_req;
403
static int ett_address_ext_type;
404
static int ett_address_ext_length;
405
406
static int ett_extensions;
407
static int ett_extension;
408
static int ett_extension_header;
409
410
static int ett_content;
411
412
static int ett_message;
413
static int ett_message_st_type;
414
static int ett_message_reserved;
415
static int ett_message_precedence;
416
static int ett_message_importance;
417
static int ett_message_body_format;
418
static int ett_message_sec_class;
419
static int ett_message_sec_pol;
420
static int ett_message_sec_cat;
421
static int ett_message_heading_flags;
422
static int ett_message_exp_time;
423
static int ett_message_dtg;
424
static int ett_message_sic;
425
static int ett_message_sic_key;
426
static int ett_message_sic_bitmap;
427
static int ett_message_sic_bits;
428
static int ett_message_eit;
429
static int ett_message_compr;
430
static int ett_message_body_reserved;
431
static int ett_message_body;
432
433
static int ett_report;
434
static int ett_report_type;
435
static int ett_report_info_present_dr;
436
static int ett_report_info_present_ndr;
437
static int ett_report_addr_enc_dr;
438
static int ett_report_addr_enc_ndr;
439
static int ett_report_reserved;
440
static int ett_report_del_time;
441
static int ett_report_reason;
442
static int ett_report_suppl_info;
443
static int ett_report_diagn;
444
445
static int ett_notif;
446
static int ett_notif_type;
447
static int ett_notif_rec_time;
448
static int ett_notif_suppl_info;
449
static int ett_notif_acp127recip;
450
451
static int ett_ack;
452
static int ett_ack_recips;
453
454
static int ett_analysis;
455
456
static expert_field ei_reserved_value;
457
static expert_field ei_message_sic_illegal;
458
static expert_field ei_envelope_version_value;
459
static expert_field ei_message_compr;
460
static expert_field ei_ack_reason;
461
static expert_field ei_addr_ext_rec_no_generated;
462
static expert_field ei_checksum_bad;
463
static expert_field ei_message_body_uncompress;
464
static expert_field ei_envelope_msg_id;
465
static expert_field ei_7bit_string_unused_bits;
466
static expert_field ei_analysis_ack_missing;
467
static expert_field ei_analysis_ack_dup_no;
468
static expert_field ei_analysis_ack_unexpected;
469
static expert_field ei_analysis_msg_missing;
470
static expert_field ei_analysis_retrans_no;
471
static expert_field ei_too_many_sec_cat;
472
473
static dissector_handle_t dmp_handle;
474
475
typedef struct _dmp_id_key {
476
  unsigned   id;
477
  address src;
478
  address dst;
479
} dmp_id_key;
480
481
typedef struct _dmp_id_val {
482
  int      msg_type;                   /* Message type                   */
483
  unsigned prev_msg_id;                /* Previous message package num   */
484
  unsigned msg_id;                     /* Message package num            */
485
  unsigned ack_id;                     /* Acknowledgement package num    */
486
  unsigned rep_id;                     /* Report package num             */
487
  unsigned not_id;                     /* Notification package num       */
488
  nstime_t msg_time;                   /* Message receive time           */
489
  nstime_t first_msg_time;             /* First message receive time     */
490
  nstime_t prev_msg_time;              /* Previous message receive time  */
491
  nstime_t rep_not_msg_time;           /* Report or Notification time    */
492
  uint32_t msg_resend_count;           /* Message resend counter         */
493
  uint32_t ack_resend_count;           /* Acknowledgement resend counter */
494
} dmp_id_val;
495
496
static wmem_map_t *dmp_id_hash_table;
497
static wmem_map_t *dmp_long_id_hash_table;
498
499
/* Global values used in several functions */
500
static struct dmp_data {
501
  int      version;
502
  int      prot_id;
503
  int      addr_enc;
504
  int      checksum;
505
  int      msg_type;
506
  int      st_type;
507
  int      prec;
508
  int      body_format;
509
  int      notif_type;
510
  int32_t  subm_time;
511
  uint8_t  msg_id_type;
512
  uint8_t  mts_id_length;
513
  proto_item *mts_id_item;
514
  uint8_t  ack_reason;
515
  uint16_t msg_id;
516
  uint16_t subj_id;
517
  bool extensions;
518
  bool dr;
519
  bool ndr;
520
  bool notif_req;
521
  bool ack_rec_present;
522
  dmp_id_val *id_val;
523
} dmp;
524
525
/* User definable values */
526
static int      dmp_nat_decode = NAT_DECODE_DMP;
527
static int      dmp_local_nation;
528
static bool use_seq_ack_analysis = true;
529
static bool dmp_align;
530
531
typedef struct _dmp_security_class_t {
532
  unsigned nation;
533
  unsigned sec_class;
534
  char *name;
535
} dmp_security_class_t;
536
537
static dmp_security_class_t *dmp_security_classes;
538
static unsigned num_dmp_security_classes;
539
540
static const true_false_string addr_enc = {
541
  "Use Extended Encoding", "Use Direct Encoding"
542
};
543
544
static const true_false_string dtg_sign = {
545
  "Future", "Past"
546
};
547
548
static const true_false_string report_type = {
549
  "Non-Delivery Report", "Delivery Report"
550
};
551
552
static const value_string version_vals[] = {
553
  { 0x0, "1"       },
554
  { 0x1, "2"       },
555
  { 0x2, "Unknown" },
556
  { 0x3, "Unknown" },
557
  { 0x4, "Unknown" },
558
  { 0x5, "Unknown" },
559
  { 0x6, "Unknown" },
560
  { 0x7, "Unknown" },
561
  { 0,   NULL } };
562
563
static const value_string type_vals[] = {
564
  { 0x0, "Message"          },
565
  { 0x1, "Message (E-Mail)" },
566
  { 0x2, "Report"           },
567
  { 0x3, "Notification"     },
568
  { 0x4, "Acknowledgement"  },
569
  { 0x5, "Unknown Content"  },
570
  { 0x6, "Unknown Content"  },
571
  { 0x7, "Unknown Content"  },
572
  { 0,   NULL } };
573
574
static const value_string msg_id_type_vals[] = {
575
  { 0x0, "DMP Identifiers only"      },
576
  { 0x1, "X.400 Message Identifiers" },
577
  { 0x2, "Nationally-defined"        },
578
  { 0x3, "Reserved"                  },
579
  { 0,   NULL } };
580
581
static const value_string msg_id_length_vals[] = {
582
  { 0x0, "Full (16 bits)"  },
583
  { 0x1, "Short (12 bits)" },
584
  { 0,   NULL } };
585
586
static const value_string report_vals[] = {
587
  { 0x0, "No Report"           },
588
  { 0x1, "Non-Delivery Report" },
589
  { 0x2, "Delivery Report"     },
590
  { 0x3, "Reserved"            },
591
  { 0,   NULL } };
592
593
static const value_string report_vals_ext[] = {
594
  { 0x0, "No Report"                 },
595
  { 0x1, "Non-Delivery Report"       },
596
  { 0x2, "Delivery Report"           },
597
  { 0x3, "Recipient Number Extended" },
598
  { 0,   NULL } };
599
600
/* Note the space in front of these values */
601
static const value_string report_vals_short[] = {
602
  { 0x1, " NDR" },
603
  { 0x2, " DR"  },
604
  { 0,   NULL } };
605
606
static const value_string notif_vals[] = {
607
  { 0x0, "No Notification"          },
608
  { 0x1, "Non-Receipt Notification" },
609
  { 0x2, "Receipt Notification"     },
610
  { 0x3, "Reserved"                 },
611
  { 0,   NULL } };
612
613
static const value_string notif_vals_ext[] = {
614
  { 0x0, "No Notification"          },
615
  { 0x1, "Non-Receipt Notification" },
616
  { 0x2, "Receipt Notification"     },
617
  { 0x3, "Direct Address Extended"  },
618
  { 0,   NULL } };
619
620
/* Note the space in front of these values */
621
static const value_string notif_vals_short[] = {
622
  { 0x1, " NRN" },
623
  { 0x2, " RN"  },
624
  { 0,   NULL } };
625
626
static const value_string notif_type [] = {
627
  { 0x0, "Receipt Notification (RN)"      },
628
  { 0x1, "Non-Receipt Notification (NRN)" },
629
  { 0x2, "Other Notification (ON)"        },
630
  { 0x3, "Unknown Notification"           },
631
  { 0,   NULL } };
632
633
/* Note the space behind these values */
634
static const value_string addr_type_str [] = {
635
  { ORIGINATOR,      ""          },
636
  { P1_ADDRESS,      "P1 "       },
637
  { P2_ADDRESS,      "P22/P772 " },
638
  { ORIG_P2_ADDRESS, "P22 "      },
639
  { 0,          NULL } };
640
641
static const value_string addr_form [] = {
642
  { 0x0, "P1 Direct"                       },
643
  { 0x1, "P22/P772 Direct"                 },
644
  { 0x2, "P1 Extended"                     },
645
  { 0x3, "P22/P772 Extended"               },
646
  { 0x4, "P1 and P22/P772 Direct"          },
647
  { 0x5, "P1 Direct and P22/P772 Extended" },
648
  { 0x6, "P1 Extended and P22/P772 Direct" },
649
  { 0x7, "P1 and P22/P772 Extended"        },
650
  { 0,   NULL } };
651
652
static const value_string addr_form_orig_v1 [] = {
653
  { 0x0, "Direct"                             },
654
  { 0x1, "Reserved"                           },
655
  { 0x2, "Extended"                           },
656
  { 0x3, "Reserved"                           },
657
  { 0x4, "Reserved"                           },
658
  { 0x5, "Reserved"                           },
659
  { 0x6, "Reserved"                           },
660
  { 0x7, "Reserved"                           },
661
  { 0,   NULL } };
662
663
static const value_string addr_form_orig [] = {
664
  { 0x0, "Direct"                             },
665
  { 0x1, "Reserved"                           },
666
  { 0x2, "Extended"                           },
667
  { 0x3, "Reserved"                           },
668
  { 0x4, "Originator and P2 Direct"           },
669
  { 0x5, "Originator Direct and P2 Extended"  },
670
  { 0x6, "Originator Extended and P2 Direct"  },
671
  { 0x7, "Originator and P2 Extended"         },
672
  { 0,   NULL } };
673
674
static const value_string ext_addr_type [] = {
675
  { 0x0, "ASN.1 BER-encoded OR-name" },
676
  { 0x1, "ASN.1 PER-encoded OR-name" },
677
  { 0x2, "Reserved" },
678
  { 0x3, "Reserved" },
679
  { 0x4, "Reserved" },
680
  { 0x5, "Reserved" },
681
  { 0x6, "Reserved" },
682
  { 0x7, "Address Length Extended" },
683
  { 0,   NULL } };
684
685
static const value_string ext_addr_type_ext [] = {
686
  { 0x0, "ASN.1 BER-encoded OR-name" },
687
  { 0x1, "ASN.1 PER-encoded OR-name" },
688
  { 0x2, "Reserved" },
689
  { 0x3, "Reserved" },
690
  { 0x4, "Reserved" },
691
  { 0x5, "Reserved" },
692
  { 0x6, "Reserved" },
693
  { 0x7, "Reserved" },
694
  { 0,   NULL } };
695
696
static const value_string ext_addr_type_short [] = {
697
  { 0x0, "OR-name (BER)" },
698
  { 0x1, "OR-name (PER)" },
699
  { 0x2, "Reserved" },
700
  { 0x3, "Reserved" },
701
  { 0x4, "Reserved" },
702
  { 0x5, "Reserved" },
703
  { 0x6, "Reserved" },
704
  { 0x7, "Reserved" },
705
  { 0,   NULL } };
706
707
static const value_string message_type_vals[] = {
708
  { 0x0, "Operation" },
709
  { 0x1, "Project"   },
710
  { 0x2, "Exercise"  },
711
  { 0x3, "Drill"     },
712
  { 0,   NULL } };
713
714
static const value_string precedence[] = {
715
  { 0x0, "Deferred"  },
716
  { 0x1, "Routine"   },
717
  { 0x2, "Priority"  },
718
  { 0x3, "Immediate" },
719
  { 0x4, "Flash"     },
720
  { 0x5, "Override"  },
721
  { 0x6, "Priority, Info Precedence: Routine"   },
722
  { 0x7, "Immediate, Info Precedence: Routine"  },
723
  { 0,   NULL } };
724
725
static const value_string importance[] = {
726
  { 0x0, "Low"      },
727
  { 0x1, "Reserved" },
728
  { 0x2, "Normal"   },
729
  { 0x3, "Reserved" },
730
  { 0x4, "High"     },
731
  { 0x5, "Reserved" },
732
  { 0x6, "Reserved" },
733
  { 0x7, "Reserved" },
734
  { 0,   NULL } };
735
736
static const value_string sec_class[] = {
737
  { 0x0, "Unmarked"     },
738
  { 0x1, "Unclassified" },
739
/* { 0x2, "Reserved"     }, */
740
  { 0x3, "Restricted"   },
741
/* { 0x4, "Reserved"     }, */
742
  { 0x5, "Confidential" },
743
  { 0x6, "Secret"       },
744
  { 0x7, "Top secret"   },
745
  { 0,   NULL } };
746
747
static const value_string sec_pol[] = {
748
  { 0x0, "Network defined"                   },
749
  { 0x1, "Network defined"                   },
750
  { 0x2, "Network defined"                   },
751
  { 0x3, "Network defined"                   },
752
  { 0x4, "NATO"                              },
753
  { 0x5, "National (nation of local server)" },
754
  { 0x6, "Extended, National"                },
755
  { 0x7, "Extended, Mission Defined"         },
756
  { 0,   NULL } };
757
758
/* For name we use the ISO 3166-1 Alfa-3 value for the country,
759
 * for description we use the Country Name and
760
 * for value we use the DMP value for National Policy Identifier.
761
 */
762
static const enum_val_t dmp_national_values[] = {
763
  { "xxx",  "None", 0x00 },
764
  { "alb",  "Albania", 0x1B },
765
  { "arm",  "Armenia", 0x20 },
766
  { "aut",  "Austria", 0x21 },
767
  { "aze",  "Azerbaijan", 0x22 },
768
  { "blr",  "Belarus", 0x23 },
769
  { "bel",  "Belgium", 0x01 },
770
  { "bih",  "Bosnia and Hercegowina", 0x24 },
771
  { "bgr",  "Bulgaria", 0x02 },
772
  { "can",  "Canada", 0x03 },
773
  { "hrv",  "Croatia", 0x1C },
774
  { "cze",  "Czech Republic", 0x04 },
775
  { "dnk",  "Denmark", 0x05 },
776
  { "est",  "Estonia", 0x06 },
777
  { "eapc", "Euro-Atlantic Partnership Council (EAPC)", 0x3A },
778
  { "eu",   "European Union (EU)", 0x3B },
779
  { "fin",  "Finland", 0x25 },
780
  { "mkd",  "Former Yugoslav Republic of Macedonia", 0x26 },
781
  { "fra",  "France", 0x07 },
782
  { "geo",  "Georgia", 0x27 },
783
  { "deu",  "Germany", 0x08 },
784
  { "grc",  "Greece", 0x09 },
785
  { "hun",  "Hungary", 0x0A },
786
  { "isl",  "Iceland", 0x0B },
787
  { "isaf", "International Security Assistance Force (ISAF)", 0x3C },
788
  { "irl",  "Ireland", 0x28 },
789
  { "ita",  "Italy", 0x0C },
790
  { "kaz",  "Kazakhstan", 0x29 },
791
  { "kgz",  "Kyrgyztan", 0x2A },
792
  { "lva",  "Latvia", 0x0D },
793
  { "ltu",  "Lithuania", 0x0E },
794
  { "lux",  "Luxembourg", 0x0F },
795
  { "mlt",  "Malta", 0x2B },
796
  { "mda",  "Moldova", 0x2C },
797
  { "mne",  "Montenegro", 0x2D },
798
  { "nld",  "Netherlands", 0x10 },
799
  { "nor",  "Norway", 0x11 },
800
  { "pfp",  "Partnership for Peace (PfP)", 0x3D },
801
  { "pol",  "Poland", 0x12 },
802
  { "ptr",  "Portugal", 0x13 },
803
  { "rou",  "Romania", 0x14 },
804
  { "rus",  "Russian Federation", 0x2E },
805
  { "srb",  "Serbia", 0x2F },
806
  { "svk",  "Slovakia", 0x15 },
807
  { "svn",  "Slovenia", 0x16 },
808
  { "esp",  "Spain", 0x17 },
809
  { "swe",  "Sweden", 0x30 },
810
  { "che",  "Switzerland", 0x31 },
811
  { "tjk",  "Tajikistan", 0x32 },
812
  { "tur",  "Turkey", 0x18 },
813
  { "tkm",  "Turkmenistan", 0x33 },
814
  { "gbr",  "United Kingdom", 0x19 },
815
  { "usa",  "United States", 0x1A },
816
  { "ukr",  "Ukraine", 0x34 },
817
  { "uzb",  "Uzbekistan", 0x35 },
818
  { "weu",  "Western European Union (WEU)", 0x3E },
819
  { NULL, NULL, 0 }
820
};
821
822
812
#define MAX_NATIONAL_VALUES array_length(dmp_national_values)
823
/* Will be built in build_national_strings() */
824
static value_string nat_pol_id[MAX_NATIONAL_VALUES];
825
826
static const value_string ext_sec_cat[] = {
827
  { 0x0, "Not present"                  },
828
  { 0x1, "Permissive category follows"  },
829
  { 0x2, "Restrictive category follows" },
830
  { 0x3, "Reserved"                     },
831
  { 0,   NULL } };
832
833
static const value_string sic_key_type[] = {
834
  { 0xc, "2 or more 3-character SICs"      },
835
  { 0xd, "1 or more 3-to-8 character SICs" },
836
  { 0,   NULL } };
837
838
static const true_false_string sic_key_chars = {
839
  "Any", "[A-Z0-9] only"
840
};
841
842
static const value_string sic_key_num[] = {
843
  { 0, "1"  },
844
  { 1, "2"  },
845
  { 2, "3"  },
846
  { 3, "4"  },
847
  { 4, "5"  },
848
  { 5, "6"  },
849
  { 6, "7"  },
850
  { 7, "8"  },
851
  { 0, NULL } };
852
853
854
static const value_string sic_bit_vals[] = {
855
  { 0,   "length:6, bytes:4" },
856
  { 1,   "length:6, bytes:4" },
857
  { 2,   "length:6, bytes:4" },
858
  { 3,   "length:6, bytes:4" },
859
  { 4,   "length:6, bytes:4" },
860
  { 5,   "length:6, bytes:4" },
861
  { 6,   "length:6, bytes:4" },
862
  { 7,   "length:6, bytes:4" },
863
  { 8,   "length:6, bytes:4" },
864
  { 9,   "reserved"          },
865
  { 10,  "length:5, bytes:4" },
866
  { 11,  "length:8, bytes:6" },
867
  { 12,  "length:4, bytes:3" },
868
  { 13,  "length:4, bytes:3" },
869
  { 14,  "length:7, bytes:5" },
870
  { 15,  "length:7, bytes:5" },
871
  { 0,   NULL } };
872
873
static const value_string sic_bit_any_vals[] = {
874
  { 0,   "length:5, bytes:4" },
875
  { 1,   "length:5, bytes:4" },
876
  { 2,   "length:5, bytes:4" },
877
  { 3,   "length:5, bytes:4" },
878
  { 4,   "length:5, bytes:4" },
879
  { 5,   "length:5, bytes:4" },
880
  { 6,   "length:5, bytes:4" },
881
  { 7,   "length:5, bytes:4" },
882
  { 8,   "length:5, bytes:4" },
883
  { 9,   "length:8, bytes:7" },
884
  { 10,  "length:4, bytes:4" },
885
  { 11,  "length:7, bytes:6" },
886
  { 12,  "length:6, bytes:5" },
887
  { 13,  "length:6, bytes:5" },
888
  { 14,  "length:6, bytes:5" },
889
  { 15,  "length:6, bytes:5" },
890
  { 0,   NULL } };
891
892
static const value_string body_format_vals[] = {
893
  { 0x0, "Free text"                    },
894
  { 0x1, "Free text including subject"  },
895
  { 0x2, "Structured"                   },
896
  { 0x3, "Reserved"                     },
897
  { 0,   NULL } };
898
899
static const value_string eit_vals[] = {
900
  { 0x0, "Empty"                             },
901
  { 0x1, "IA5-text"                          },
902
  { 0x2, "General text"                      },
903
  { 0x3, "Bilaterally defined (binary data)" },
904
  { 0x4, "AdatP-3"                           },
905
  { 0x5, "Reserved"                          },
906
  { 0x6, "Reserved"                          },
907
  { 0x7, "Reserved"                          },
908
  { 0,   NULL } };
909
910
static const value_string compression_vals[] = {
911
  { 0x0, "No compression"  },
912
  { 0x1, "ZLib compressed" },
913
  { 0x2, "Reserved"        },
914
  { 0x3, "Reserved"        },
915
  { 0,   NULL } };
916
917
static const value_string ack_reason [] = {
918
  { 0x00, "Successful, positive acknowledgement" },
919
  { 0x01, "Unspecified error"                    },
920
  { 0x02, "Checksum incorrect"                   },
921
  { 0,    NULL } };
922
923
static const value_string non_del_reason [] = {
924
  { 0x3D, "Unknown reason"                     },
925
  { 0x3E, "Reason code greater than 0x3c (60)" },
926
  { 0x3F, "Reserved"                           },
927
  { 0,    NULL } };
928
929
static const value_string non_del_diagn [] = {
930
  { 0x7C, "Diagnostic not specified"                },
931
  { 0x7D, "Unknown diagnostic"                      },
932
  { 0x7E, "Diagnostic code greater than 0x7b (123)" },
933
  { 0x7F, "Reserved"                                },
934
  { 0,    NULL } };
935
936
static const value_string discard_reason [] = {
937
  { 0xFE, "Discard Reason absent" },
938
  { 0xFF, "Reserved"              },
939
  { 0,    NULL } };
940
941
static const value_string on_type [] = {
942
  { 0x00, "acp127-nn" },
943
  { 0x01, "acp127-pn" },
944
  { 0x02, "acp127-tn" },
945
  { 0,    NULL } };
946
947
static const value_string ack_msg_type [] = {
948
  { STANAG, " (message)" },
949
  { IPM,    " (e-mail)"  },
950
  { REPORT, " (report)"  },
951
  { NOTIF,  " (notif)"   },
952
  { ACK,    " (ack)"     },
953
  { 0,      NULL } };
954
955
static const enum_val_t national_decoding[] = {
956
  { "none",    "None (raw data)", NAT_DECODE_NONE   },
957
  { "dmp",     "As for regular",  NAT_DECODE_DMP    },
958
  { "thales",  "Thales XOmail",   NAT_DECODE_THALES },
959
  { NULL,      NULL, 0 }
960
};
961
962
static const value_string ipm_id_modifier[] = {
963
  { 0x0,  "X.400 IPM Identifier" },
964
  { 0x1,  "Nationally-defined"   },
965
  { 0x2,  "Nationally-defined"   },
966
  { 0x3,  "Nationally-defined"   },
967
  { 0, NULL }
968
};
969
970
static const value_string thales_ipm_id_modifier[] = {
971
  { 0x0,  "X.400 IPM Identifier" },
972
  { 0x1,  "3 or 5 digits"        },
973
  { 0x2,  "4 digits"             },
974
  { 0x3,  "5 digits"             },
975
  { 0, NULL }
976
};
977
978
UAT_VS_DEF(dmp_security_class, nation, dmp_security_class_t, unsigned, 0, "None")
979
0
UAT_DEC_CB_DEF(dmp_security_class, sec_class, dmp_security_class_t)
Unexecuted instantiation: packet-dmp.c:dmp_security_class_sec_class_set_cb
Unexecuted instantiation: packet-dmp.c:dmp_security_class_sec_class_tostr_cb
980
UAT_CSTRING_CB_DEF(dmp_security_class, name, dmp_security_class_t)
981
982
static void *
983
dmp_class_copy_cb(void *dest, const void *orig, size_t len _U_)
984
0
{
985
0
  dmp_security_class_t *u = (dmp_security_class_t *)dest;
986
0
  const dmp_security_class_t *o = (const dmp_security_class_t *)orig;
987
988
0
  u->nation = o->nation;
989
0
  u->sec_class = o->sec_class;
990
0
  u->name = g_strdup(o->name);
991
992
0
  return dest;
993
0
}
994
995
static void
996
dmp_class_free_cb(void *r)
997
0
{
998
0
  dmp_security_class_t *u = (dmp_security_class_t *)r;
999
1000
0
  g_free(u->name);
1001
0
}
1002
1003
static char *dmp_national_sec_class (unsigned nation, unsigned dmp_sec_class)
1004
28
{
1005
28
  unsigned i;
1006
1007
28
  for (i = 0; i < num_dmp_security_classes; i++) {
1008
0
    dmp_security_class_t *u = &(dmp_security_classes[i]);
1009
1010
0
    if (u->nation == nation && u->sec_class == dmp_sec_class) {
1011
0
      return u->name;
1012
0
    }
1013
0
  }
1014
1015
28
  return NULL;
1016
28
}
1017
1018
static void build_national_strings (void)
1019
14
{
1020
14
  unsigned i = 0;
1021
1022
  /*
1023
  ** We use values from dmp_national_values to build value_string for nat_pol_id.
1024
  */
1025
812
  for (i = 0; i < MAX_NATIONAL_VALUES; i++) {
1026
798
    nat_pol_id[i].value  = dmp_national_values[i].value;
1027
798
    nat_pol_id[i].strptr = dmp_national_values[i].description;
1028
798
  }
1029
14
}
1030
1031
static const char *get_nat_pol_id_short (int nation)
1032
1.52k
{
1033
1.52k
  int i = 0;
1034
42.8k
  while (dmp_national_values[i].name) {
1035
42.7k
    if (dmp_national_values[i].value == nation) {
1036
1.44k
      return dmp_national_values[i].name;
1037
1.44k
    }
1038
41.3k
    i++;
1039
41.3k
  }
1040
1041
78
  return "???";
1042
1.52k
}
1043
1044
static const char *msg_type_to_str (wmem_allocator_t* allocator)
1045
266
{
1046
266
  const char *msg_type;
1047
266
  bool         have_msg = false;
1048
1049
266
  switch (dmp.msg_type) {
1050
1051
150
  case STANAG:
1052
    /* Include message type and precedence */
1053
150
    msg_type = wmem_strdup_printf (allocator, "%s (%s) [%s]",
1054
150
                val_to_str_const (dmp.msg_type, type_vals, "Unknown"),
1055
150
                val_to_str_const (dmp.st_type, message_type_vals, "Unknown"),
1056
150
                (dmp.prec == 0x6 || dmp.prec == 0x7) ?
1057
36
                val_to_str_const (dmp.prec-4, precedence, "Unknown") :
1058
150
                val_to_str_const (dmp.prec, precedence, "Unknown"));
1059
150
    break;
1060
1061
26
  case IPM:
1062
    /* Include importance */
1063
26
    msg_type = wmem_strdup_printf (allocator, "%s [%s]",
1064
26
                val_to_str_const (dmp.msg_type, type_vals, "Unknown"),
1065
26
                val_to_str_const (dmp.prec, importance, "Unknown"));
1066
26
    break;
1067
1068
22
  case REPORT:
1069
    /* Include report types included */
1070
22
    msg_type = wmem_strdup_printf (allocator, "Report (%s%s%s)",
1071
22
                dmp.dr ? "DR" : "", (dmp.dr && dmp.ndr) ? " and " : "",
1072
22
                dmp.ndr ? "NDR" : "");
1073
22
    break;
1074
1075
24
  case NOTIF:
1076
24
    msg_type = val_to_str_const (dmp.notif_type, notif_type, "Unknown");
1077
24
    break;
1078
1079
30
  case ACK:
1080
    /* If we have msg_time we have a matching packet */
1081
30
    have_msg = (dmp.id_val &&
1082
30
                (dmp.id_val->msg_time.secs>0 || dmp.id_val->msg_time.nsecs>0));
1083
30
    msg_type = wmem_strdup_printf (allocator, "Acknowledgement%s%s",
1084
30
                have_msg ? val_to_str(allocator, dmp.id_val->msg_type, ack_msg_type,
1085
30
                                       " (unknown:%d)") : "",
1086
30
                dmp.ack_reason ? " [negative]" : "");
1087
30
    break;
1088
1089
14
  default:
1090
14
    msg_type = "Unknown";
1091
14
    break;
1092
266
  }
1093
1094
266
  return msg_type;
1095
266
}
1096
1097
static const char *non_del_reason_str (uint32_t value)
1098
516
{
1099
516
  if (value < 0x3D) {
1100
    /* Standard values according to P1 */
1101
402
    return val_to_str_const (value, p1_NonDeliveryReasonCode_vals, "Unknown");
1102
402
  } else {
1103
114
    return val_to_str_const (value, non_del_reason, "Unknown");
1104
114
  }
1105
516
}
1106
1107
static const char *non_del_diagn_str (uint32_t value)
1108
513
{
1109
513
  if (value < 0x7C) {
1110
    /* Standard values according to P1 */
1111
469
    return val_to_str_const (value, p1_NonDeliveryDiagnosticCode_vals, "Unknown");
1112
469
  } else {
1113
44
    return val_to_str_const (value, non_del_diagn, "Unknown");
1114
44
  }
1115
513
}
1116
1117
static const char *nrn_reason_str (uint32_t value)
1118
4
{
1119
  /* Standard values according to P22 */
1120
4
  return val_to_str_const (value, p22_NonReceiptReasonField_vals, "Reserved");
1121
4
}
1122
1123
static const char *discard_reason_str (uint32_t value)
1124
4
{
1125
4
  if (value < 0xFE) {
1126
    /* Standard values according to P22 */
1127
3
    return val_to_str_const (value, p22_DiscardReasonField_vals, "Reserved");
1128
3
  } else {
1129
1
    return val_to_str_const (value, discard_reason, "Unknown");
1130
1
  }
1131
4
}
1132
1133
/* Ref chapter 6.2.8.10 TimeDifference */
1134
static int32_t dmp_dec_time_diff (uint8_t dmp_time_diff)
1135
141
{
1136
141
  int32_t time_diff = 0;
1137
1138
141
  if (dmp_time_diff <= 0x01) {
1139
    /* Reserved - low value */
1140
21
    time_diff = DMP_TIME_RESERVED;
1141
120
  } else if (dmp_time_diff <= 0x1D) {
1142
    /* Number of 2-second units (2-58 seconds) */
1143
8
    time_diff = dmp_time_diff * 2;
1144
112
  } else if (dmp_time_diff <= 0x91) {
1145
    /* Number of 15-second units (1 min - 29 min 45 sec) */
1146
38
    time_diff = (dmp_time_diff - 0x1D + 3) * 15;
1147
74
  } else if (dmp_time_diff  <= 0xDF) {
1148
    /* Number of 5-minute units (30 min - 6 hours 55 min) */
1149
44
    time_diff = (dmp_time_diff - 0x91 + 5) * 5*60;
1150
44
  } else if (dmp_time_diff <= 0xF7) {
1151
    /* Number of 30-minute units (7 hours - 18 hours 30 min) */
1152
11
    time_diff = (dmp_time_diff - 0xDF + 7) * 30*60;
1153
19
  } else {
1154
    /* Reserved - high value */
1155
19
    time_diff = DMP_TIME_RESERVED;
1156
19
  }
1157
1158
141
  return time_diff;
1159
141
}
1160
1161
/*
1162
 * Ref chapter 6.3.7.2.10 ExpiryTime
1163
 * and chapter 6.3.9.2.2  DeliveryTime
1164
 */
1165
static int32_t dmp_dec_exp_del_time (uint8_t timev, bool expiry_time)
1166
2.88k
{
1167
2.88k
  int32_t time_value = 0;
1168
1169
2.88k
  if (expiry_time && (timev == 0x00)) {
1170
    /* No expiry time */
1171
27
    time_value = DMP_TIME_NOT_PRESENT;
1172
2.85k
  } else if (timev <= 0x1D) {
1173
    /* Number of 2-second units (2-58 seconds) */
1174
1.92k
    time_value = timev * 2;
1175
1.92k
  } else if (timev <= 0x91) {
1176
    /* Number of 15-second units (1 min - 29 min 45 sec) */
1177
624
    time_value = (timev - 0x1D + 3) * 15;
1178
624
  } else if (timev <= 0xBB) {
1179
    /* Number of 5-minute units (30 min - 3 hours 55 min) */
1180
73
    time_value = (timev - 0x91 + 5) * 5*60;
1181
233
  } else if (timev <= 0xE3) {
1182
    /* Number of 30-minute units (4 hours - 23 hours 30 min) */
1183
92
    time_value = (timev - 0xBB + 7) * 30*60;
1184
141
  } else if (timev < 0xFF) {
1185
    /* Number of 2-hour units (24 - 78 hours) */
1186
88
    time_value = (timev - 0xE3 + 11) * 2*3600;
1187
88
  } else {
1188
    /* Reserved */
1189
53
    time_value = DMP_TIME_RESERVED;
1190
53
  }
1191
1192
2.88k
  return time_value;
1193
2.88k
}
1194
1195
static int32_t dmp_dec_exp_time (uint8_t expiry_time)
1196
141
{
1197
141
  return dmp_dec_exp_del_time (expiry_time, true);
1198
141
}
1199
1200
static int32_t dmp_dec_del_time (uint8_t delivery_time)
1201
2.73k
{
1202
2.73k
  return dmp_dec_exp_del_time (delivery_time, false);
1203
2.73k
}
1204
1205
/* Ref chapter 6.3.7.2.11 DTG */
1206
static int32_t dmp_dec_dtg (uint32_t dtg)
1207
106
{
1208
106
  int32_t value;
1209
1210
106
  if (dtg == 0x00) {
1211
    /* Not present */
1212
15
    value = DMP_TIME_NOT_PRESENT;
1213
91
  } else if (dtg <= 0x3C) {
1214
    /* Number of minutes (0-59 min) */
1215
34
    value = (dtg - 1) * 60;
1216
57
  } else if (dtg <= 0x64) {
1217
    /* Number of 15-minute units (1 hour - 10 hours 45 min) */
1218
44
    value = (dtg - 0x3C + 3) * 15 * 60;
1219
44
  } else if (dtg < 0x7F) {
1220
    /* Number of hours (11-36 hours) */
1221
8
    value = (dtg - 0x64 + 10) * 3600;
1222
8
  } else {
1223
    /* Reserved */
1224
5
    value = DMP_TIME_RESERVED;
1225
5
  }
1226
1227
106
  return value;
1228
106
}
1229
1230
/*
1231
 * Ref chapter 7.10.11.1 Submission time
1232
 *
1233
 * start_time                 (current time)
1234
 * delta1     = E             (encoded submission time)
1235
 * delta2     = C             (encoded current time)
1236
 * 0x01C2     = Pn + 15min    (maximum point for S1)
1237
 * 0x7E38     = Pn+1 - 15min  (minimum point for S3)
1238
 * 0x7FF8     = Pn+1          (length of P (period))
1239
 */
1240
static int32_t dmp_dec_subm_time (uint16_t delta1, int32_t start_time)
1241
456
{
1242
456
  int32_t subm_time = start_time;
1243
456
  uint16_t delta2;
1244
1245
456
  delta2 = (uint16_t) ((subm_time / 2) % 0x7FF8);
1246
1247
456
  if ((delta1 < 0x01C2) && (delta2 >= delta1 + 0x7E38)) {
1248
0
    subm_time += 2 * (0x7FF8 - delta2 + delta1);
1249
456
  } else if ((delta1 >= 0x01C2) && (delta2 < delta1 - 0x01C2)) {
1250
307
    subm_time -= 2 * (0x7FF8 - delta1 + delta2);
1251
307
  } else {
1252
149
    subm_time -= 2 * (delta2 - delta1);
1253
149
  }
1254
1255
456
  return subm_time;
1256
456
}
1257
1258
/* Ref chapter 6.3.7.2.12 SIC */
1259
static bool dmp_dec_xbyte_sic (uint64_t bin, char *sic,
1260
                                   uint8_t no_char, bool any)
1261
393
{
1262
393
  bool failure = false;
1263
393
  double   multiplier;
1264
393
  uint8_t  i;
1265
393
  uint64_t p, tmp;
1266
1267
393
  if (no_char >= MAX_SIC_LEN) {
1268
    /* Illegal length */
1269
0
    snprintf (sic, MAX_SIC_LEN, "Illegal length: %d", no_char);
1270
0
    return true;
1271
0
  }
1272
1273
393
  if (any) {
1274
275
    multiplier = 74.0;
1275
275
  } else {
1276
118
    multiplier = 36.0;
1277
118
  }
1278
1279
2.11k
  for (i = 0; i < no_char; i++) {
1280
1.71k
    p = (uint64_t) pow (multiplier, no_char - 1 - i);
1281
1.71k
    tmp = bin / p;
1282
1.71k
    bin -= tmp * p;
1283
1.71k
    sic[i] = (char) tmp;
1284
1.71k
    if (sic[i] <= 9) {
1285
370
      sic[i] += '0';
1286
1.34k
    } else if (sic[i] <= 35) {
1287
556
      sic[i] += ('A' - 10);
1288
793
    } else if (!any) {
1289
31
      sic[i] = '*';
1290
31
      failure = true;
1291
762
    } else if (sic[i] <= 61) {
1292
493
      sic[i] += ('a' - 36);
1293
493
    } else if (sic[i] == 62) {
1294
17
      sic[i] = '\'';
1295
252
    } else if (sic[i] == 63) {
1296
19
      sic[i] = '(';
1297
233
    } else if (sic[i] == 64) {
1298
19
      sic[i] = ')';
1299
214
    } else if (sic[i] == 65) {
1300
11
      sic[i] = '+';
1301
203
    } else if (sic[i] == 66) {
1302
16
      sic[i] = ',';
1303
187
    } else if (sic[i] == 67) {
1304
21
      sic[i] = '-';
1305
166
    } else if (sic[i] == 68) {
1306
18
      sic[i] = '.';
1307
148
    } else if (sic[i] == 69) {
1308
9
      sic[i] = '/';
1309
139
    } else if (sic[i] == 70) {
1310
9
      sic[i] = ':';
1311
130
    } else if (sic[i] == 71) {
1312
13
      sic[i] = '=';
1313
117
    } else if (sic[i] == 72) {
1314
22
      sic[i] = '?';
1315
95
    } else if (sic[i] == 73) {
1316
15
      sic[i] = ' ';
1317
80
    } else {
1318
80
      sic[i] = '*';
1319
80
      failure = true;
1320
80
    }
1321
1.71k
    if (!g_ascii_isprint(sic[i])) {
1322
11
      sic[i] = '*';
1323
11
      failure = true;
1324
11
    }
1325
1.71k
  }
1326
393
  sic[i] = '\0';
1327
1328
393
  return failure;
1329
393
}
1330
1331
static unsigned dmp_id_hash (const void *k)
1332
462
{
1333
462
  const dmp_id_key *dmpx=(const dmp_id_key *)k;
1334
462
  return dmpx->id;
1335
462
}
1336
1337
static int dmp_id_hash_equal (const void *k1, const void *k2)
1338
190
{
1339
190
  const dmp_id_key *dmp1=(const dmp_id_key *)k1;
1340
190
  const dmp_id_key *dmp2=(const dmp_id_key *)k2;
1341
190
  if (dmp1->id != dmp2->id)
1342
0
    return 0;
1343
1344
190
  return (addresses_equal (&dmp1->src, &dmp2->src) &&
1345
190
          addresses_equal (&dmp1->dst, &dmp2->dst));
1346
190
}
1347
1348
static void register_dmp_id (packet_info *pinfo, uint8_t reason)
1349
260
{
1350
260
  dmp_id_val *dmp_data = NULL, *pkg_data = NULL;
1351
260
  dmp_id_key *dmp_key = NULL;
1352
260
  nstime_t    msg_time;
1353
260
  unsigned    msg_id = 0;
1354
1355
260
  if (pinfo->flags.in_error_pkt) {
1356
    /* No analysis of error packets */
1357
0
    return;
1358
0
  }
1359
1360
260
  nstime_set_zero(&msg_time);
1361
1362
260
  dmp_key = wmem_new (wmem_file_scope(), dmp_id_key);
1363
1364
260
  if (!pinfo->fd->visited &&
1365
260
      (dmp.msg_type == REPORT || dmp.msg_type == NOTIF))
1366
116
  {
1367
    /* Try to match corresponding message */
1368
116
    dmp_key->id = (unsigned) dmp.subj_id;
1369
116
    copy_address_wmem(wmem_file_scope(), &dmp_key->src, &(pinfo->dst));
1370
116
    copy_address_wmem(wmem_file_scope(), &dmp_key->dst, &(pinfo->src));
1371
1372
116
    dmp_data = (dmp_id_val *) wmem_map_lookup (dmp_id_hash_table, dmp_key);
1373
1374
116
    if (dmp_data) {
1375
      /* Found message */
1376
54
      if (dmp_data->prev_msg_id > 0) {
1377
50
        msg_id = dmp_data->prev_msg_id;
1378
50
      } else {
1379
4
        msg_id = dmp_data->msg_id;
1380
4
      }
1381
54
      msg_time = dmp_data->msg_time;
1382
54
    }
1383
116
  }
1384
1385
260
  if (dmp.msg_type == ACK) {
1386
44
    dmp_key->id = (unsigned) dmp.subj_id;
1387
44
    copy_address_wmem(wmem_file_scope(), &dmp_key->src, &(pinfo->dst));
1388
44
    copy_address_wmem(wmem_file_scope(), &dmp_key->dst, &(pinfo->src));
1389
216
  } else {
1390
216
    dmp_key->id = (unsigned) dmp.msg_id;
1391
216
    copy_address_wmem(wmem_file_scope(), &dmp_key->src, &(pinfo->src));
1392
216
    copy_address_wmem(wmem_file_scope(), &dmp_key->dst, &(pinfo->dst));
1393
216
  }
1394
1395
260
  dmp_data = (dmp_id_val *) wmem_map_lookup (dmp_id_hash_table, dmp_key);
1396
1397
260
  if (!pinfo->fd->visited) {
1398
260
    if (dmp_data) {
1399
136
      if (dmp.msg_type == ACK) {
1400
        /* Only save this data if positive ack */
1401
15
        if (reason == 0) {
1402
6
          if (dmp_data->ack_id == 0) {
1403
            /* Only save reference to first ACK */
1404
2
            dmp_data->ack_id = pinfo->num;
1405
4
          } else {
1406
            /* Only count when resending */
1407
4
            dmp_data->ack_resend_count++;
1408
4
          }
1409
6
        }
1410
121
      } else {
1411
        /* Message resent */
1412
121
        dmp_data->msg_resend_count++;
1413
121
        dmp_data->prev_msg_id = pinfo->num;
1414
121
        dmp_data->prev_msg_time = dmp_data->msg_time;
1415
121
        dmp_data->msg_time = pinfo->abs_ts;
1416
121
      }
1417
136
    } else {
1418
      /* New message */
1419
124
      dmp_data = wmem_new0 (wmem_file_scope(), dmp_id_val);
1420
124
      dmp_data->msg_type = dmp.msg_type;
1421
1422
124
      if (dmp.msg_type == ACK) {
1423
        /* No matching message for this ack */
1424
29
        dmp_data->ack_id = pinfo->num;
1425
95
      } else {
1426
95
        dmp_data->first_msg_time = pinfo->abs_ts;
1427
95
        dmp_data->msg_time = pinfo->abs_ts;
1428
1429
95
        if (dmp.msg_type == REPORT) {
1430
37
          dmp_data->rep_id = pinfo->num;
1431
37
          dmp_data->msg_id = msg_id;
1432
37
          dmp_data->rep_not_msg_time = msg_time;
1433
58
        } else if (dmp.msg_type == NOTIF) {
1434
13
          dmp_data->not_id = pinfo->num;
1435
13
          dmp_data->msg_id = msg_id;
1436
13
          dmp_data->rep_not_msg_time = msg_time;
1437
45
        } else {
1438
45
          dmp_data->msg_id = pinfo->num;
1439
45
        }
1440
1441
95
        wmem_map_insert (dmp_id_hash_table, dmp_key, dmp_data);
1442
95
      }
1443
124
    }
1444
1445
260
    pkg_data = wmem_new (wmem_file_scope(), dmp_id_val);
1446
260
    *pkg_data = *dmp_data;
1447
260
    p_add_proto_data(wmem_file_scope(), pinfo, proto_dmp, 0, pkg_data);
1448
260
  } else {
1449
    /* Fetch last values from data saved in packet */
1450
0
    pkg_data = (dmp_id_val *)p_get_proto_data(wmem_file_scope(), pinfo, proto_dmp, 0);
1451
1452
0
    if (dmp_data && pkg_data && dmp.msg_type != ACK && pkg_data->ack_id == 0) {
1453
0
      pkg_data->ack_id = dmp_data->ack_id;
1454
0
    }
1455
0
  }
1456
1457
260
  DISSECTOR_ASSERT (pkg_data);
1458
260
  dmp.id_val = pkg_data;
1459
260
}
1460
1461
static void dmp_add_seq_ack_analysis (tvbuff_t *tvb, packet_info *pinfo,
1462
                                      proto_tree *dmp_tree, int offset)
1463
133
{
1464
133
  proto_tree *analysis_tree = NULL;
1465
133
  proto_item *en = NULL, *eh = NULL;
1466
133
  nstime_t    ns;
1467
1468
133
  if (dmp.msg_type > ACK || (dmp.msg_type < ACK && !dmp.checksum) ||
1469
41
      dmp.id_val == NULL || pinfo->flags.in_error_pkt)
1470
92
  {
1471
    /* No need for seq/ack analysis */
1472
92
    return;
1473
92
  }
1474
1475
41
  analysis_tree = proto_tree_add_subtree(dmp_tree, tvb, 0, 0, ett_analysis, &en, "SEQ/ACK analysis");
1476
41
  proto_item_set_generated (en);
1477
1478
41
  if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
1479
27
      (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF)) {
1480
26
    if (dmp.id_val->ack_id) {
1481
3
      en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_num, tvb,
1482
3
                                0, 0, dmp.id_val->ack_id);
1483
3
      proto_item_set_generated (en);
1484
3
      if (!dmp.checksum) {
1485
0
        proto_item_append_text (en, " (unexpected)");
1486
0
        expert_add_info(pinfo, en, &ei_analysis_ack_unexpected);
1487
0
      }
1488
23
    } else if (dmp.checksum && !dmp.id_val->msg_resend_count) {
1489
17
      en = proto_tree_add_item (analysis_tree, hf_analysis_ack_missing, tvb, offset, 0, ENC_NA);
1490
17
      if (pinfo->fd->visited) {
1491
        /* We do not know this on first visit and we do not want to
1492
           add a entry in the "Expert Severity Info" for this note */
1493
0
        expert_add_info(pinfo, en, &ei_analysis_ack_missing);
1494
0
        proto_item_set_generated (en);
1495
0
      }
1496
17
    }
1497
1498
26
    if (dmp.msg_type == REPORT) {
1499
4
      if (dmp.id_val->msg_id) {
1500
1
        en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_num,
1501
1
                                  tvb, 0, 0, dmp.id_val->msg_id);
1502
1
        proto_item_set_generated (en);
1503
1504
1
        nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->rep_not_msg_time);
1505
1
        en = proto_tree_add_time (analysis_tree, hf_analysis_rep_time,
1506
1
                                  tvb, 0, 0, &ns);
1507
1
        proto_item_set_generated (en);
1508
3
      } else {
1509
3
        proto_tree_add_expert (analysis_tree, pinfo, &ei_analysis_msg_missing, tvb, 0, 0);
1510
3
      }
1511
22
    } else if (dmp.msg_type == NOTIF) {
1512
8
      if (dmp.id_val->msg_id) {
1513
4
        en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_num,
1514
4
                                  tvb, 0, 0, dmp.id_val->msg_id);
1515
4
        proto_item_set_generated (en);
1516
1517
4
        nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->rep_not_msg_time);
1518
4
        en = proto_tree_add_time (analysis_tree, hf_analysis_not_time,
1519
4
                                  tvb, 0, 0, &ns);
1520
4
        proto_item_set_generated (en);
1521
4
      } else {
1522
4
        proto_tree_add_expert (analysis_tree, pinfo, &ei_analysis_msg_missing, tvb, 0, 0);
1523
4
      }
1524
8
    }
1525
1526
26
    if (dmp.id_val->msg_resend_count) {
1527
9
      en = proto_tree_add_uint (analysis_tree, hf_analysis_retrans_no,
1528
9
                                tvb, 0, 0, dmp.id_val->msg_resend_count);
1529
9
      proto_item_set_generated (en);
1530
1531
9
      expert_add_info_format(pinfo, en, &ei_analysis_retrans_no, "Retransmission #%d", dmp.id_val->msg_resend_count);
1532
1533
9
      if (dmp.msg_type == REPORT) {
1534
2
        en = proto_tree_add_uint (analysis_tree, hf_analysis_rep_resend_from,
1535
2
                                  tvb, 0, 0, dmp.id_val->rep_id);
1536
7
      } else if (dmp.msg_type == NOTIF) {
1537
3
        en = proto_tree_add_uint (analysis_tree, hf_analysis_not_resend_from,
1538
3
                                  tvb, 0, 0, dmp.id_val->not_id);
1539
4
      } else {
1540
4
        en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_resend_from,
1541
4
                                  tvb, 0, 0, dmp.id_val->msg_id);
1542
4
      }
1543
9
      proto_item_set_generated (en);
1544
1545
9
      nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->prev_msg_time);
1546
9
      en = proto_tree_add_time (analysis_tree, hf_analysis_retrans_time,
1547
9
                                tvb, 0, 0, &ns);
1548
9
      proto_item_set_generated (en);
1549
1550
9
      nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->first_msg_time);
1551
9
      eh = proto_tree_add_time (analysis_tree, hf_analysis_total_retrans_time,
1552
9
                                tvb, 0, 0, &ns);
1553
9
      proto_item_set_generated (eh);
1554
1555
9
      if (dmp.id_val->first_msg_time.secs == dmp.id_val->prev_msg_time.secs &&
1556
9
          dmp.id_val->first_msg_time.nsecs == dmp.id_val->prev_msg_time.nsecs) {
1557
        /* Time values does not differ, hide the total time */
1558
9
        proto_item_set_hidden (eh);
1559
9
      }
1560
9
    }
1561
26
  } else if (dmp.msg_type == ACK) {
1562
15
    if (dmp.id_val->msg_type != ACK) {
1563
9
      if (dmp.id_val->msg_type == REPORT) {
1564
8
        en = proto_tree_add_uint (analysis_tree, hf_analysis_acks_rep_num,
1565
8
                                  tvb, 0, 0, dmp.id_val->rep_id);
1566
8
      } else if (dmp.id_val->msg_type == NOTIF) {
1567
0
        en = proto_tree_add_uint (analysis_tree, hf_analysis_acks_not_num,
1568
0
                                  tvb, 0, 0, dmp.id_val->not_id);
1569
1
      } else {
1570
1
        en = proto_tree_add_uint (analysis_tree, hf_analysis_acks_msg_num,
1571
1
                                  tvb, 0, 0, dmp.id_val->msg_id);
1572
1
      }
1573
9
      proto_item_set_generated (en);
1574
1575
9
      nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->msg_time);
1576
9
      en = proto_tree_add_time (analysis_tree, hf_analysis_ack_time,
1577
9
                                tvb, 0, 0, &ns);
1578
9
      proto_item_set_generated (en);
1579
1580
9
      nstime_delta (&ns, &pinfo->abs_ts, &dmp.id_val->first_msg_time);
1581
9
      eh = proto_tree_add_time (analysis_tree, hf_analysis_total_time,
1582
9
                                tvb, 0, 0, &ns);
1583
9
      proto_item_set_generated (eh);
1584
1585
9
      if (dmp.id_val->first_msg_time.secs == dmp.id_val->msg_time.secs &&
1586
9
          dmp.id_val->first_msg_time.nsecs == dmp.id_val->msg_time.nsecs) {
1587
        /* Time values does not differ, hide the total time */
1588
9
        proto_item_set_hidden (eh);
1589
9
      } else {
1590
        /* Different times, add a reference to the message we have ack'ed */
1591
0
        proto_item_append_text (en, " (from frame %d)",
1592
0
                                dmp.id_val->prev_msg_id);
1593
0
      }
1594
9
    } else {
1595
6
      proto_tree_add_expert (analysis_tree, pinfo, &ei_analysis_msg_missing, tvb, 0, 0);
1596
6
    }
1597
1598
15
    if (dmp.id_val->ack_resend_count) {
1599
6
      en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_dup_no,
1600
6
                                tvb, 0, 0, dmp.id_val->ack_resend_count);
1601
6
      proto_item_set_generated (en);
1602
1603
6
      expert_add_info_format(pinfo, en, &ei_analysis_ack_dup_no, "Dup ACK #%d", dmp.id_val->ack_resend_count);
1604
1605
6
      en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_resend_from,
1606
6
                                tvb, 0, 0, dmp.id_val->ack_id);
1607
6
      proto_item_set_generated (en);
1608
6
    }
1609
15
  }
1610
41
}
1611
1612
static const char *dissect_7bit_string (tvbuff_t *tvb, wmem_allocator_t* allocator, int offset, int length, unsigned char *byte_rest)
1613
68
{
1614
68
  unsigned char *encoded, *decoded;
1615
68
  unsigned char  rest = 0, bits = 1;
1616
68
  int     len = 0, i;
1617
1618
68
  if (length <= 0) {
1619
3
    if (byte_rest) {
1620
3
      *byte_rest = '\0';
1621
3
    }
1622
3
    return "";
1623
3
  }
1624
1625
65
  encoded = (unsigned char *)tvb_memdup (allocator, tvb, offset, length);
1626
65
  decoded = (unsigned char *)wmem_alloc0 (allocator, (size_t)(length * 1.2) + 1);
1627
944
  for (i = 0; i < length; i++) {
1628
879
    decoded[len++] = encoded[i] >> bits | rest;
1629
879
    rest = (encoded[i] << (7 - bits) & 0x7F);
1630
879
    if (bits == 7) {
1631
101
      decoded[len++] = rest;
1632
101
      bits = 1;
1633
101
      rest = 0;
1634
778
    } else {
1635
778
      bits++;
1636
778
    }
1637
879
  }
1638
1639
65
  if (byte_rest) {
1640
65
    *byte_rest = rest;
1641
65
  }
1642
1643
65
  return (const char*)decoded;
1644
68
}
1645
1646
static const char *dissect_thales_mts_id (tvbuff_t *tvb, wmem_allocator_t* allocator, int offset, int length, unsigned char *byte_rest)
1647
0
{
1648
  /* Thales XOmail uses this format: "MTA-NAME/000000000000" */
1649
0
  if (length >= 7 && length <= 22) {
1650
0
    return wmem_strdup_printf (allocator, "%s/%08X%04X",
1651
0
                               dissect_7bit_string (tvb, allocator, offset, length - 6, byte_rest),
1652
0
                               tvb_get_ntohl (tvb, offset + length - 6),
1653
0
                               tvb_get_ntohs (tvb, offset + length - 2));
1654
0
  }
1655
1656
0
  return ILLEGAL_FORMAT;
1657
0
}
1658
1659
static const char *dissect_thales_ipm_id (tvbuff_t *tvb, wmem_allocator_t* allocator, int offset, int length, int modifier, unsigned char *byte_rest)
1660
0
{
1661
  /* Thales XOmail uses this format: "<prefix>0000 YYMMDDhhmmssZ" */
1662
0
  if (length >= 6 && length <= 20 && modifier >= 0 && modifier <= 2) {
1663
0
    unsigned number = tvb_get_ntohs (tvb, offset + length - 6);
1664
0
    uint8_t number_len = modifier + 2;
1665
0
    time_t timev = tvb_get_ntohl(tvb, offset + length - 4);
1666
0
    struct tm *tmp = gmtime(&timev);
1667
1668
0
    if (tmp == NULL)
1669
0
      return TIME_NOT_REPRESENTABLE;
1670
1671
0
    if (modifier == 1 && number >= 1024) {
1672
      /* The number is in the range 65536-99999 */
1673
0
      number_len = 5;
1674
0
      number += (65536 - 1024);
1675
0
    }
1676
1677
0
    return wmem_strdup_printf (allocator, "%s%0*d %02d%02d%02d%02d%02d%02dZ",
1678
0
                               (length == 6) ? "" : dissect_7bit_string (tvb, allocator, offset, length - 6, byte_rest),
1679
0
                               number_len, number,
1680
0
                               tmp->tm_year % 100, tmp->tm_mon + 1, tmp->tm_mday,
1681
0
                               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
1682
0
  }
1683
1684
0
  return ILLEGAL_FORMAT;
1685
0
}
1686
1687
/* Ref chapter 6.3.7.2.12 SIC */
1688
static int dissect_dmp_sic (tvbuff_t *tvb, packet_info *pinfo,
1689
                             proto_tree *message_tree, int offset)
1690
106
{
1691
106
  proto_tree *sic_tree = NULL, *bitmap_tree = NULL, *key_tree = NULL;
1692
106
  proto_item *sf = NULL, *bf = NULL, *kf = NULL;
1693
106
  uint64_t    value;
1694
106
  uint8_t     key, bitmap, no, i, length = 0;
1695
106
  bool        any, no_sic = false, failure = false;
1696
106
  int         bytes = 0, boffset = offset;
1697
106
  char       *sic = NULL;
1698
1699
106
  key = tvb_get_uint8 (tvb, offset);
1700
106
  sic = (char *)wmem_alloc (pinfo->pool, MAX_SIC_LEN);
1701
1702
106
  if (key <= 0xB6) {
1703
    /* 2 bytes, single 3-character SIC, characters [A-Z0-9] only */
1704
1705
24
    value = tvb_get_ntohs (tvb, offset);
1706
24
    failure = dmp_dec_xbyte_sic (value, sic, 3, false);
1707
24
    sf = proto_tree_add_string_format_value(message_tree, hf_message_sic, tvb,
1708
24
                                       offset, 2, sic,
1709
24
                                       "%s [A-Z0-9 only]%s", sic,
1710
24
                                       failure ? " (invalid)": "");
1711
24
    if (failure) {
1712
1
      expert_add_info(pinfo, sf, &ei_message_sic_illegal);
1713
1
    }
1714
24
    offset += 2;
1715
1716
82
  } else if (key <= 0xBD) {
1717
    /* 3 bytes, single 3-character SIC, any valid character */
1718
1719
5
    value = tvb_get_ntohl (tvb, offset);
1720
5
    value = (value >> 8) & 0x48FFFF;
1721
5
    failure = dmp_dec_xbyte_sic (value, sic, 3, true);
1722
5
    sf = proto_tree_add_string_format_value(message_tree, hf_message_sic, tvb,
1723
5
                                       offset, 3, sic,
1724
5
                                       "%s [any character]%s", sic,
1725
5
                                       failure ? " (invalid)": "");
1726
5
    if (failure) {
1727
4
      expert_add_info(pinfo, sf, &ei_message_sic_illegal);
1728
4
    }
1729
5
    offset += 3;
1730
1731
77
  } else if (key <= 0xBF) {
1732
    /* Reserved (not used) */
1733
1
    snprintf (sic, MAX_SIC_LEN, "Reserved");
1734
1
    no_sic = true;
1735
1736
76
  } else if (key <= 0xCF) {
1737
    /* 2 or more 3-character SICs */
1738
1739
17
    sf = proto_tree_add_item (message_tree, hf_message_sic_key, tvb, offset, 1, ENC_NA);
1740
17
    sic_tree = proto_item_add_subtree (sf, ett_message_sic);
1741
1742
17
    kf = proto_tree_add_item (sic_tree, hf_message_sic_key_values, tvb, offset, 1, ENC_BIG_ENDIAN);
1743
17
    key_tree = proto_item_add_subtree (kf, ett_message_sic_key);
1744
1745
17
    proto_tree_add_item (key_tree, hf_message_sic_key_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1746
17
    proto_tree_add_item (key_tree, hf_message_sic_key_chars, tvb, offset, 1, ENC_BIG_ENDIAN);
1747
17
    proto_tree_add_item (key_tree, hf_message_sic_key_num, tvb, offset, 1, ENC_BIG_ENDIAN);
1748
17
    offset += 1;
1749
1750
17
    any = (key & 0x08);
1751
17
    no = (key & 0x07) + 1;
1752
100
    for (i = 0; i < no; i++) {
1753
83
      if (any) {
1754
47
        value = tvb_get_ntohl (tvb, offset);
1755
47
        value = (value >> 8) & 0x48FFFF;
1756
47
        bytes = 3;
1757
47
      } else {
1758
36
        value = tvb_get_ntohs (tvb, offset);
1759
36
        bytes = 2;
1760
36
      }
1761
83
      failure = dmp_dec_xbyte_sic (value, sic, 3, any);
1762
83
      bf = proto_tree_add_string_format (sic_tree, hf_message_sic, tvb,
1763
83
                                         offset, bytes, sic,
1764
83
                                         "SIC %d: %s%s", i + 1, sic,
1765
83
                                         failure ? " (invalid)": "");
1766
83
      if (failure) {
1767
41
        expert_add_info(pinfo, bf, &ei_message_sic_illegal);
1768
41
      }
1769
83
      offset += bytes;
1770
83
    }
1771
17
    proto_item_append_text (sf, ": %d (3 %s character)", no,
1772
17
                            any ? "any" : "[A-Z0-9]");
1773
1774
59
  } else if (key <= 0xDF) {
1775
    /* 1 or more 3 to 8 character SICs */
1776
1777
53
    sf = proto_tree_add_item (message_tree, hf_message_sic_key, tvb, offset, 1, ENC_NA);
1778
53
    sic_tree = proto_item_add_subtree (sf, ett_message_sic);
1779
1780
53
    kf = proto_tree_add_item (sic_tree, hf_message_sic_key_values, tvb, offset, 1, ENC_BIG_ENDIAN);
1781
53
    key_tree = proto_item_add_subtree (kf, ett_message_sic_key);
1782
1783
53
    proto_tree_add_item (key_tree, hf_message_sic_key_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1784
53
    proto_tree_add_item (key_tree, hf_message_sic_key_chars, tvb, offset, 1, ENC_BIG_ENDIAN);
1785
53
    proto_tree_add_item (key_tree, hf_message_sic_key_num, tvb, offset, 1, ENC_BIG_ENDIAN);
1786
53
    offset += 1;
1787
1788
53
    bitmap = tvb_get_uint8 (tvb, offset);
1789
53
    bf = proto_tree_add_uint_format (sic_tree, hf_message_sic_bitmap, tvb,
1790
53
                                     offset, 1, bitmap,
1791
53
                                     "Length Bitmap: 0x%2.2x", bitmap);
1792
53
    bitmap_tree = proto_item_add_subtree (bf, ett_message_sic_bitmap);
1793
53
    proto_tree_add_item (bitmap_tree, hf_message_sic_bitmap, tvb, offset, 1, ENC_BIG_ENDIAN);
1794
1795
53
    any = (key & 0x08);
1796
53
    no = (key & 0x07) + 1;
1797
53
    offset += 1;
1798
1799
355
    for (i = 0; i < no; i++) {
1800
302
      if (bitmap & (1 << (7 - i))) {
1801
        /* 4 - 8 character */
1802
215
        key = tvb_get_uint8 (tvb, offset);
1803
215
        if (any) {
1804
          /* Any valid characters */
1805
174
          if ((key & 0xF0) == 0xA0) {        /* bit 7-4: 1010 */
1806
22
            length = 4;
1807
22
            bytes = 4;
1808
22
            value = tvb_get_ntohl (tvb, offset) & 0x0FFFFFFF;
1809
152
          } else if ((key & 0xC0) == 0xC0) { /* bit 7-4: 11xx */
1810
86
            length = 6;
1811
86
            bytes = 5;
1812
86
            value = ((uint64_t)key & 0x3F)<<32|tvb_get_ntohl (tvb, offset + 1);
1813
86
          } else if ((key & 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1814
4
            length = 7;
1815
4
            bytes = 6;
1816
4
            value = ((uint64_t)(tvb_get_ntohs (tvb, offset) & 0x0FFF)) << 32 |
1817
4
              tvb_get_ntohl (tvb, offset + 2);
1818
62
          } else if ((key & 0xF0) == 0x90) { /* bit 7-4: 1001 */
1819
14
            length = 8;
1820
14
            bytes = 7;
1821
14
            value = ((uint64_t)((tvb_get_ntohl (tvb, offset)>>8) & 0x0FFF))<<32 |
1822
14
              tvb_get_ntohl (tvb, offset + 3);
1823
48
          } else {                           /* bit 7-4: 0xxx or 1000 */
1824
48
            length = 5;
1825
48
            bytes = 4;
1826
48
            value = tvb_get_ntohl (tvb, offset);
1827
48
          }
1828
174
        } else {
1829
          /* Characters [A-Z0-9] only */
1830
41
          if ((key & 0xE0) == 0xC0) {        /* bit 7-4: 110x */
1831
14
            length = 4;
1832
14
            bytes = 3;
1833
14
            value = (tvb_get_ntohl (tvb, offset) >> 8) & 0x1FFFFF;
1834
27
          } else if ((key & 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1835
1
            length = 5;
1836
1
            bytes = 4;
1837
1
            value = tvb_get_ntohl (tvb, offset) & 0x0FFFFFFF;
1838
26
          } else if ((key & 0xE0) == 0xE0) { /* bit 7-4: 111x */
1839
4
            length = 7;
1840
4
            bytes = 5;
1841
4
            value = ((uint64_t)key & 0x1F)<<32 | tvb_get_ntohl (tvb, offset +1);
1842
22
          } else if ((key & 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1843
3
            length = 8;
1844
3
            bytes = 6;
1845
3
            value = ((uint64_t)tvb_get_ntohs (tvb, offset) & 0x0FFF) << 32 |
1846
3
              tvb_get_ntohl (tvb, offset + 2);
1847
19
          } else {                           /* bit 7-4: 0xxx or 1000 */
1848
19
            length = 6;
1849
19
            bytes = 4;
1850
19
            value = tvb_get_ntohl (tvb, offset);
1851
19
          }
1852
41
        }
1853
215
      } else {
1854
        /* 3 character */
1855
87
        if (any) {
1856
63
          value = (tvb_get_ntohl (tvb, offset) >> 8) & 0x48FFFF;
1857
63
          length = 3;
1858
63
          bytes = 3;
1859
63
        } else {
1860
24
          value = tvb_get_ntohs (tvb, offset);
1861
24
          length = 3;
1862
24
          bytes = 2;
1863
24
        }
1864
87
      }
1865
302
      failure = dmp_dec_xbyte_sic (value, sic, length, any);
1866
302
      bf = proto_tree_add_string_format (sic_tree, hf_message_sic, tvb,
1867
302
                                         offset, bytes, sic,
1868
302
                                         "SIC %d: %s (%d bytes: %" PRIx64 ")%s",
1869
302
                                         i + 1, sic, bytes, value,
1870
302
                                         failure ? " (invalid)": "");
1871
302
      if (bitmap & (1 << (7 - i))) {
1872
        /* Only if 4 - 8 character */
1873
205
        bitmap_tree = proto_item_add_subtree (bf, ett_message_sic_bits);
1874
205
        if (any) {
1875
167
          proto_tree_add_item (bitmap_tree, hf_message_sic_bits_any, tvb, offset, 1, ENC_BIG_ENDIAN);
1876
167
        } else {
1877
38
          proto_tree_add_item (bitmap_tree, hf_message_sic_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
1878
38
        }
1879
205
      }
1880
302
      if (failure) {
1881
76
        expert_add_info(pinfo, bf, &ei_message_sic_illegal);
1882
76
      }
1883
302
      offset += bytes;
1884
302
    }
1885
53
    proto_item_append_text (sf, ": %d (3-to-8 %s character)", no,
1886
53
                            any ? "any" : "[A-Z0-9]");
1887
1888
53
  } else if (key == 0xFE) {
1889
    /* No SIC */
1890
1
    snprintf (sic, MAX_SIC_LEN, "Not present");
1891
1
    no_sic = true;
1892
1893
5
  } else {
1894
    /* Resered (not used) */
1895
5
    snprintf (sic, MAX_SIC_LEN, "Reserved");
1896
5
    no_sic = true;
1897
5
  }
1898
1899
106
  if (no_sic) {
1900
    /* Not added any SIC, dump text value */
1901
6
    sf = proto_tree_add_string (message_tree, hf_message_sic, tvb, offset, 1, sic);
1902
6
    offset += 1;
1903
6
  }
1904
1905
106
  proto_item_set_len (sf, offset - boffset);
1906
1907
106
  return offset;
1908
106
}
1909
1910
/* Ref chapter 5.2.7.1 Direct Originator Encoding */
1911
static int dissect_dmp_direct_addr (tvbuff_t *tvb, packet_info *pinfo,
1912
                                     proto_tree *field_tree, proto_item *tf,
1913
                                     int offset, int rec_no,
1914
                                     int rec_ofs, int addr_type)
1915
2.24k
{
1916
2.24k
  proto_tree *addr_tree = NULL;
1917
2.24k
  proto_item *en = NULL;
1918
2.24k
  int         dir_addr;
1919
2.24k
  uint8_t     value;
1920
1921
2.24k
  value = tvb_get_uint8 (tvb, offset);
1922
2.24k
  dir_addr = (value & 0x7F);
1923
2.24k
  if (value & 0x80) {
1924
656
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address1, tvb,
1925
656
                                     offset, 1, value,
1926
656
                                     "%sDirect Address (bits 6-0): %d",
1927
656
                                     val_to_str_const (addr_type, addr_type_str, ""),
1928
656
                                     value & 0x7F);
1929
656
    addr_tree = proto_item_add_subtree (en, ett_address_direct);
1930
656
    proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
1931
656
    proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset, 1, ENC_BIG_ENDIAN);
1932
656
    offset += 1;
1933
1934
    /* Extended 1 */
1935
656
    value = tvb_get_uint8 (tvb, offset);
1936
656
    dir_addr |= ((value & 0x3F) << 7);
1937
656
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address2, tvb,
1938
656
                                     offset, 1, value,
1939
656
                                     "%sDirect Address (bits 12-7): %d",
1940
656
                                     val_to_str_const (addr_type, addr_type_str, ""),
1941
656
                                     value & 0x3F);
1942
656
    addr_tree = proto_item_add_subtree (en, ett_address_direct);
1943
656
    proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
1944
656
    en = proto_tree_add_item (addr_tree, hf_reserved_0x40, tvb, offset, 1, ENC_BIG_ENDIAN);
1945
656
    if (value & 0x40) {
1946
150
      expert_add_info(pinfo, en, &ei_reserved_value);
1947
150
    }
1948
656
    proto_tree_add_item (addr_tree, hf_addr_dir_address2, tvb, offset, 1, ENC_BIG_ENDIAN);
1949
656
    offset += 1;
1950
1951
656
    if (value & 0x80) {
1952
      /* Extended 2 */
1953
484
      value = tvb_get_uint8 (tvb, offset);
1954
484
      dir_addr |= ((value & 0x3F) << 13);
1955
484
      en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address3, tvb,
1956
484
                                       offset, 1, value,
1957
484
                                       "%sDirect Address (bits 18-13): %d",
1958
484
                                       val_to_str_const (addr_type,addr_type_str,""),
1959
484
                                       value & 0x3F);
1960
484
      addr_tree = proto_item_add_subtree (en, ett_address_direct);
1961
484
      en = proto_tree_add_item (addr_tree, hf_reserved_0xC0, tvb, offset, 1, ENC_BIG_ENDIAN);
1962
484
      if (value & 0xC0) {
1963
427
        expert_add_info(pinfo, en, &ei_reserved_value);
1964
427
      }
1965
484
      proto_tree_add_item (addr_tree, hf_addr_dir_address3, tvb, offset, 1, ENC_BIG_ENDIAN);
1966
484
      offset += 1;
1967
484
    }
1968
1969
656
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address_generated,
1970
656
                                     tvb, offset, 0, dir_addr,
1971
656
                                     "%sDirect Address: %d",
1972
656
                                     val_to_str_const (addr_type, addr_type_str, ""),
1973
656
                                     dir_addr);
1974
656
    proto_item_set_generated (en);
1975
1.59k
  } else {
1976
1.59k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address, tvb,
1977
1.59k
                                     offset, 1, value,
1978
1.59k
                                     "%sDirect Address: %d",
1979
1.59k
                                     val_to_str_const (addr_type, addr_type_str, ""),
1980
1.59k
                                     value & 0x7F);
1981
1.59k
    addr_tree = proto_item_add_subtree (en, ett_address_direct);
1982
1.59k
    proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
1983
1.59k
    proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset, 1, ENC_BIG_ENDIAN);
1984
1.59k
    offset += 1;
1985
1.59k
  }
1986
1987
2.24k
  if (rec_no != -1) {
1988
1.95k
    proto_item_append_text (tf, " %d", rec_no);
1989
1.95k
    if (rec_ofs != -1) {
1990
565
      proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
1991
565
    }
1992
1.95k
  }
1993
2.24k
  proto_item_append_text (tf, ", %sDirect Address: %d",
1994
2.24k
                          val_to_str_const (addr_type, addr_type_str, ""), dir_addr);
1995
1996
2.24k
  return offset;
1997
2.24k
}
1998
1999
/* Ref 5.3.14 Extended Address */
2000
static int dissect_dmp_ext_addr (tvbuff_t *tvb, packet_info *pinfo,
2001
                                  proto_tree *field_tree, proto_item *tf,
2002
                                  int offset, int rec_no, int rec_ofs,
2003
                                  int addr_type)
2004
722
{
2005
722
  proto_tree *addr_tree = NULL, *ext_tree = NULL;
2006
722
  proto_item *en = NULL, *ef = NULL;
2007
722
  int         type, length;
2008
722
  uint8_t     value;
2009
722
  int         boffset = offset;
2010
722
  bool        addr_length_extended = false;
2011
722
  asn1_ctx_t  asn1_ctx;
2012
2013
722
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
2014
2015
722
  value = tvb_get_uint8 (tvb, offset);
2016
722
  type = (value & 0xE0) >> 5;
2017
722
  length = (value & 0x1F);
2018
722
  ef = proto_tree_add_none_format (field_tree, hf_addr_ext_address, tvb,
2019
722
                                   offset, -1, "%sExtended Address",
2020
722
                                   val_to_str_const (addr_type, addr_type_str, ""));
2021
722
  ext_tree = proto_item_add_subtree (ef, ett_address_extended);
2022
2023
722
  en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_type, tvb,
2024
722
                                   offset, 1, value, "Address Type: %s",
2025
722
                                   val_to_str_const (type, ext_addr_type,
2026
722
                                                     "Reserved"));
2027
722
  addr_tree = proto_item_add_subtree (en, ett_address_ext_type);
2028
722
  proto_tree_add_item (addr_tree, hf_addr_ext_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2029
2030
722
  if (value & 0x80) {
2031
166
    addr_length_extended = true;
2032
166
    en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length1, tvb,
2033
166
                                     offset, 1, value,
2034
166
                                     "Address Length (bits 4-0): %d", length);
2035
166
    addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
2036
166
    proto_tree_add_item (addr_tree, hf_addr_ext_length1, tvb, offset, 1, ENC_BIG_ENDIAN);
2037
166
    offset += 1;
2038
2039
    /* Extended */
2040
166
    value = tvb_get_uint8 (tvb, offset);
2041
166
    type = ((value & 0xE0) >> 5);
2042
166
    length |= ((value & 0x1F) << 5);
2043
2044
166
    en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_type_ext, tvb,
2045
166
                                     offset, 1, value, "Address Type Ext: %s",
2046
166
                                     val_to_str_const (type, ext_addr_type_ext,
2047
166
                                                       "Reserved"));
2048
166
    addr_tree = proto_item_add_subtree (en, ett_address_ext_type);
2049
166
    proto_tree_add_item (addr_tree, hf_addr_ext_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2050
2051
166
    en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length2, tvb,
2052
166
                                     offset, 1, value,
2053
166
                                     "Address Length (bits 9-5): %d",
2054
166
                                     value & 0x1F);
2055
166
    addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
2056
166
    proto_tree_add_item (addr_tree, hf_addr_ext_length2, tvb, offset, 1, ENC_BIG_ENDIAN);
2057
166
    offset += 1;
2058
556
  } else {
2059
556
    en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length, tvb,
2060
556
                                     offset, 1, value, "Address Length: %d",
2061
556
                                     length);
2062
556
    addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
2063
556
    proto_tree_add_item (addr_tree, hf_addr_ext_length1, tvb, offset, 1, ENC_BIG_ENDIAN);
2064
556
    offset += 1;
2065
556
  }
2066
2067
722
  if (type == ASN1_BER) {
2068
93
    tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, length);
2069
2070
93
    dissect_p1_ORName (false, next_tvb, 0, &asn1_ctx, ext_tree,
2071
93
                         hf_addr_ext_asn1_ber);
2072
629
  } else if (type == ASN1_PER) {
2073
163
    proto_tree_add_item (ext_tree, hf_addr_ext_asn1_per, tvb, offset, length, ENC_NA);
2074
466
  } else {
2075
466
    proto_tree_add_item (ext_tree, hf_addr_ext_unknown, tvb, offset, length, ENC_NA);
2076
466
  }
2077
722
  offset += length;
2078
2079
722
  if (addr_length_extended) {
2080
123
    en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length_generated,
2081
123
                                     tvb, offset, 0, length,
2082
123
                                     "Address Length: %d", length);
2083
123
    proto_item_set_generated (en);
2084
123
  }
2085
2086
722
  proto_item_append_text (ef, ", Type: %s, Length: %d",
2087
722
                          val_to_str_const (type, ext_addr_type, "Reserved"),
2088
722
                          length);
2089
2090
722
  if (rec_no != -1) {
2091
628
    proto_item_append_text (tf, " %d", rec_no);
2092
628
    if (rec_ofs != -1) {
2093
149
      proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
2094
149
    }
2095
628
  }
2096
722
  proto_item_append_text (tf, ", %sExtended Address Type: %s",
2097
722
                          val_to_str_const (addr_type, addr_type_str, ""),
2098
722
                          val_to_str_const (type, ext_addr_type_short, "Reserved"));
2099
2100
722
  proto_item_set_len (ef, offset - boffset);
2101
2102
722
  return offset;
2103
722
}
2104
2105
/* Ref chapter 5.2.8.1 Extended Originator Encoding */
2106
static int dissect_dmp_originator (tvbuff_t *tvb, packet_info *pinfo,
2107
                                    proto_tree *envelope_tree, int offset)
2108
314
{
2109
314
  proto_tree *field_tree = NULL, *rec_tree = NULL;
2110
314
  proto_item *en = NULL, *tf = NULL;
2111
314
  uint8_t     value, dmp_addr_form;
2112
314
  int         boffset = offset;
2113
314
  bool        p2_addr = false;
2114
2115
314
  tf = proto_tree_add_item (envelope_tree, hf_addr_originator, tvb, offset, -1, ENC_NA);
2116
314
  field_tree = proto_item_add_subtree (tf, ett_address);
2117
2118
314
  if (dmp.addr_enc == DIRECT_ADDR) {
2119
220
    offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf,
2120
220
                                      offset, -1, -1, ORIGINATOR);
2121
220
  } else {
2122
94
    value = tvb_get_uint8 (tvb, offset);
2123
94
    dmp_addr_form = (value & 0xE0) >> 5;
2124
2125
94
    if (dmp.version == DMP_VERSION_1 && !(dmp.prot_id == PROT_NAT && dmp_nat_decode == NAT_DECODE_THALES)) {
2126
43
      en = proto_tree_add_uint_format (field_tree, hf_addr_ext_form_orig_v1, tvb,
2127
43
                                       offset, 1, value,
2128
43
                                       "Address Form: %s",
2129
43
                                       val_to_str_const (dmp_addr_form,
2130
43
                                                         addr_form_orig_v1, "Reserved"));
2131
43
      rec_tree = proto_item_add_subtree (en, ett_address_ext_form);
2132
43
      proto_tree_add_item (rec_tree, hf_addr_ext_form_orig_v1, tvb, offset, 1, ENC_BIG_ENDIAN);
2133
51
    } else {
2134
51
      en = proto_tree_add_uint_format (field_tree, hf_addr_ext_form_orig, tvb,
2135
51
                                       offset, 1, value,
2136
51
                                       "Address Form: %s",
2137
51
                                       val_to_str_const (dmp_addr_form,
2138
51
                                                         addr_form_orig, "Reserved"));
2139
51
      rec_tree = proto_item_add_subtree (en, ett_address_ext_form);
2140
51
      proto_tree_add_item (rec_tree, hf_addr_ext_form_orig, tvb, offset, 1, ENC_BIG_ENDIAN);
2141
51
    }
2142
2143
94
    en = proto_tree_add_item (rec_tree, hf_reserved_0x1F, tvb, offset, 1, ENC_BIG_ENDIAN);
2144
94
    if (value & 0x1F) {
2145
69
      expert_add_info(pinfo, en, &ei_reserved_value);
2146
69
    }
2147
94
    offset += 1;
2148
2149
94
    if (dmp.version == DMP_VERSION_1 && !(dmp.prot_id == PROT_NAT && dmp_nat_decode == NAT_DECODE_THALES)) {
2150
43
      switch (dmp_addr_form) {
2151
2152
9
      case P1_DIRECT:
2153
9
        offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree,
2154
9
                                          tf, offset, -1, -1,
2155
9
                                          ORIGINATOR);
2156
9
        break;
2157
2158
3
      case P1_EXTENDED:
2159
3
        offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset, -1,
2160
3
                                       -1, ORIGINATOR);
2161
3
        break;
2162
2163
31
      default:
2164
31
        proto_item_append_text (tf, " (invalid address form)");
2165
31
        break;
2166
2167
43
      }
2168
51
    } else {
2169
51
      switch (dmp_addr_form) {
2170
2171
16
      case P1_DIRECT:
2172
27
      case P1_P2_DIRECT:
2173
28
      case P1_DIRECT_P2_EXTENDED:
2174
28
        offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree,
2175
28
                                          tf, offset, -1, -1,
2176
28
                                          ORIGINATOR);
2177
28
        break;
2178
2179
4
      case P1_EXTENDED:
2180
6
      case P1_EXTENDED_P2_DIRECT:
2181
10
      case P1_P2_EXTENDED:
2182
10
        offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset, -1,
2183
10
                                       -1, ORIGINATOR);
2184
10
        break;
2185
2186
4
      default:
2187
4
        proto_item_append_text (tf, " (invalid address form)");
2188
4
        break;
2189
2190
51
      }
2191
2192
38
      switch (dmp_addr_form) {
2193
2194
11
      case P1_P2_DIRECT:
2195
13
      case P1_EXTENDED_P2_DIRECT:
2196
13
        offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree,
2197
13
                                          tf, offset, -1, -1,
2198
13
                                          ORIG_P2_ADDRESS);
2199
13
        p2_addr = true;
2200
13
        break;
2201
2202
1
      case P1_DIRECT_P2_EXTENDED:
2203
4
      case P1_P2_EXTENDED:
2204
4
        offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset, -1,
2205
4
                                       -1, ORIG_P2_ADDRESS);
2206
4
        p2_addr = true;
2207
4
        break;
2208
2209
38
      }
2210
38
    }
2211
2212
77
    if (p2_addr) {
2213
15
      if (dmp.msg_type == NOTIF) {
2214
5
        en = proto_tree_add_boolean (field_tree, hf_addr_int_rec, tvb,
2215
5
                                     offset, 0, true);
2216
10
      } else {
2217
10
        en = proto_tree_add_boolean (field_tree, hf_addr_dl_expanded, tvb,
2218
10
                                     offset, 0, true);
2219
10
      }
2220
15
      proto_item_set_generated (en);
2221
15
    }
2222
77
  }
2223
297
  proto_item_set_len (tf, offset - boffset);
2224
2225
297
  return offset;
2226
314
}
2227
2228
static void dmp_add_recipient_info (proto_item *tf, uint8_t rep_req,
2229
                                    uint8_t not_req, bool action)
2230
10.6k
{
2231
10.6k
  if (rep_req || not_req) {
2232
6.66k
    proto_item_append_text (tf, ", Request:");
2233
6.66k
  }
2234
10.6k
  if (rep_req) {
2235
4.88k
    proto_item_append_text (tf, "%s",
2236
4.88k
                            val_to_str_const (rep_req, report_vals_short, ""));
2237
4.88k
  }
2238
10.6k
  if (not_req) {
2239
5.03k
    dmp.notif_req = true;
2240
5.03k
    proto_item_append_text (tf, "%s",
2241
5.03k
                            val_to_str_const (not_req, notif_vals_short, ""));
2242
5.03k
  }
2243
10.6k
  if (action) {
2244
3.64k
    if (dmp.msg_type == STANAG) {
2245
1.39k
      proto_item_append_text (tf, " (Action)");
2246
2.24k
    } else if (dmp.msg_type == IPM) {
2247
657
      proto_item_append_text (tf, " (To)");
2248
657
    }
2249
7.05k
  } else {
2250
7.05k
    if (dmp.msg_type == STANAG) {
2251
1.36k
      proto_item_append_text (tf, " (Info)");
2252
5.69k
    } else if (dmp.msg_type == IPM) {
2253
998
      proto_item_append_text (tf, " (Cc)");
2254
998
    }
2255
7.05k
  }
2256
10.6k
}
2257
2258
/* Ref chapter 5.2.7 Direct Recipient Encoding */
2259
static int dissect_dmp_direct_encoding (tvbuff_t *tvb, packet_info *pinfo,
2260
                                         proto_tree *field_tree, proto_item *tf,
2261
                                         int offset, unsigned *prev_rec_no)
2262
8.57k
{
2263
2264
8.57k
  proto_tree *addr_tree = NULL, *rec_tree = NULL;
2265
8.57k
  proto_item *en = NULL;
2266
8.57k
  uint8_t     rep_req = 0, not_req = 0, value;
2267
8.57k
  int         rec_no, rec_ofs = -1, dir_addr;
2268
8.57k
  bool        action = false, dir_addr_extended = false;
2269
2270
8.57k
  value = tvb_get_uint8 (tvb, offset);
2271
8.57k
  rec_no = (value & 0xF0) >> 4;
2272
8.57k
  rep_req = (value & 0x0C) >> 2;
2273
8.57k
  not_req = (value & 0x03);
2274
2275
8.57k
  if (rep_req == 0x03) {
2276
1.65k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no1,
2277
1.65k
                                     tvb, offset, 1, value,
2278
1.65k
                                     "Recipient Number (bits 3-0): %d"
2279
1.65k
                                     " (offset from previous)",
2280
1.65k
                                     (value & 0xF0) >> 4);
2281
6.92k
  } else {
2282
6.92k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no,
2283
6.92k
                                     tvb, offset, 1, value,
2284
6.92k
                                     "Recipient Number Offset: %d"
2285
6.92k
                                     " (offset from previous)",
2286
6.92k
                                     (value & 0xF0) >> 4);
2287
6.92k
  }
2288
8.57k
  rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
2289
8.57k
  proto_tree_add_item (rec_tree, hf_addr_dir_rec_no1, tvb, offset, 1, ENC_BIG_ENDIAN);
2290
8.57k
  proto_tree_add_item (rec_tree, hf_addr_dir_rep_req1, tvb, offset, 1, ENC_BIG_ENDIAN);
2291
8.57k
  proto_tree_add_item (rec_tree, hf_addr_dir_not_req1, tvb, offset, 1, ENC_BIG_ENDIAN);
2292
8.57k
  offset += 1;
2293
2294
8.57k
  value = tvb_get_uint8 (tvb, offset);
2295
8.57k
  dir_addr = (value & 0x7F);
2296
8.57k
  action = (value & 0x80);
2297
8.57k
  if (not_req == 0x03) {
2298
1.57k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address1,
2299
1.57k
                                     tvb, offset, 1, value,
2300
1.57k
                                     "Direct Address (bits 6-0): %d",
2301
1.57k
                                     value & 0x7F);
2302
7.00k
  } else {
2303
7.00k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address,
2304
7.00k
                                     tvb, offset, 1, value,
2305
7.00k
                                     "Direct Address: %d",
2306
7.00k
                                     value & 0x7F);
2307
7.00k
  }
2308
8.57k
  addr_tree = proto_item_add_subtree (en, ett_address_direct);
2309
8.57k
  proto_tree_add_item (addr_tree, hf_addr_dir_action, tvb, offset, 1, ENC_BIG_ENDIAN);
2310
8.57k
  proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset, 1, ENC_BIG_ENDIAN);
2311
8.57k
  offset += 1;
2312
2313
8.57k
  if (rep_req == 0x03) {
2314
    /* Extended Recipient Number 1 */
2315
1.64k
    value = tvb_get_uint8 (tvb, offset);
2316
1.64k
    rec_no |= ((value & 0x3F) << 4);
2317
1.64k
    rec_ofs = rec_no;
2318
1.64k
    rep_req = (value & 0xC0) >> 6;
2319
2320
1.64k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no2,
2321
1.64k
                                     tvb, offset, 1, value,
2322
1.64k
                                     "Recipient Number (bits 9-4): %d"
2323
1.64k
                                     " (offset from previous)",
2324
1.64k
                                     value & 0x3F);
2325
1.64k
    rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
2326
1.64k
    proto_tree_add_item (rec_tree, hf_addr_dir_rep_req2, tvb, offset, 1, ENC_BIG_ENDIAN);
2327
1.64k
    proto_tree_add_item (rec_tree, hf_addr_dir_rec_no2, tvb, offset, 1, ENC_BIG_ENDIAN);
2328
1.64k
    offset += 1;
2329
2330
1.64k
    if (rep_req == 0x03) {
2331
      /* Extended Recipient Number 2 */
2332
680
      value = tvb_get_uint8 (tvb, offset);
2333
680
      rec_no |= ((value & 0x1F) << 10);
2334
680
      rec_ofs = rec_no;
2335
680
      rep_req = (value & 0xC0) >> 6;
2336
2337
680
      en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no3,
2338
680
                                       tvb, offset, 1, value,
2339
680
                                       "Recipient Number (bits 14-10): %d"
2340
680
                                       " (offset from previous)",
2341
680
                                       value & 0x1F);
2342
680
      rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
2343
680
      proto_tree_add_item (rec_tree, hf_addr_dir_rep_req3, tvb, offset, 1, ENC_BIG_ENDIAN);
2344
680
      en = proto_tree_add_item (rec_tree, hf_reserved_0x20, tvb, offset, 1, ENC_BIG_ENDIAN);
2345
680
      if (value & 0x20) {
2346
404
        expert_add_info(pinfo, en, &ei_reserved_value);
2347
404
      }
2348
680
      proto_tree_add_item (rec_tree, hf_addr_dir_rec_no3, tvb, offset, 1, ENC_BIG_ENDIAN);
2349
680
      offset += 1;
2350
680
    }
2351
1.64k
  }
2352
2353
8.57k
  if (not_req == 0x03) {
2354
    /* Extended Direct Address 1 */
2355
1.56k
    dir_addr_extended = true;
2356
1.56k
    value = tvb_get_uint8 (tvb, offset);
2357
1.56k
    dir_addr |= ((value & 0x3F) << 7);
2358
1.56k
    not_req = (value & 0xC0) >> 6;
2359
2360
1.56k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address2, tvb,
2361
1.56k
                                     offset, 1, value,
2362
1.56k
                                     "Direct Address (bits 12-7): %d",
2363
1.56k
                                     value & 0x3F);
2364
1.56k
    addr_tree = proto_item_add_subtree (en, ett_address_direct);
2365
1.56k
    proto_tree_add_item (addr_tree, hf_addr_dir_not_req2, tvb, offset, 1, ENC_BIG_ENDIAN);
2366
1.56k
    proto_tree_add_item (addr_tree, hf_addr_dir_address2, tvb, offset, 1, ENC_BIG_ENDIAN);
2367
1.56k
    offset += 1;
2368
2369
1.56k
    if (not_req == 0x03) {
2370
      /* Extended Direct Address 2 */
2371
525
      value = tvb_get_uint8 (tvb, offset);
2372
525
      dir_addr |= ((value & 0x3F) << 13);
2373
525
      not_req = (value & 0xC0) >> 6;
2374
2375
525
      en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address3, tvb,
2376
525
                                       offset, 1, value,
2377
525
                                       "Direct Address (bits 18-13): %d",
2378
525
                                       value & 0x3F);
2379
525
      addr_tree = proto_item_add_subtree (en, ett_address_direct);
2380
525
      proto_tree_add_item (addr_tree, hf_addr_dir_not_req3, tvb, offset, 1, ENC_BIG_ENDIAN);
2381
525
      proto_tree_add_item (addr_tree, hf_addr_dir_address3, tvb, offset, 1, ENC_BIG_ENDIAN);
2382
525
      offset += 1;
2383
525
    }
2384
1.56k
  }
2385
2386
8.57k
  rec_no += *prev_rec_no;
2387
8.57k
  if (dmp.version == DMP_VERSION_1 && !(dmp.prot_id == PROT_NAT && dmp_nat_decode == NAT_DECODE_THALES)) {
2388
6.23k
    rec_no++;
2389
6.23k
  }
2390
8.57k
  *prev_rec_no = rec_no;
2391
2392
8.57k
  en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no_generated,
2393
8.57k
                                   tvb, offset, 0, rec_no,
2394
8.57k
                                   "Recipient Number: %d", rec_no);
2395
8.57k
  if (rec_no > 32767) {
2396
4.20k
    proto_item_append_text (en, " (maximum 32767)");
2397
4.20k
    expert_add_info(pinfo, en, &ei_addr_ext_rec_no_generated);
2398
4.20k
  }
2399
8.57k
  proto_item_set_generated (en);
2400
2401
8.57k
  if (dir_addr_extended) {
2402
1.56k
    en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address_generated,
2403
1.56k
                                     tvb, offset, 0, dir_addr,
2404
1.56k
                                     "Direct Address: %d", dir_addr);
2405
1.56k
    proto_item_set_generated (en);
2406
1.56k
  }
2407
2408
8.57k
  proto_item_append_text (tf, " %d", rec_no);
2409
8.57k
  if (rec_ofs != -1) {
2410
1.64k
    proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
2411
1.64k
  }
2412
2413
8.57k
  proto_item_append_text (tf, ", Direct Address: %d", dir_addr);
2414
8.57k
  dmp_add_recipient_info (tf, rep_req, not_req, action);
2415
2416
8.57k
  return offset;
2417
8.57k
}
2418
2419
/* Ref 5.2.8.2 Extended Recipient Encoding */
2420
static int dissect_dmp_ext_encoding (tvbuff_t *tvb, packet_info *pinfo,
2421
                                      proto_tree *field_tree,
2422
                                      proto_item *tf, int offset,
2423
                                      unsigned *prev_rec_no)
2424
2.31k
{
2425
2.31k
  proto_tree *addr_tree = NULL;
2426
2.31k
  proto_item *en = NULL;
2427
2.31k
  uint8_t     rep_req = 0, not_req = 0;
2428
2.31k
  uint8_t     value, dmp_addr_form;
2429
2.31k
  bool        action = false;
2430
2.31k
  int         rec_no, rec_ofs = -1;
2431
2432
2.31k
  value = tvb_get_uint8 (tvb, offset);
2433
2.31k
  dmp_addr_form = (value & 0xE0) >> 5;
2434
2.31k
  action = (value & 0x10);
2435
2.31k
  en = proto_tree_add_uint_format (field_tree, hf_addr_ext_form, tvb,
2436
2.31k
                                   offset, 1, value,
2437
2.31k
                                   "Address Form: %s",
2438
2.31k
                                   val_to_str_const (dmp_addr_form,
2439
2.31k
                                                     addr_form, "Reserved"));
2440
2.31k
  addr_tree = proto_item_add_subtree (en, ett_address_ext_form);
2441
2.31k
  proto_tree_add_item (addr_tree, hf_addr_ext_form, tvb, offset, 1, ENC_BIG_ENDIAN);
2442
2443
2.31k
  en = proto_tree_add_boolean_format (field_tree, hf_addr_ext_action, tvb,
2444
2.31k
                                      offset, 1, value, "Action: %s",
2445
2.31k
                                      action ? "Yes" : "No");
2446
2.31k
  addr_tree = proto_item_add_subtree (en, ett_address_ext_action);
2447
2.31k
  proto_tree_add_item (addr_tree, hf_addr_ext_action, tvb, offset, 1, ENC_BIG_ENDIAN);
2448
2449
2.31k
  rep_req = (value & 0x0C) >> 2;
2450
2.31k
  en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rep_req, tvb,
2451
2.31k
                                   offset, 1, value,
2452
2.31k
                                   "Report Request: %s",
2453
2.31k
                                   val_to_str_const ((value & 0x0C) >> 2,
2454
2.31k
                                                     report_vals, "Reserved"));
2455
2.31k
  addr_tree = proto_item_add_subtree (en, ett_address_ext_rep_req);
2456
2.31k
  proto_tree_add_item (addr_tree, hf_addr_ext_rep_req, tvb, offset, 1, ENC_BIG_ENDIAN);
2457
2458
2.31k
  not_req = (value & 0x03);
2459
2.31k
  en = proto_tree_add_uint_format (field_tree, hf_addr_ext_not_req, tvb,
2460
2.31k
                                   offset, 1, value,
2461
2.31k
                                   "Notification Request: %s",
2462
2.31k
                                   val_to_str_const (value & 0x03,
2463
2.31k
                                                     notif_vals, "Reserved"));
2464
2.31k
  addr_tree = proto_item_add_subtree (en, ett_address_ext_not_req);
2465
2.31k
  proto_tree_add_item (addr_tree, hf_addr_ext_not_req, tvb, offset, 1, ENC_BIG_ENDIAN);
2466
2.31k
  offset += 1;
2467
2468
2.31k
  value = tvb_get_uint8 (tvb, offset);
2469
2.31k
  rec_no = (value & 0x7F);
2470
2.31k
  if (value & 0x80) {
2471
497
    en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no1, tvb,
2472
497
                                     offset, 1, value,
2473
497
                                     "Recipient Number (bits 6-0): %d"
2474
497
                                     " (offset from previous)",
2475
497
                                     value & 0x7F);
2476
497
    addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2477
497
    proto_tree_add_item (addr_tree, hf_addr_ext_rec_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
2478
497
    proto_tree_add_item (addr_tree, hf_addr_ext_rec_no1, tvb, offset, 1, ENC_BIG_ENDIAN);
2479
497
    offset += 1;
2480
2481
    /* Extended */
2482
497
    value = tvb_get_uint8 (tvb, offset);
2483
497
    rec_no |= (value << 7);
2484
497
    rec_ofs = rec_no;
2485
497
    en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no2, tvb,
2486
497
                                     offset, 1, value,
2487
497
                                     "Recipient Number (bits 14-7): %d"
2488
497
                                     " (offset from previous)", value);
2489
497
    addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2490
497
    proto_tree_add_item (addr_tree, hf_addr_ext_rec_no2, tvb, offset, 1, ENC_BIG_ENDIAN);
2491
497
    offset += 1;
2492
2493
1.81k
  } else {
2494
1.81k
    en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no, tvb,
2495
1.81k
                                     offset, 1, value,
2496
1.81k
                                     "Recipient Number Offset: %d"
2497
1.81k
                                     " (offset from previous)",
2498
1.81k
                                     value & 0x7F);
2499
1.81k
    addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2500
1.81k
    proto_tree_add_item (addr_tree, hf_addr_ext_rec_ext, tvb, offset, 1, ENC_BIG_ENDIAN);
2501
1.81k
    proto_tree_add_item (addr_tree, hf_addr_ext_rec_no1, tvb, offset, 1, ENC_BIG_ENDIAN);
2502
1.81k
    offset += 1;
2503
2504
1.81k
  }
2505
2506
2.31k
  rec_no += *prev_rec_no;
2507
2.31k
  if (dmp.version == DMP_VERSION_1 && !(dmp.prot_id == PROT_NAT && dmp_nat_decode == NAT_DECODE_THALES)) {
2508
1.15k
    rec_no++;
2509
1.15k
  }
2510
2.31k
  *prev_rec_no = rec_no;
2511
2512
2.31k
  en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no_generated,
2513
2.31k
                                   tvb, offset, 0, rec_no,
2514
2.31k
                                   "Recipient Number: %d", rec_no);
2515
2.31k
  if (rec_no > 32767) {
2516
693
    proto_item_append_text (en, " (maximum 32767)");
2517
693
    expert_add_info(pinfo, en, &ei_addr_ext_rec_no_generated);
2518
693
  }
2519
2.31k
  proto_item_set_generated (en);
2520
2521
2.31k
  switch (dmp_addr_form) {
2522
2523
806
  case P1_DIRECT:
2524
1.05k
  case P1_P2_DIRECT:
2525
1.09k
  case P1_DIRECT_P2_EXTENDED:
2526
1.09k
    offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf, offset,
2527
1.09k
                                      rec_no, rec_ofs, P1_ADDRESS);
2528
1.09k
    break;
2529
2530
132
  case P1_EXTENDED:
2531
198
  case P1_EXTENDED_P2_DIRECT:
2532
289
  case P1_P2_EXTENDED:
2533
289
    offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset,
2534
289
                                   rec_no, rec_ofs, P1_ADDRESS);
2535
289
    break;
2536
2537
2.31k
  }
2538
2539
2.22k
  switch (dmp_addr_form) {
2540
2541
581
  case P2_DIRECT:
2542
828
  case P1_P2_DIRECT:
2543
882
  case P1_EXTENDED_P2_DIRECT:
2544
882
    offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf, offset,
2545
882
                                      rec_no, rec_ofs, P2_ADDRESS);
2546
882
    break;
2547
2548
318
  case P2_EXTENDED:
2549
357
  case P1_DIRECT_P2_EXTENDED:
2550
416
  case P1_P2_EXTENDED:
2551
416
    offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset,
2552
416
                                   rec_no, rec_ofs, P2_ADDRESS);
2553
416
    break;
2554
2555
2.22k
  }
2556
2557
2.18k
  dmp_add_recipient_info (tf, rep_req, not_req, action);
2558
2559
2.18k
  return offset;
2560
2.22k
}
2561
2562
/* Ref chapter 5.2 Address encoding */
2563
static int dissect_dmp_address (tvbuff_t *tvb, packet_info *pinfo,
2564
                                 proto_tree *envelope_tree,
2565
                                 int offset, unsigned *prev_rec_no,
2566
                                 bool reporting_name)
2567
10.9k
{
2568
10.9k
  proto_tree *field_tree = NULL;
2569
10.9k
  proto_item *tf = NULL;
2570
10.9k
  int         boffset = offset;
2571
2572
10.9k
  if (reporting_name) {
2573
3.25k
    tf = proto_tree_add_item (envelope_tree, hf_addr_reporting_name, tvb, offset, -1, ENC_NA);
2574
7.69k
  } else {
2575
7.69k
    tf = proto_tree_add_none_format (envelope_tree, hf_addr_recipient, tvb,
2576
7.69k
                                     offset, -1, "Recipient Number");
2577
7.69k
  }
2578
10.9k
  field_tree = proto_item_add_subtree (tf, ett_address);
2579
2580
10.9k
  if (dmp.addr_enc == DIRECT_ADDR) {
2581
8.57k
    offset = dissect_dmp_direct_encoding (tvb, pinfo, field_tree, tf,
2582
8.57k
                                          offset, prev_rec_no);
2583
8.57k
  } else {
2584
2.37k
    offset = dissect_dmp_ext_encoding (tvb, pinfo, field_tree, tf, offset,
2585
2.37k
                                       prev_rec_no);
2586
2.37k
  }
2587
2588
10.9k
  proto_item_set_len (tf, offset - boffset);
2589
2590
10.9k
  return offset;
2591
10.9k
}
2592
2593
/* Ref chapter 6.2.9 Acknowledgement */
2594
static int dissect_dmp_ack (tvbuff_t *tvb, packet_info *pinfo,
2595
                             proto_tree *dmp_tree, int offset)
2596
46
{
2597
46
  proto_tree *ack_tree = NULL, *recip_tree = NULL;
2598
46
  proto_item *en = NULL, *rt = NULL;
2599
46
  proto_item *hidden_item;
2600
46
  unsigned    prev_rec_no = 0;
2601
46
  int         rec_len, rec_no = 0;
2602
46
  int         boffset = offset;
2603
2604
46
  en = proto_tree_add_item (dmp_tree, hf_ack, tvb, offset, 4, ENC_NA);
2605
46
  ack_tree = proto_item_add_subtree (en, ett_ack);
2606
2607
46
  dmp.ack_reason = tvb_get_uint8 (tvb, offset);
2608
46
  proto_item_append_text (en, ", Reason: %s",
2609
46
                          val_to_str_const (dmp.ack_reason, ack_reason, "Reserved"));
2610
2611
46
  rt = proto_tree_add_item (ack_tree, hf_ack_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
2612
46
  if (dmp.ack_reason != 0) {
2613
34
    expert_add_info_format(pinfo, rt, &ei_ack_reason, "ACK reason: %s", val_to_str_const (dmp.ack_reason, ack_reason, "Reserved"));
2614
34
  }
2615
46
  offset += 1;
2616
2617
46
  proto_tree_add_item (ack_tree, hf_ack_diagnostic, tvb, offset, 1, ENC_BIG_ENDIAN);
2618
46
  offset += 1;
2619
2620
  /* Subject Message Identifier */
2621
46
  dmp.subj_id = tvb_get_ntohs (tvb, offset);
2622
46
  proto_tree_add_item (ack_tree, hf_message_subj_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2623
46
  hidden_item = proto_tree_add_item (ack_tree, hf_dmp_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2624
46
  proto_item_set_hidden (hidden_item);
2625
46
  offset += 2;
2626
2627
46
  if (use_seq_ack_analysis) {
2628
44
    register_dmp_id (pinfo, dmp.ack_reason);
2629
44
  }
2630
2631
46
  if (dmp.ack_rec_present) {
2632
    /* Recipient List */
2633
42
    rec_len = tvb_reported_length (tvb);
2634
42
    if (dmp.checksum) {
2635
10
      rec_len -= 2;
2636
10
    }
2637
42
    if (offset < rec_len) {
2638
40
      rt = proto_tree_add_item (ack_tree, hf_ack_recips, tvb, offset, -1, ENC_NA);
2639
40
      recip_tree = proto_item_add_subtree (rt, ett_ack_recips);
2640
1.30k
      while (offset < rec_len) {
2641
1.26k
        offset = dissect_dmp_address (tvb, pinfo, recip_tree, offset,
2642
1.26k
                                      &prev_rec_no, false);
2643
1.26k
        rec_no++;
2644
1.26k
      }
2645
40
      proto_item_append_text (rt, ", No Recipients: %d", rec_no);
2646
40
      proto_item_set_len (rt, offset - boffset - 4);
2647
40
      proto_item_set_len (en, offset - boffset);
2648
40
    }
2649
42
  }
2650
2651
46
  return offset;
2652
46
}
2653
2654
static int dissect_mts_identifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2655
                                    int offset, bool subject)
2656
52
{
2657
52
  proto_item *ti, *hidden_item;
2658
52
  const char *mts_id;
2659
52
  unsigned char byte_rest = 0;
2660
2661
52
  if (dmp.msg_id_type == X400_MSG_ID || dmp_nat_decode == NAT_DECODE_DMP) {
2662
52
    mts_id = dissect_7bit_string (tvb, pinfo->pool, offset, dmp.mts_id_length, &byte_rest);
2663
52
  } else if (dmp_nat_decode == NAT_DECODE_THALES) {
2664
0
    mts_id = dissect_thales_mts_id (tvb, pinfo->pool, offset, dmp.mts_id_length, &byte_rest);
2665
0
  } else {
2666
0
    mts_id = tvb_bytes_to_str(pinfo->pool, tvb, offset, dmp.mts_id_length);
2667
0
  }
2668
52
  proto_item_append_text (dmp.mts_id_item, " (%zu bytes decompressed)", strlen(mts_id));
2669
52
  mts_id = format_text(pinfo->pool, mts_id, strlen(mts_id));
2670
52
  if (subject) {
2671
13
    ti = proto_tree_add_string (tree, hf_message_subj_mts_id, tvb, offset, dmp.mts_id_length, mts_id);
2672
13
    hidden_item = proto_tree_add_string (tree, hf_mts_id, tvb, offset, dmp.mts_id_length, mts_id);
2673
    /* Read from hash, for analysis */
2674
13
    dmp.subj_id = GPOINTER_TO_UINT (wmem_map_lookup (dmp_long_id_hash_table, mts_id));
2675
39
  } else {
2676
39
    ti = proto_tree_add_string (tree, hf_envelope_mts_id, tvb, offset, dmp.mts_id_length, mts_id);
2677
39
    hidden_item = proto_tree_add_string (tree, hf_mts_id, tvb, offset, dmp.mts_id_length, mts_id);
2678
    /* Insert into hash, for analysis */
2679
39
    wmem_map_insert (dmp_long_id_hash_table, wmem_strdup (wmem_file_scope(), mts_id), GUINT_TO_POINTER ((unsigned)dmp.msg_id));
2680
39
  }
2681
52
  proto_item_set_hidden (hidden_item);
2682
52
  offset += dmp.mts_id_length;
2683
2684
52
  if (byte_rest) {
2685
36
    expert_add_info (pinfo, ti, &ei_7bit_string_unused_bits);
2686
36
  }
2687
2688
52
  return offset;
2689
52
}
2690
2691
static int dissect_ipm_identifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2692
                                    int offset, bool subject)
2693
16
{
2694
16
  proto_tree *field_tree;
2695
16
  proto_item *ti, *tf, *hidden_item;
2696
16
  const char *ipm_id;
2697
16
  int         length, modifier, ipm_id_length;
2698
16
  unsigned char      byte_rest = 0;
2699
2700
16
  length = tvb_get_uint8 (tvb, offset);
2701
16
  modifier = (length & 0xC0) >> 6;
2702
16
  ipm_id_length = length & 0x3F;
2703
2704
16
  tf = proto_tree_add_uint_format (tree, hf_envelope_ipm_id_length,
2705
16
                                   tvb, offset, 1, ipm_id_length,
2706
16
                                   "IPM Identifier Length: %u",
2707
16
                                   ipm_id_length);
2708
16
  field_tree = proto_item_add_subtree (tf, ett_envelope_ipm_id_length);
2709
16
  if ((dmp.msg_id_type == NAT_MSG_ID || modifier != IPM_MODIFIER_X400) && dmp_nat_decode == NAT_DECODE_THALES) {
2710
0
    proto_tree_add_item (field_tree, hf_thales_ipm_id_modifier, tvb, offset, 1, ENC_BIG_ENDIAN);
2711
16
  } else {
2712
16
    proto_tree_add_item (field_tree, hf_envelope_ipm_id_modifier, tvb, offset, 1, ENC_BIG_ENDIAN);
2713
16
  }
2714
16
  proto_tree_add_item (field_tree, hf_envelope_ipm_id_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2715
16
  offset += 1;
2716
2717
16
  if (modifier == IPM_MODIFIER_X400 || dmp_nat_decode == NAT_DECODE_DMP) {
2718
16
    ipm_id = dissect_7bit_string (tvb, pinfo->pool, offset, ipm_id_length, &byte_rest);
2719
16
  } else if (dmp_nat_decode == NAT_DECODE_THALES) {
2720
0
    ipm_id = dissect_thales_ipm_id (tvb, pinfo->pool, offset, ipm_id_length, modifier, &byte_rest);
2721
0
  } else {
2722
0
    ipm_id = tvb_bytes_to_str(pinfo->pool, tvb, offset, ipm_id_length);
2723
0
  }
2724
16
  proto_item_append_text (tf, " (%zu bytes decompressed)", strlen(ipm_id));
2725
16
  ipm_id = format_text(pinfo->pool, ipm_id, strlen(ipm_id));
2726
16
  if (subject) {
2727
3
    ti = proto_tree_add_string (tree, hf_message_subj_ipm_id, tvb, offset, ipm_id_length, ipm_id);
2728
3
    hidden_item = proto_tree_add_string (tree, hf_ipm_id, tvb, offset, ipm_id_length, ipm_id);
2729
    /* Read from hash, for analysis */
2730
3
    dmp.subj_id = GPOINTER_TO_UINT (wmem_map_lookup (dmp_long_id_hash_table, ipm_id));
2731
13
  } else {
2732
13
    ti = proto_tree_add_string (tree, hf_envelope_ipm_id, tvb, offset, ipm_id_length, ipm_id);
2733
13
    hidden_item = proto_tree_add_string (tree, hf_ipm_id, tvb, offset, ipm_id_length, ipm_id);
2734
    /* Insert into hash, for analysis */
2735
13
    wmem_map_insert (dmp_long_id_hash_table, wmem_strdup (wmem_file_scope(), ipm_id), GUINT_TO_POINTER ((unsigned)dmp.msg_id));
2736
13
  }
2737
16
  proto_item_set_hidden (hidden_item);
2738
16
  offset += ipm_id_length;
2739
2740
16
  if (byte_rest) {
2741
8
    expert_add_info (pinfo, ti, &ei_7bit_string_unused_bits);
2742
8
  }
2743
2744
16
  return offset;
2745
16
}
2746
2747
/* Ref chapter 6.2.7 Envelope structure */
2748
static int dissect_dmp_envelope (tvbuff_t *tvb, packet_info *pinfo,
2749
                                  proto_tree *dmp_tree, int offset)
2750
545
{
2751
545
  proto_tree *envelope_tree = NULL;
2752
545
  proto_tree *field_tree = NULL;
2753
545
  proto_item *en = NULL, *tf = NULL, *vf = NULL;
2754
545
  proto_item *hidden_item;
2755
545
  uint8_t     envelope, time_diff;
2756
545
  uint16_t    subm_time, no_rec, value16;
2757
545
  int32_t     secs = 0;
2758
545
  char       *env_flags = NULL;
2759
545
  unsigned    prev_rec_no = 0;
2760
545
  int         boffset = offset, i;
2761
545
  bool        using_short_id = false;
2762
2763
545
  en = proto_tree_add_item (dmp_tree, hf_envelope, tvb, offset, 10, ENC_NA);
2764
545
  envelope_tree = proto_item_add_subtree (en, ett_envelope);
2765
2766
545
  envelope = tvb_get_uint8 (tvb, offset);
2767
545
  dmp.prot_id = (envelope & 0xF8) >> 3;
2768
545
  dmp.version = (envelope & 0x07) + 1;
2769
2770
  /* Protocol Version */
2771
545
  tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_version,
2772
545
                                   tvb, offset, 1, dmp.version,
2773
545
                                   "Protocol Version: %d", dmp.version);
2774
2775
545
  field_tree = proto_item_add_subtree (tf, ett_envelope_version);
2776
545
  vf = proto_tree_add_item (field_tree, hf_envelope_protocol_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2777
545
  if (dmp.prot_id == PROT_NAT) {
2778
27
    proto_item_append_text (vf, " (national version of DMP)");
2779
27
    proto_item_append_text (tf, " (national)");
2780
518
  } else if (dmp.prot_id == PROT_DMP) {
2781
9
    proto_item_append_text (vf, " (correct)");
2782
509
  } else {
2783
509
    proto_item_append_text (vf, " (incorrect, should be 0x1d)");
2784
509
  }
2785
545
  vf = proto_tree_add_item (field_tree, hf_envelope_version_value, tvb, offset, 1, ENC_BIG_ENDIAN);
2786
545
  offset += 1;
2787
2788
545
  if (dmp.version > DMP_VERSION_2) {
2789
    /* Unsupported DMP Version */
2790
26
    proto_item_append_text (vf, " (unsupported)");
2791
26
    proto_item_append_text (tf, " (unsupported)");
2792
26
    expert_add_info_format(pinfo, vf, &ei_envelope_version_value, "Unsupported DMP Version: %d", dmp.version);
2793
26
    return offset;
2794
26
  }
2795
2796
519
  envelope = tvb_get_uint8 (tvb, offset);
2797
519
  dmp.addr_enc = ((envelope & 0x10) >> 4);
2798
519
  dmp.checksum = ((envelope & 0x08) >> 3);
2799
519
  dmp.msg_type = (envelope & 0x07);
2800
2801
519
  if (dmp.msg_type != ACK) {
2802
    /* Hop count */
2803
469
    tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_hop_count,
2804
469
                                     tvb, offset, 1, envelope,
2805
469
                                     "Hop Count: %d", (envelope & 0xE0) >> 5);
2806
469
    field_tree = proto_item_add_subtree (tf, ett_envelope_hop_count);
2807
469
    proto_tree_add_item (field_tree, hf_envelope_hop_count_value, tvb, offset, 1, ENC_BIG_ENDIAN);
2808
469
  } else {
2809
50
    if (dmp.version >= DMP_VERSION_2) {
2810
      /* Extensions Present */
2811
23
      dmp.extensions = (envelope & 0x80);
2812
23
      tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_extensions,
2813
23
                                          tvb, offset, 1, envelope,
2814
23
                                          "Extensions: %s",
2815
23
                                          tfs_get_string(envelope & 0x80, &tfs_present_absent));
2816
23
      field_tree = proto_item_add_subtree (tf, ett_envelope_extensions);
2817
23
      proto_tree_add_item (field_tree, hf_envelope_extensions, tvb, offset, 1, ENC_BIG_ENDIAN);
2818
23
    }
2819
2820
    /* Recipient Present */
2821
50
    dmp.ack_rec_present = (envelope & 0x20);
2822
50
    tf = proto_tree_add_boolean_format (envelope_tree,hf_envelope_rec_present,
2823
50
                                        tvb, offset, 1, envelope,
2824
50
                                        "Recipient Present: %s",
2825
50
                                        tfs_get_string(envelope & 0x20, &tfs_present_absent));
2826
50
    field_tree = proto_item_add_subtree (tf, ett_envelope_rec_present);
2827
50
    proto_tree_add_item (field_tree, hf_envelope_rec_present, tvb, offset, 1, ENC_BIG_ENDIAN);
2828
50
  }
2829
2830
  /* Address Encoding */
2831
519
  tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_addr_enc,
2832
519
                                      tvb, offset, 1, envelope,
2833
519
                                      "Address Encoding: %s",
2834
519
                                      tfs_get_string(envelope & 0x10, &addr_enc));
2835
519
  field_tree = proto_item_add_subtree (tf, ett_envelope_addr_enc);
2836
519
  proto_tree_add_item (field_tree, hf_envelope_addr_enc, tvb, offset, 1, ENC_BIG_ENDIAN);
2837
2838
  /* Checksum Present */
2839
519
  tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_checksum,
2840
519
                                      tvb, offset, 1, envelope,
2841
519
                                      "Checksum: %s",
2842
519
                                      (envelope & 0x08) ? "Used" : "Not used");
2843
519
  field_tree = proto_item_add_subtree (tf, ett_envelope_checksum);
2844
519
  proto_tree_add_item (field_tree, hf_envelope_checksum, tvb, offset, 1, ENC_BIG_ENDIAN);
2845
2846
  /* Content Type */
2847
519
  tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_type,
2848
519
                                   tvb, offset, 1, envelope,
2849
519
                                   "Content Type: %s (%d)",
2850
519
                                   val_to_str_const (envelope & 0x07,
2851
519
                                                     type_vals, "Unknown"),
2852
519
                                   envelope & 0x07);
2853
519
  field_tree = proto_item_add_subtree (tf, ett_envelope_cont_type);
2854
519
  proto_tree_add_item (field_tree, hf_envelope_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2855
2856
519
  proto_item_append_text (en, ", Checksum %s", (envelope >> 3) & 0x01 ? "Used" : "Not used");
2857
519
  offset += 1;
2858
2859
519
  if (dmp.msg_type >= ACK) {
2860
59
    proto_item_set_len (en, offset - boffset);
2861
59
    return offset;
2862
59
  }
2863
2864
460
  if (dmp.version >= DMP_VERSION_2) {
2865
187
    envelope = tvb_get_uint8 (tvb, offset);
2866
    /* Extensions Present */
2867
187
    tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_extensions,
2868
187
                                        tvb, offset, 1, envelope,
2869
187
                                        "Extensions: %s",
2870
187
                                        (envelope & 0x80) ? "Present" : "Absent");
2871
187
    field_tree = proto_item_add_subtree (tf, ett_envelope_extensions);
2872
187
    proto_tree_add_item (field_tree, hf_envelope_extensions, tvb, offset, 1, ENC_BIG_ENDIAN);
2873
187
    dmp.extensions = (envelope & 0x80);
2874
2875
    /* Message Identifier Type */
2876
187
    dmp.msg_id_type = (envelope & 0x60) >> 5;
2877
187
    tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_msg_id_type,
2878
187
                                     tvb, offset, 1, envelope,
2879
187
                                     "Message Identifier Type: %s (%d)",
2880
187
                                     val_to_str_const (dmp.msg_id_type, msg_id_type_vals, "Unknown"),
2881
187
                                     dmp.msg_id_type);
2882
187
    field_tree = proto_item_add_subtree (tf, ett_envelope_msg_id_type);
2883
187
    proto_tree_add_item (field_tree, hf_envelope_msg_id_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2884
2885
187
    if (dmp.msg_id_type == X400_MSG_ID || dmp.msg_id_type == NAT_MSG_ID) {
2886
      /* MTS Identifier Length */
2887
55
      dmp.mts_id_length = (envelope & 0x1F);
2888
55
      dmp.mts_id_item = proto_tree_add_uint_format (envelope_tree, hf_envelope_mts_id_length,
2889
55
                                                    tvb, offset, 1, envelope,
2890
55
                                                    "MTS Identifier Length: %u",
2891
55
                                                    dmp.mts_id_length);
2892
55
      field_tree = proto_item_add_subtree (dmp.mts_id_item, ett_envelope_mts_id_length);
2893
55
      proto_tree_add_item (field_tree, hf_envelope_mts_id_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2894
55
      offset += 1;
2895
132
    } else {
2896
132
      proto_tree_add_item (field_tree, hf_envelope_msg_id_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2897
132
      if (envelope & 0x10) {
2898
        /* Using Short Identifier (12 bits) */
2899
39
        using_short_id = true;
2900
93
      } else {
2901
93
        tf = proto_tree_add_item (field_tree, hf_reserved_0x0F, tvb, offset, 1, ENC_BIG_ENDIAN);
2902
93
        if (envelope & 0x0F) {
2903
50
          expert_add_info(pinfo, tf, &ei_reserved_value);
2904
50
        }
2905
93
        offset += 1;
2906
93
      }
2907
132
    }
2908
187
  }
2909
2910
  /* Message Identifier */
2911
460
  dmp.msg_id = tvb_get_ntohs (tvb, offset);
2912
460
  if (using_short_id) {
2913
39
    dmp.msg_id &= 0x0FFF;
2914
39
  }
2915
460
  tf = proto_tree_add_uint (envelope_tree, hf_envelope_msg_id, tvb, offset, 2, dmp.msg_id);
2916
460
  hidden_item = proto_tree_add_uint (envelope_tree, hf_dmp_id, tvb, offset, 2, dmp.msg_id);
2917
460
  if (using_short_id) {
2918
39
    field_tree = proto_item_add_subtree (tf, ett_envelope_msg_id);
2919
39
    proto_tree_add_item (field_tree, hf_envelope_msg_id_12bit, tvb, offset, 2, ENC_BIG_ENDIAN);
2920
421
  } else if (dmp.version >= DMP_VERSION_2 && dmp.msg_id_type == ONLY_DMP_ID && dmp.msg_id < 4096) {
2921
36
    expert_add_info(pinfo, tf, &ei_envelope_msg_id);
2922
36
  }
2923
460
  proto_item_set_hidden (hidden_item);
2924
460
  offset += 2;
2925
2926
460
  if (dmp.version >= DMP_VERSION_2) {
2927
186
    if ((dmp.msg_type != REPORT) && (dmp.msg_id_type == X400_MSG_ID || dmp.msg_id_type == NAT_MSG_ID)) {
2928
39
      offset = dissect_mts_identifier (tvb, pinfo, envelope_tree, offset, false);
2929
39
    }
2930
186
  }
2931
2932
  /* Submission Time */
2933
460
  subm_time = tvb_get_ntohs (tvb, offset);
2934
460
  dmp.subm_time = dmp_dec_subm_time ((uint16_t)(subm_time & 0x7FFF),
2935
460
                                     (int32_t) pinfo->abs_ts.secs);
2936
460
  tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_subm_time, tvb,
2937
460
                                   offset, 2, subm_time,
2938
460
                                   "Submission time: %s",
2939
460
                                   (subm_time & 0x7FFF) >= 0x7FF8 ?
2940
14
                                   "Reserved" :
2941
460
                                   abs_time_secs_to_str (pinfo->pool, dmp.subm_time, ABSOLUTE_TIME_LOCAL, true));
2942
460
  field_tree = proto_item_add_subtree (tf, ett_envelope_subm_time);
2943
460
  proto_tree_add_item (field_tree, hf_envelope_time_diff_present, tvb, offset, 2, ENC_BIG_ENDIAN);
2944
460
  proto_tree_add_item (field_tree, hf_envelope_subm_time_value, tvb, offset, 2, ENC_BIG_ENDIAN);
2945
460
  offset += 2;
2946
2947
460
  if (subm_time & 0x8000) {
2948
    /* Timed Difference */
2949
143
    time_diff = tvb_get_uint8 (tvb, offset);
2950
143
    tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_time_diff,
2951
143
                                     tvb, offset, 1, time_diff,
2952
143
                                     "Time Difference: ");
2953
143
    field_tree = proto_item_add_subtree (tf, ett_envelope_time_diff);
2954
143
    proto_tree_add_item (field_tree, hf_envelope_time_diff_value, tvb, offset, 1, ENC_BIG_ENDIAN);
2955
143
    secs = dmp_dec_time_diff (time_diff);
2956
143
    if (secs == DMP_TIME_RESERVED) {
2957
40
      proto_item_append_text (tf, "Reserved (0x%2.2x)", time_diff);
2958
103
    } else {
2959
103
      proto_item_append_text (tf, "%s", signed_time_secs_to_str(pinfo->pool, secs));
2960
103
    }
2961
143
    offset += 1;
2962
143
  }
2963
2964
  /* Envelope Flags */
2965
460
  envelope = tvb_get_uint8 (tvb, offset);
2966
460
  tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_flags,
2967
460
                                   tvb, offset, 1, envelope,
2968
460
                                   "Envelope Flags");
2969
2970
460
  field_tree = proto_item_add_subtree (tf, ett_envelope_flags);
2971
460
  proto_tree_add_item (field_tree, hf_envelope_content_id_discarded, tvb, offset, 1, ENC_BIG_ENDIAN);
2972
460
  proto_tree_add_item (field_tree, hf_envelope_recip_reassign_prohib, tvb, offset, 1, ENC_BIG_ENDIAN);
2973
460
  proto_tree_add_item (field_tree, hf_envelope_dl_expansion_prohib, tvb, offset, 1, ENC_BIG_ENDIAN);
2974
2975
460
  if (envelope & 0xE0) {
2976
225
    env_flags = wmem_strdup_printf (pinfo->pool, "%s%s%s",
2977
225
                                    (envelope & 0x80) ? ", ContId discarded" : "",
2978
225
                                    (envelope & 0x40) ? ", Reass prohibited" : "",
2979
225
                                    (envelope & 0x20) ? ", DLE prohibited"   : "");
2980
225
    proto_item_append_text (tf, ":%s", &env_flags[1]);
2981
235
  } else {
2982
235
    proto_item_append_text (tf, " (none)");
2983
235
  }
2984
2985
  /* Recipient Count */
2986
460
  no_rec = (envelope & 0x1F);
2987
460
  tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_recipients,
2988
460
                                   tvb, offset, 1, envelope,
2989
460
                                   "Recipient Count: %d", no_rec);
2990
2991
460
  field_tree = proto_item_add_subtree (tf, ett_envelope_recipients);
2992
460
  proto_tree_add_item (field_tree, hf_envelope_recipients, tvb, offset, 1, ENC_BIG_ENDIAN);
2993
460
  offset += 1;
2994
2995
460
  if (no_rec == 0) {
2996
    /* Extended Recipient Count */
2997
166
    value16 = tvb_get_ntohs (tvb, offset);
2998
166
    no_rec = value16 & 0x7FFF;
2999
166
    tf = proto_tree_add_uint_format (envelope_tree,hf_envelope_ext_recipients,
3000
166
                                     tvb, offset, 2, value16,
3001
166
                                     "Extended Recipient Count: %d%s", no_rec,
3002
166
                                     (no_rec < 32 ?
3003
102
                                      " (incorrect, reserved value)" : ""));
3004
3005
166
    field_tree = proto_item_add_subtree (tf, ett_envelope_ext_recipients);
3006
166
    en = proto_tree_add_item (field_tree, hf_reserved_0x8000, tvb, offset, 2, ENC_BIG_ENDIAN);
3007
166
    if (value16 & 0x8000) {
3008
28
      expert_add_info(pinfo, en, &ei_reserved_value);
3009
28
    }
3010
166
    proto_tree_add_item (field_tree, hf_envelope_ext_recipients, tvb, offset, 2, ENC_BIG_ENDIAN);
3011
166
    offset += 2;
3012
166
  }
3013
3014
460
  if (dmp.msg_type != REPORT) {
3015
    /* Originator - Not present for reports */
3016
314
    offset = dissect_dmp_originator (tvb, pinfo, envelope_tree, offset);
3017
314
  }
3018
3019
6.88k
  for (i = 0; i < no_rec; i++) {
3020
    /* Recipient(s) */
3021
6.42k
    offset = dissect_dmp_address (tvb, pinfo, envelope_tree, offset,
3022
6.42k
                                  &prev_rec_no, false);
3023
6.42k
  }
3024
3025
460
  if (dmp.version >= DMP_VERSION_2) {
3026
119
    if ((dmp.msg_id_type == X400_MSG_ID || dmp.msg_id_type == NAT_MSG_ID) &&
3027
30
        dmp.notif_req && (dmp.msg_type == STANAG || dmp.msg_type == IPM))
3028
13
    {
3029
13
      offset = dissect_ipm_identifier (tvb, pinfo, envelope_tree, offset, false);
3030
13
    }
3031
119
  }
3032
3033
460
  proto_item_set_len (en, offset - boffset);
3034
3035
460
  return offset;
3036
519
}
3037
3038
/*
3039
 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3040
 * and chapter 6.3.8.1 IPM 88 message structure
3041
 */
3042
static int dissect_dmp_message (tvbuff_t *tvb, packet_info *pinfo,
3043
                                 proto_tree *dmp_tree, int offset)
3044
100
{
3045
100
  tvbuff_t   *body_tvb = NULL;
3046
100
  proto_tree *message_tree = NULL;
3047
100
  proto_tree *field_tree = NULL;
3048
100
  proto_item *en = NULL, *tf = NULL, *tr = NULL;
3049
100
  uint8_t     message, eit = 0, compr_alg = ALGORITHM_NONE;
3050
100
  int         len, boffset = offset, body_offset = 0, body_len = 0;
3051
3052
100
  en = proto_tree_add_item (dmp_tree, hf_message_body, tvb, offset, -1, ENC_NA);
3053
100
  message_tree = proto_item_add_subtree (en, ett_message);
3054
3055
100
  if (dmp.body_format == FREE_TEXT_SUBJECT) {
3056
24
    len = tvb_strsize (tvb, offset);
3057
24
    proto_tree_add_item (message_tree, hf_message_subject, tvb, offset, len, ENC_ASCII);
3058
24
    offset += len;
3059
24
  }
3060
3061
100
  if (dmp.body_format == FREE_TEXT || dmp.body_format == FREE_TEXT_SUBJECT) {
3062
56
    message = tvb_get_uint8 (tvb, offset);
3063
56
    eit = (message & 0xE0) >> 5;
3064
56
    compr_alg = (message & 0x18) >> 3;
3065
    /* Encoded Information Type */
3066
56
    tf = proto_tree_add_uint_format (message_tree, hf_message_eit,
3067
56
                                     tvb, offset, 1, message, "EIT: %s (%d)",
3068
56
                                     val_to_str_const (eit, eit_vals, "Unknown"),
3069
56
                                     eit);
3070
56
    field_tree = proto_item_add_subtree (tf, ett_message_eit);
3071
56
    proto_tree_add_item (field_tree, hf_message_eit, tvb, offset, 1, ENC_BIG_ENDIAN);
3072
56
    proto_item_append_text (en, ", Type: %s",
3073
56
                            val_to_str_const (eit, eit_vals, "Unknown"));
3074
3075
    /* Compression Algorithm */
3076
56
    tf = proto_tree_add_uint_format (message_tree, hf_message_compr,
3077
56
                                     tvb, offset, 1, message,
3078
56
                                     "Compression Algorithm: %s (%d)",
3079
56
                                     val_to_str_const (compr_alg, compression_vals, "Unknown"),
3080
56
                                     compr_alg);
3081
56
    field_tree = proto_item_add_subtree (tf, ett_message_compr);
3082
56
    tr = proto_tree_add_item (field_tree, hf_message_compr, tvb, offset, 1, ENC_BIG_ENDIAN);
3083
56
    if (compr_alg == ALGORITHM_ZLIB) {
3084
13
      proto_item_append_text (en, " (compressed)");
3085
43
    } else if (compr_alg != ALGORITHM_NONE) {
3086
19
      expert_add_info(pinfo, tr, &ei_message_compr);
3087
19
    }
3088
3089
56
    if (message & 0x07) {
3090
      /* Reserved */
3091
35
      tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x07,
3092
35
                                       tvb, offset, 1, message,
3093
35
                                       "Reserved: %d",  message & 0x07);
3094
35
      field_tree = proto_item_add_subtree (tf, ett_message_body_reserved);
3095
35
      tf = proto_tree_add_item (field_tree, hf_reserved_0x07, tvb, offset, 1, ENC_BIG_ENDIAN);
3096
35
      expert_add_info(pinfo, tf, &ei_reserved_value);
3097
35
    }
3098
56
    offset += 1;
3099
56
  }
3100
3101
100
  len = tvb_reported_length_remaining (tvb, offset);
3102
100
  if (dmp.checksum) {
3103
15
    len -= 2;
3104
15
    if (len < 0) {
3105
1
      THROW_MESSAGE(ReportedBoundsError, "Packet length too short");
3106
1
    }
3107
15
  }
3108
3109
100
  if (compr_alg == ALGORITHM_ZLIB) {
3110
13
    tf = proto_tree_add_item (message_tree, hf_message_body_compressed,
3111
13
                              tvb, offset, len, ENC_NA);
3112
13
    proto_item_append_text (tf, ", Length: %d", len);
3113
87
  } else {
3114
87
    tf = proto_tree_add_item (message_tree, hf_message_body_data,
3115
87
                              tvb, offset, len, ENC_NA);
3116
87
    proto_item_set_text (tf, "User data, Length: %d", len);
3117
87
  }
3118
3119
100
  if (dmp.body_format == STRUCTURED) {
3120
    /* Structured Message ID */
3121
11
    field_tree = proto_item_add_subtree (tf, ett_message_body);
3122
11
    proto_tree_add_item (field_tree, hf_message_body_structured, tvb, offset, len, ENC_NA);
3123
89
  } else if (len > 0 && (dmp.body_format == FREE_TEXT ||
3124
52
                         dmp.body_format == FREE_TEXT_SUBJECT)) {
3125
52
    if (compr_alg == ALGORITHM_ZLIB) {
3126
10
      if ((body_tvb = tvb_child_uncompress_zlib(tvb, tvb, offset, len)) != NULL) {
3127
1
        body_len = tvb_captured_length (body_tvb);
3128
1
        add_new_data_source (pinfo, body_tvb, "Uncompressed User data");
3129
1
        tf = proto_tree_add_item (message_tree, hf_message_body_data,
3130
1
                                  body_tvb, 0, body_len, ENC_NA);
3131
1
        proto_item_set_text (tf, "User data, Length: %d", body_len);
3132
1
        proto_item_set_generated (tf);
3133
9
      } else {
3134
9
        proto_tree_add_expert (message_tree, pinfo, &ei_message_body_uncompress, tvb, offset, len);
3135
9
      }
3136
42
    } else {
3137
42
      body_tvb = tvb;
3138
42
      body_offset = offset;
3139
42
      body_len = len;
3140
42
    }
3141
3142
52
    if (eit != EIT_BILATERAL && body_len > 0) {
3143
39
      field_tree = proto_item_add_subtree (tf, ett_message_body);
3144
39
      proto_tree_add_item (field_tree, hf_message_body_plain, body_tvb,
3145
39
                           body_offset, body_len, ENC_ASCII);
3146
39
    }
3147
52
  }
3148
100
  offset += len;
3149
3150
100
  proto_item_set_len (en, offset - boffset);
3151
3152
100
  return offset;
3153
100
}
3154
3155
/* Ref chapter 6.3.9.1 Report structure */
3156
static int dissect_dmp_report (tvbuff_t *tvb, packet_info *pinfo,
3157
                                proto_tree *dmp_tree, int offset,
3158
                                unsigned *prev_rec_no, int num)
3159
3.25k
{
3160
3.25k
  proto_tree *report_tree = NULL;
3161
3.25k
  proto_tree *field_tree = NULL;
3162
3.25k
  proto_item *en = NULL, *ei = NULL, *tf = NULL;
3163
3.25k
  uint8_t     report;
3164
3.25k
  bool        info_present;
3165
3.25k
  int32_t     secs = 0;
3166
3.25k
  int         len, boffset = offset;
3167
3.25k
  int         rep_type = 0;
3168
3169
3.25k
  report = tvb_get_uint8 (tvb, offset);
3170
3.25k
  rep_type = (report & 0x80) >> 7;
3171
3.25k
  if (rep_type) {
3172
516
    en = proto_tree_add_item (dmp_tree, hf_non_delivery_report, tvb, offset, 4, ENC_NA);
3173
2.74k
  } else {
3174
2.74k
    en = proto_tree_add_item (dmp_tree, hf_delivery_report, tvb, offset, 4, ENC_NA);
3175
2.74k
  }
3176
3.25k
  proto_item_append_text (en, " (#%d)", num);
3177
3178
3.25k
  report_tree = proto_item_add_subtree (en, ett_report);
3179
3180
  /* Report Type */
3181
3.25k
  tf = proto_tree_add_boolean_format (report_tree, hf_report_type,
3182
3.25k
                                      tvb, offset, 1, report,
3183
3.25k
                                      "Report Type: %s",
3184
3.25k
                                      tfs_get_string(rep_type, &report_type));
3185
3.25k
  field_tree = proto_item_add_subtree (tf, ett_report_type);
3186
3.25k
  proto_tree_add_item (field_tree, hf_report_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3187
3188
3.25k
  if (rep_type == DR) {
3189
2.74k
    dmp.dr = true;
3190
    /* Info Present */
3191
2.74k
    info_present = (report & 0x40);
3192
2.74k
    tf = proto_tree_add_boolean_format (report_tree,hf_report_info_present_dr,
3193
2.74k
                                        tvb, offset, 1, report,
3194
2.74k
                                        "Info Present: %s",
3195
2.74k
                                        tfs_get_string(report & 0x40, &tfs_present_absent));
3196
2.74k
    field_tree = proto_item_add_subtree (tf, ett_report_info_present_dr);
3197
2.74k
    proto_tree_add_item (field_tree, hf_report_info_present_dr, tvb, offset, 1, ENC_BIG_ENDIAN);
3198
3199
    /* Address Encoding */
3200
2.74k
    dmp.addr_enc = ((report & 0x20) >> 5);
3201
2.74k
    tf = proto_tree_add_boolean_format (report_tree, hf_report_addr_enc_dr,
3202
2.74k
                                        tvb, offset, 1, report,
3203
2.74k
                                        "Address Encoding: %s",
3204
2.74k
                                        tfs_get_string(report & 0x20, &addr_enc));
3205
2.74k
    field_tree = proto_item_add_subtree (tf, ett_report_addr_enc_dr);
3206
2.74k
    proto_tree_add_item (field_tree, hf_report_addr_enc_dr, tvb, offset, 1, ENC_BIG_ENDIAN);
3207
3208
2.74k
    if (report & 0x1F) {
3209
      /* Reserved */
3210
1.08k
      tf = proto_tree_add_uint_format (report_tree, hf_reserved_0x1F,
3211
1.08k
                                       tvb, offset, 1, report,
3212
1.08k
                                       "Reserved: %d", report & 0x1F);
3213
1.08k
      field_tree = proto_item_add_subtree (tf, ett_report_reserved);
3214
1.08k
      tf = proto_tree_add_item (field_tree, hf_reserved_0x1F, tvb, offset, 1, ENC_BIG_ENDIAN);
3215
1.08k
      expert_add_info(pinfo, tf, &ei_reserved_value);
3216
3217
1.08k
    }
3218
2.74k
    offset += 1;
3219
3220
    /* Delivery Time */
3221
2.74k
    report = tvb_get_uint8 (tvb, offset);
3222
2.74k
    tf = proto_tree_add_uint_format (report_tree, hf_report_del_time,
3223
2.74k
                                     tvb, offset, 1, report,
3224
2.74k
                                     "Delivery Time: ");
3225
2.74k
    field_tree = proto_item_add_subtree (tf, ett_report_del_time);
3226
2.74k
    ei = proto_tree_add_item (field_tree, hf_report_del_time_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3227
2.74k
    secs = dmp_dec_del_time (report);
3228
2.74k
    if (secs == DMP_TIME_RESERVED) {
3229
41
      proto_item_append_text (tf, "Reserved (0x%2.2x)", report);
3230
41
      proto_item_append_text (ei, " (Reserved)");
3231
2.69k
    } else {
3232
2.69k
      proto_item_append_text (tf, "%s (%s)", signed_time_secs_to_str(pinfo->pool, secs),
3233
2.69k
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time - secs, ABSOLUTE_TIME_LOCAL, true));
3234
2.69k
      proto_item_append_text (ei, " (%s from submission time)", signed_time_secs_to_str(pinfo->pool, secs));
3235
2.69k
    }
3236
2.74k
  } else {
3237
516
    dmp.ndr = true;
3238
    /* Address Encoding */
3239
516
    dmp.addr_enc = ((report & 0x40) >> 6);
3240
516
    tf = proto_tree_add_boolean_format (report_tree, hf_report_addr_enc_ndr,
3241
516
                                        tvb, offset, 1, report,
3242
516
                                        "Address Encoding: %s",
3243
516
                                        tfs_get_string(report & 0x40, &addr_enc));
3244
516
    field_tree = proto_item_add_subtree (tf, ett_report_addr_enc_ndr);
3245
516
    proto_tree_add_item (field_tree, hf_report_addr_enc_ndr, tvb, offset, 1, ENC_BIG_ENDIAN);
3246
3247
    /* Reason */
3248
516
    tf = proto_tree_add_uint_format (report_tree, hf_report_reason,
3249
516
                                     tvb, offset, 1, report,
3250
516
                                     "Reason%s: %s (%d)",
3251
516
                                     ((report & 0x3F) < 0x3D) ? " (P1)":"",
3252
516
                                     non_del_reason_str (report & 0x3F),
3253
516
                                     report & 0x3F);
3254
516
    field_tree = proto_item_add_subtree (tf, ett_report_reason);
3255
516
    proto_tree_add_item (field_tree, hf_report_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
3256
516
    offset += 1;
3257
3258
    /* Info Present */
3259
516
    report = tvb_get_uint8 (tvb, offset);
3260
516
    info_present = (report & 0x80);
3261
516
    tf = proto_tree_add_boolean_format (report_tree,
3262
516
                                        hf_report_info_present_ndr,
3263
516
                                        tvb, offset, 1, report,
3264
516
                                        "Info Present: %s", (report & 0x80) ? "Present" : "Absent");
3265
516
    field_tree = proto_item_add_subtree (tf, ett_report_info_present_ndr);
3266
516
    proto_tree_add_item (field_tree, hf_report_info_present_ndr, tvb, offset, 1, ENC_BIG_ENDIAN);
3267
3268
    /* Diagnostic */
3269
516
    tf = proto_tree_add_uint_format (report_tree, hf_report_diagn,
3270
516
                                     tvb, offset, 1, report,
3271
516
                                     "Diagnostic%s: %s (%d)",
3272
516
                                     ((report & 0x7F) < 0x7C) ? " (P1)":"",
3273
516
                                     non_del_diagn_str (report & 0x7F),
3274
516
                                     report & 0x7F);
3275
516
    field_tree = proto_item_add_subtree (tf, ett_report_diagn);
3276
516
    proto_tree_add_item (field_tree, hf_report_diagn, tvb, offset, 1, ENC_BIG_ENDIAN);
3277
516
  }
3278
3.25k
  offset += 1;
3279
3280
3.25k
  offset = dissect_dmp_address (tvb, pinfo, report_tree, offset,
3281
3.25k
                                prev_rec_no, true);
3282
3283
3.25k
  if (info_present) {
3284
    /* Supplementary Information */
3285
451
    len = tvb_strsize (tvb, offset);
3286
451
    tf = proto_tree_add_uint_format (report_tree, hf_report_suppl_info_len,
3287
451
                                     tvb, offset, len, len,
3288
451
                                     "Supplementary Information, Length: %d",
3289
451
                                     len - 1);
3290
451
    if (len > 1) {
3291
323
      if ((offset - boffset + len) > 128) {
3292
4
        proto_item_append_text (tf, " (incorrect, should be less than %d)",
3293
4
                                128 - (offset - boffset));
3294
4
      }
3295
323
      field_tree = proto_item_add_subtree (tf, ett_report_suppl_info);
3296
323
      proto_tree_add_item (field_tree, hf_report_suppl_info, tvb, offset, len, ENC_ASCII);
3297
323
    }
3298
451
    offset += len;
3299
451
  }
3300
3301
3.25k
  proto_item_set_len (en, offset - boffset);
3302
3303
3.25k
  return offset;
3304
3.25k
}
3305
3306
/* Ref chapter 6.3.10.1 Notification structure */
3307
static int dissect_dmp_notification (tvbuff_t *tvb, packet_info *pinfo,
3308
                                      proto_tree *dmp_tree, int offset)
3309
20
{
3310
20
  proto_tree *notif_tree = NULL;
3311
20
  proto_tree *field_tree = NULL;
3312
20
  proto_item *en = NULL, *ei = NULL, *tf = NULL;
3313
20
  uint8_t     notif, rec_time, on_typex = 0xFF;
3314
20
  int         len, boffset = offset;
3315
20
  int32_t     secs = 0;
3316
3317
20
  if (dmp.notif_type == RN) {
3318
7
    en = proto_tree_add_item (dmp_tree, hf_receipt_notif, tvb, offset, 4, ENC_NA);
3319
13
  } else if (dmp.notif_type == NRN) {
3320
4
    en = proto_tree_add_item (dmp_tree, hf_non_receipt_notif, tvb, offset, 4, ENC_NA);
3321
9
  } else if (dmp.notif_type == ON) {
3322
7
    en = proto_tree_add_item (dmp_tree, hf_other_notif, tvb, offset, 4, ENC_NA);
3323
7
  } else {
3324
2
    return offset;
3325
2
  }
3326
18
  notif_tree = proto_item_add_subtree (en, ett_notif);
3327
3328
18
  if (dmp.notif_type == RN || dmp.notif_type == ON) {
3329
    /* Receipt Time */
3330
14
    rec_time = tvb_get_uint8 (tvb, offset);
3331
14
    tf = proto_tree_add_uint_format (notif_tree, hf_notif_rec_time,
3332
14
                                     tvb, offset, 1, rec_time,
3333
14
                                     "Receipt Time: ");
3334
14
    field_tree = proto_item_add_subtree (tf, ett_notif_rec_time);
3335
14
    ei = proto_tree_add_item (field_tree, hf_notif_rec_time_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3336
14
    secs = dmp_dec_exp_time (rec_time);
3337
14
    if (secs == DMP_TIME_NOT_PRESENT) {
3338
3
      proto_item_append_text (tf, "Not present");
3339
3
      proto_item_append_text (ei, " (not present)");
3340
11
    } else if (secs == DMP_TIME_RESERVED) {
3341
1
      proto_item_append_text (tf, "Reserved (0x%2.2x)", rec_time);
3342
1
      proto_item_append_text (ei, " (Reserved)");
3343
10
    } else {
3344
10
      proto_item_append_text (tf, "%s (%s)", signed_time_secs_to_str(pinfo->pool, secs),
3345
10
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time - secs, ABSOLUTE_TIME_LOCAL, true));
3346
10
      proto_item_append_text (ei, " (%s from submission time)", signed_time_secs_to_str(pinfo->pool, secs));
3347
10
    }
3348
14
    offset += 1;
3349
3350
14
    if (dmp.notif_type == ON) {
3351
      /* ON Type */
3352
7
      on_typex = tvb_get_uint8 (tvb, offset);
3353
7
      proto_tree_add_item (notif_tree, hf_notif_on_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3354
7
      offset += 1;
3355
7
    }
3356
3357
    /* Supplementary Information */
3358
14
    len = tvb_strsize (tvb, offset);
3359
14
    tf = proto_tree_add_uint_format (notif_tree, hf_notif_suppl_info_len,
3360
14
                                     tvb, offset, len, len,
3361
14
                                     "Supplementary Information, Length: %d",
3362
14
                                     len - 1);
3363
14
    if (len > 1) {
3364
6
      if ((offset - boffset + len) > 128) {
3365
1
        proto_item_append_text (tf, " (incorrect, should be less than %d)",
3366
1
                                128 - (offset - boffset));
3367
1
      }
3368
6
      field_tree = proto_item_add_subtree (tf, ett_notif_suppl_info);
3369
6
      proto_tree_add_item (field_tree, hf_notif_suppl_info, tvb, offset, len, ENC_ASCII);
3370
6
    }
3371
14
    offset += len;
3372
3373
14
    if ((dmp.notif_type == ON) && (on_typex < 0x03)) {
3374
      /* ACP127 Recipient */
3375
2
      len = tvb_strsize (tvb, offset);
3376
2
      tf = proto_tree_add_uint_format (notif_tree, hf_notif_acp127,
3377
2
                                       tvb, offset, len, len,
3378
2
                                       "ACP127 Recipient, Length: %d",
3379
2
                                       len - 1);
3380
2
      if (len > 1) {
3381
1
        if (len > 64) {
3382
0
          proto_item_append_text (tf, " (incorrect, must be less than 64)");
3383
0
        }
3384
1
        field_tree = proto_item_add_subtree (tf, ett_notif_acp127recip);
3385
1
        proto_tree_add_item (field_tree, hf_notif_acp127recip, tvb, offset, len, ENC_ASCII);
3386
1
      }
3387
2
      offset += len;
3388
2
    }
3389
14
  } else if (dmp.notif_type == NRN) {
3390
    /* Non-Recipient Reason */
3391
4
    notif = tvb_get_uint8 (tvb, offset);
3392
4
    proto_tree_add_uint_format (notif_tree, hf_notif_non_rec_reason,
3393
4
                                tvb, offset, 1, notif,
3394
4
                                "Non-Receipt Reason%s: %s (%d)",
3395
4
                                (notif < 0x10) ? " (P22)" : "",
3396
4
                                nrn_reason_str (notif), notif);
3397
4
    offset += 1;
3398
3399
    /* Discard Reason */
3400
4
    notif = tvb_get_uint8 (tvb, offset);
3401
4
    proto_tree_add_uint_format (notif_tree, hf_notif_discard_reason,
3402
4
                                tvb, offset, 1, notif,
3403
4
                                "Discard Reason%s: %s (%d)",
3404
4
                                (notif < 0x10) ? " (P22)" : "",
3405
4
                                discard_reason_str (notif), notif);
3406
4
    offset += 1;
3407
4
  }
3408
3409
18
  proto_item_set_len (en, offset - boffset);
3410
3411
18
  return offset;
3412
20
}
3413
3414
/* Ref chapter 6.2.1.2.8 SecurityCategories */
3415
static int dissect_dmp_security_category (tvbuff_t *tvb, packet_info *pinfo,
3416
                                           proto_tree *tree,
3417
                                           const char **label_string,
3418
                                           int offset, uint8_t *ext)
3419
1.19k
{
3420
1.19k
  proto_tree *field_tree = NULL;
3421
1.19k
  proto_item *tf = NULL, *tr = NULL;
3422
1.19k
  char       *sec_cat = NULL;
3423
1.19k
  uint8_t     message;
3424
1.19k
  bool        country_code = false;
3425
3426
1.19k
  message = tvb_get_uint8 (tvb, offset);
3427
1.19k
  tf = proto_tree_add_uint_format (tree, hf_message_sec_cat_nat, tvb,
3428
1.19k
                                   offset, 1, message, "Security Categories");
3429
1.19k
  field_tree = proto_item_add_subtree (tf, ett_message_sec_cat);
3430
3431
1.19k
  switch (*ext) {
3432
3433
81
  case SEC_CAT_EXT_NONE:
3434
81
    proto_tree_add_item (field_tree, hf_message_sec_cat_cl, tvb, offset, 1, ENC_BIG_ENDIAN);
3435
81
    proto_tree_add_item (field_tree, hf_message_sec_cat_cs, tvb, offset, 1, ENC_BIG_ENDIAN);
3436
81
    proto_tree_add_item (field_tree, hf_message_sec_cat_ex, tvb, offset, 1, ENC_BIG_ENDIAN);
3437
81
    proto_tree_add_item (field_tree, hf_message_sec_cat_ne, tvb, offset, 1, ENC_BIG_ENDIAN);
3438
3439
81
    tr = proto_tree_add_item (field_tree, hf_reserved_0x08, tvb, offset, 1, ENC_BIG_ENDIAN);
3440
81
    if (message & 0x08) {
3441
33
      expert_add_info(pinfo, tr, &ei_reserved_value);
3442
33
    }
3443
81
    tr = proto_tree_add_item (field_tree, hf_reserved_0x04, tvb, offset, 1, ENC_BIG_ENDIAN);
3444
81
    if (message & 0x04) {
3445
29
      expert_add_info(pinfo, tr, &ei_reserved_value);
3446
29
    }
3447
3448
81
    if (message & 0xF0) {
3449
78
      sec_cat = wmem_strdup_printf (pinfo->pool, "%s%s%s%s",
3450
78
                                    (message & 0x80) ? ",cl" : "",
3451
78
                                    (message & 0x40) ? ",cs" : "",
3452
78
                                    (message & 0x20) ? ",ex" : "",
3453
78
                                    (message & 0x10) ? ",ne" : "");
3454
78
      proto_item_append_text (tf, ": %s", &sec_cat[1]);
3455
78
      *label_string = wmem_strconcat(pinfo->pool, *label_string, sec_cat, NULL);
3456
78
    }
3457
81
    break;
3458
3459
769
  case SEC_CAT_EXT_PERMISSIVE:
3460
769
    if ((message >> 2) == 0x3F) {
3461
      /* Fake entry because nat_pol_id defines 0x3F as reserved */
3462
7
      proto_tree_add_uint_format (field_tree, hf_message_sec_cat_permissive, tvb, offset, 1,
3463
7
                                  message, "1111 11.. = Next byte has Country Code (0x3F)");
3464
7
      country_code = true;
3465
762
    } else {
3466
762
      tr = proto_tree_add_item (field_tree, hf_message_sec_cat_permissive, tvb, offset, 1, ENC_BIG_ENDIAN);
3467
762
      proto_item_append_text (tf, ": rel-to-%s", get_nat_pol_id_short (message >> 2));
3468
762
      *label_string = wmem_strdup_printf(pinfo->pool, "%s,rel-to-%s", *label_string, get_nat_pol_id_short (message >> 2));
3469
762
      if ((message >> 2) == 0) {
3470
28
        expert_add_info(pinfo, tr, &ei_reserved_value);
3471
28
      }
3472
762
    }
3473
769
    break;
3474
3475
334
  case SEC_CAT_EXT_RESTRICTIVE:
3476
334
    proto_tree_add_item (field_tree, hf_message_sec_cat_restrictive, tvb, offset, 1, ENC_BIG_ENDIAN);
3477
334
    proto_item_append_text (tf, " (restrictive: 0x%2.2x)", message >> 2);
3478
334
    break;
3479
3480
0
  default:
3481
0
    break;
3482
1.19k
  }
3483
3484
1.18k
  proto_item_append_text (tf, " (0x%2.2x)", message);
3485
1.18k
  *ext = 0; /* Reset extended bits */
3486
3487
1.18k
  if (dmp.version == 1) {
3488
24
    tr = proto_tree_add_item (field_tree, hf_reserved_0x02, tvb, offset, 1, ENC_BIG_ENDIAN);
3489
24
    if (message & 0x02) {
3490
17
      expert_add_info(pinfo, tr, &ei_reserved_value);
3491
17
    }
3492
24
    tr = proto_tree_add_item (field_tree, hf_reserved_0x01, tvb, offset, 1, ENC_BIG_ENDIAN);
3493
24
    if (message & 0x01) {
3494
10
      expert_add_info(pinfo, tr, &ei_reserved_value);
3495
10
    }
3496
24
    offset += 1;
3497
1.16k
  } else {
3498
1.16k
    tr = proto_tree_add_item (field_tree, hf_message_sec_cat_extended, tvb, offset, 1, ENC_BIG_ENDIAN);
3499
1.16k
    if ((message & 0x01) && (message & 0x02)) {
3500
15
      expert_add_info(pinfo, tr, &ei_reserved_value);
3501
1.14k
    } else if (message & 0x01 || message & 0x02) {
3502
1.10k
      proto_item_append_text (tf, " (extended)");
3503
1.10k
      *ext = message & 0x03;
3504
1.10k
    }
3505
1.16k
    offset += 1;
3506
3507
1.16k
    if (country_code) {
3508
7
      proto_tree_add_item (field_tree, hf_message_sec_cat_country_code, tvb, offset, 1, ENC_BIG_ENDIAN);
3509
7
      proto_item_append_text (tf, " (rel-to country-code: %d)", tvb_get_uint8 (tvb, offset));
3510
7
      proto_item_set_len (tf, 2);
3511
7
      offset += 1;
3512
7
    }
3513
1.16k
  }
3514
3515
1.18k
  return offset;
3516
1.19k
}
3517
3518
/*
3519
 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3520
 * and chapter 6.3.8.1 IPM 88 message structure
3521
 * and chapter 6.3.9.1 Report structure
3522
 * and chapter 6.3.10.1 Notification structure
3523
 */
3524
static int dissect_dmp_content (tvbuff_t *tvb, packet_info *pinfo,
3525
                                 proto_tree *dmp_tree, int offset)
3526
259
{
3527
259
  proto_tree *message_tree = NULL;
3528
259
  proto_tree *field_tree = NULL;
3529
259
  proto_item *en = NULL, *ei = NULL, *tf = NULL;
3530
259
  proto_item *hidden_item;
3531
259
  const char  *label_string = wmem_strdup (pinfo->pool, "");
3532
259
  const char *class_name = NULL;
3533
259
  uint8_t     message, dmp_sec_pol, dmp_sec_class, dmp_nation = 0, exp_time, dtg;
3534
259
  int32_t     secs = 0;
3535
259
  unsigned    prev_rec_no = 0;
3536
259
  int         rep_len, rep_no = 1;
3537
259
  int         loffset, boffset = offset;
3538
3539
259
  if (dmp.msg_type == REPORT) {
3540
97
    en = proto_tree_add_item (dmp_tree, hf_report_content, tvb, offset, 7, ENC_NA);
3541
162
  } else if (dmp.msg_type == NOTIF) {
3542
20
    en = proto_tree_add_item (dmp_tree, hf_notif_content, tvb, offset, 7, ENC_NA);
3543
142
  } else {
3544
142
    en = proto_tree_add_item (dmp_tree, hf_message_content, tvb, offset, 7, ENC_NA);
3545
142
  }
3546
259
  message_tree = proto_item_add_subtree (en, ett_content);
3547
3548
259
  if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3549
142
    message = tvb_get_uint8 (tvb, offset);
3550
142
    dmp.body_format = (message & 0x03);
3551
3552
142
    if (dmp.msg_type == STANAG) {
3553
      /* Message Type */
3554
117
      dmp.st_type = (message & 0xC0) >> 6;
3555
117
      tf = proto_tree_add_uint_format (message_tree, hf_message_st_type,
3556
117
                                       tvb, offset, 1, message,
3557
117
                                       "Message Type: %s (%d)",
3558
117
                                       val_to_str_const (dmp.st_type,
3559
117
                                                         message_type_vals, ""),
3560
117
                                       dmp.st_type);
3561
117
      field_tree = proto_item_add_subtree (tf, ett_message_st_type);
3562
117
      proto_tree_add_item (field_tree, hf_message_st_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3563
3564
117
      if ((message & 0x20) >> 5) {
3565
        /* Reserved */
3566
32
        tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x20,
3567
32
                                         tvb, offset, 1, message,
3568
32
                                         "Reserved: %d", (message & 0x20)>>5);
3569
32
        field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3570
32
        tf = proto_tree_add_item (field_tree, hf_reserved_0x20, tvb, offset, 1, ENC_BIG_ENDIAN);
3571
32
        expert_add_info(pinfo, tf, &ei_reserved_value);
3572
32
      }
3573
3574
      /* Precedence */
3575
117
      dmp.prec = (message & 0x1C) >> 2;
3576
117
      tf = proto_tree_add_uint_format (message_tree, hf_message_precedence,
3577
117
                                       tvb, offset, 1, message,
3578
117
                                       "Precedence: %s (%d)",
3579
117
                                       val_to_str_const (dmp.prec, precedence, ""),
3580
117
                                       dmp.prec);
3581
117
      field_tree = proto_item_add_subtree (tf, ett_message_precedence);
3582
117
      proto_tree_add_item (field_tree, hf_message_precedence, tvb, offset, 1, ENC_BIG_ENDIAN);
3583
3584
117
    } else {
3585
25
      if ((message & 0xE0) >> 5) {
3586
        /* Reserved */
3587
9
        tf = proto_tree_add_uint_format (message_tree, hf_reserved_0xE0,
3588
9
                                         tvb, offset, 1, message,
3589
9
                                         "Reserved: %d", (message & 0xE0)>>5);
3590
9
        field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3591
9
        tf = proto_tree_add_item (field_tree, hf_reserved_0xE0, tvb, offset, 1, ENC_BIG_ENDIAN);
3592
9
        expert_add_info(pinfo, tf, &ei_reserved_value);
3593
9
      }
3594
3595
      /* Importance */
3596
25
      dmp.prec = (message & 0x1C) >> 2;
3597
25
      tf = proto_tree_add_uint_format (message_tree, hf_message_importance,
3598
25
                                       tvb, offset, 1, message,
3599
25
                                       "Importance: %s (%d)",
3600
25
                                       val_to_str_const (dmp.prec, importance, ""),
3601
25
                                       dmp.prec);
3602
25
      field_tree = proto_item_add_subtree (tf, ett_message_importance);
3603
25
      proto_tree_add_item (field_tree, hf_message_importance, tvb, offset, 1, ENC_BIG_ENDIAN);
3604
25
    }
3605
3606
    /* Body Format */
3607
142
    tf = proto_tree_add_uint_format (message_tree, hf_message_body_format,
3608
142
                                     tvb, offset, 1, message,
3609
142
                                     "Body Format: %s (%d)",
3610
142
                                     val_to_str_const (message & 0x03,
3611
142
                                                       body_format_vals, ""),
3612
142
                                     message & 0x03);
3613
142
    field_tree = proto_item_add_subtree (tf, ett_message_body_format);
3614
142
    proto_tree_add_item (field_tree, hf_message_body_format, tvb, offset, 1, ENC_BIG_ENDIAN);
3615
142
    offset += 1;
3616
142
  }
3617
3618
259
  message = tvb_get_uint8 (tvb, offset);
3619
  /* Security Classification */
3620
259
  dmp_sec_class = (message & 0xE0) >> 5;
3621
259
  dmp_sec_pol = (message & 0x1C) >> 2;
3622
259
  if (dmp_sec_pol == EXTENDED_NATIONAL) {
3623
28
    dmp_nation = tvb_get_uint8 (tvb, offset + 1);
3624
28
  }
3625
3626
259
  loffset = offset; /* Offset to start of security label */
3627
259
  if (dmp_sec_pol == NATIONAL && dmp_local_nation != 0) {
3628
0
    class_name = dmp_national_sec_class (dmp_local_nation, dmp_sec_class);
3629
259
  } else if (dmp_sec_pol == EXTENDED_NATIONAL) {
3630
28
    class_name = dmp_national_sec_class (dmp_nation, dmp_sec_class);
3631
28
  }
3632
259
  if ((dmp_sec_pol == NATO || dmp_sec_pol == NATIONAL) && !class_name) {
3633
54
    class_name = val_to_str_const (dmp_sec_class, sec_class, "");
3634
54
  }
3635
259
  if (class_name && class_name[0]) {
3636
42
    tf = proto_tree_add_uint_format (message_tree, hf_message_sec_class_val,
3637
42
                                     tvb, offset, 1, message,
3638
42
                                     "Security Classification: %s (%d)",
3639
42
                                     class_name, dmp_sec_class);
3640
217
  } else {
3641
217
    tf = proto_tree_add_uint_format (message_tree, hf_message_sec_class_val,
3642
217
                                     tvb, offset, 1, message,
3643
217
                                     "Security Classification: %d",
3644
217
                                     dmp_sec_class);
3645
217
  }
3646
259
  field_tree = proto_item_add_subtree (tf, ett_message_sec_class);
3647
259
  tf = proto_tree_add_item (field_tree, hf_message_sec_class_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3648
259
  if (class_name) {
3649
54
    proto_item_append_text (tf, " (%s)", class_name);
3650
54
    label_string = wmem_strconcat(pinfo->pool, label_string, class_name, NULL);
3651
54
  }
3652
3653
  /* Security Policy */
3654
259
  tf = proto_tree_add_uint_format (message_tree, hf_message_sec_pol,
3655
259
                                   tvb, offset, 1, message,
3656
259
                                   "Security Policy: %s (%d)",
3657
259
                                   val_to_str(pinfo->pool, dmp_sec_pol, sec_pol, "%d"),
3658
259
                                   dmp_sec_pol);
3659
259
  field_tree = proto_item_add_subtree (tf, ett_message_sec_pol);
3660
259
  proto_tree_add_item (field_tree, hf_message_sec_pol, tvb, offset, 1, ENC_BIG_ENDIAN);
3661
3662
259
  if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3663
    /* Heading Flags */
3664
136
    tf = proto_tree_add_item (message_tree, hf_message_heading_flags, tvb, offset, 1, ENC_NA);
3665
136
    field_tree = proto_item_add_subtree (tf, ett_message_heading_flags);
3666
136
    proto_tree_add_item (field_tree, hf_message_auth_users, tvb, offset, 1, ENC_BIG_ENDIAN);
3667
136
    proto_tree_add_item (field_tree, hf_message_subject_disc, tvb, offset, 1, ENC_BIG_ENDIAN);
3668
136
    if (message & 0x03) {
3669
93
      proto_item_append_text (tf, ": %s%s%s discarded",
3670
93
                              (message & 0x02) ? "Authorizing users" : "",
3671
93
                              (message & 0x03) == 0x03 ? " and " : "",
3672
93
                              (message & 0x01) ? "Subject" : "");
3673
93
    } else {
3674
43
      proto_item_append_text (tf, " (none)");
3675
43
    }
3676
136
  } else if (dmp.msg_type == NOTIF) {
3677
    /* Notification Type */
3678
20
    dmp.notif_type = (message & 0x03);
3679
20
    tf = proto_tree_add_uint_format (message_tree, hf_notif_type,
3680
20
                                     tvb, offset, 1, message,
3681
20
                                     "Notification Type: %s",
3682
20
                                     val_to_str_const (dmp.notif_type, notif_type,
3683
20
                                                       "Reserved"));
3684
20
    field_tree = proto_item_add_subtree (tf, ett_notif_type);
3685
20
    proto_tree_add_item (field_tree, hf_notif_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3686
103
  } else if (message & 0x02) {
3687
    /* Reserved */
3688
22
    tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x02,
3689
22
                                     tvb, offset, 1, message,
3690
22
                                     "Reserved: %d", message & 0x02);
3691
22
    field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3692
22
    tf = proto_tree_add_item (field_tree, hf_reserved_0x02, tvb, offset, 1, ENC_BIG_ENDIAN);
3693
22
    expert_add_info(pinfo, tf, &ei_reserved_value);
3694
22
  }
3695
259
  offset += 1;
3696
3697
259
  if (dmp_sec_pol == NATIONAL && dmp_local_nation != 0) {
3698
    /* Show configured national policy */
3699
0
    tf = proto_tree_add_uint (message_tree, hf_message_national_policy_id,
3700
0
                              tvb, offset, 0, dmp_local_nation);
3701
0
    proto_item_set_generated (tf);
3702
259
  } else if (dmp_sec_pol == EXTENDED_NATIONAL) {
3703
    /* National Policy Identifier */
3704
28
    proto_tree_add_item (message_tree, hf_message_national_policy_id, tvb, offset, 1, ENC_BIG_ENDIAN);
3705
28
    offset += 1;
3706
231
  } else if (dmp_sec_pol == EXTENDED_MISSION) {
3707
    /* Mission Policy Identifier */
3708
28
    message = tvb_get_uint8 (tvb, offset);
3709
28
    if (message == 0xFF) {
3710
7
      proto_tree_add_uint_format_value (message_tree, hf_message_mission_policy_id,
3711
7
                                        tvb, offset, 1, message,
3712
7
                                        "Reserved (0xFF)");
3713
21
    } else {
3714
21
      proto_tree_add_item (message_tree, hf_message_mission_policy_id, tvb, offset, 1, ENC_BIG_ENDIAN);
3715
21
    }
3716
28
    offset += 1;
3717
28
  }
3718
3719
  /* Security Categories */
3720
259
  if (dmp_sec_pol == NATO || dmp_sec_pol == NATIONAL || dmp_sec_pol == EXTENDED_NATIONAL) {
3721
82
    uint8_t ext = 0;
3722
82
    unsigned  sec_cat_count = 0;
3723
1.19k
    do {
3724
1.19k
      offset = dissect_dmp_security_category (tvb, pinfo, message_tree, &label_string, offset, &ext);
3725
1.19k
      sec_cat_count++;
3726
1.19k
    } while (ext != 0 && sec_cat_count < UINT8_MAX);
3727
82
    if (sec_cat_count == UINT8_MAX) {
3728
      /* This is a arbitrary limit to avoid a long dissector loop. */
3729
1
      expert_add_info(pinfo, en, &ei_too_many_sec_cat);
3730
1
    }
3731
82
    proto_item_append_text (en, ", Security Label: %s", label_string);
3732
82
    tf = proto_tree_add_string (message_tree, hf_message_sec_label, tvb, loffset,
3733
82
                                offset - loffset, label_string);
3734
82
    proto_item_set_generated (tf);
3735
177
  } else {
3736
177
    tf = proto_tree_add_item (message_tree, hf_message_sec_cat_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3737
177
    field_tree = proto_item_add_subtree (tf, ett_message_sec_cat);
3738
3739
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit7, tvb, offset, 1, ENC_BIG_ENDIAN);
3740
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit6, tvb, offset, 1, ENC_BIG_ENDIAN);
3741
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit5, tvb, offset, 1, ENC_BIG_ENDIAN);
3742
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit4, tvb, offset, 1, ENC_BIG_ENDIAN);
3743
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit3, tvb, offset, 1, ENC_BIG_ENDIAN);
3744
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit2, tvb, offset, 1, ENC_BIG_ENDIAN);
3745
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit1, tvb, offset, 1, ENC_BIG_ENDIAN);
3746
177
    proto_tree_add_item (field_tree, hf_message_sec_cat_bit0, tvb, offset, 1, ENC_BIG_ENDIAN);
3747
177
    offset += 1;
3748
177
  }
3749
3750
259
  if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3751
    /* Expiry Time */
3752
130
    exp_time = tvb_get_uint8 (tvb, offset);
3753
130
    tf = proto_tree_add_uint_format (message_tree, hf_message_exp_time,
3754
130
                                     tvb, offset, 1, exp_time,
3755
130
                                     "Expiry Time: ");
3756
130
    field_tree = proto_item_add_subtree (tf, ett_message_exp_time);
3757
130
    ei = proto_tree_add_item (field_tree, hf_message_exp_time_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3758
130
    secs = dmp_dec_exp_time (exp_time);
3759
130
    if (secs == DMP_TIME_NOT_PRESENT) {
3760
24
      proto_item_append_text (tf, "Not present");
3761
24
      proto_item_append_text (ei, " (not present)");
3762
106
    } else if (secs == DMP_TIME_RESERVED) {
3763
11
      proto_item_append_text (tf, "Reserved (0x%2.2x)", exp_time);
3764
11
      proto_item_append_text (ei, " (Reserved)");
3765
95
    } else {
3766
95
      proto_item_append_text (tf, "%s (%s)", signed_time_secs_to_str(pinfo->pool, secs),
3767
95
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time + secs, ABSOLUTE_TIME_LOCAL, true));
3768
95
      proto_item_append_text (ei, " (%s from submission time)", signed_time_secs_to_str(pinfo->pool, secs));
3769
95
    }
3770
130
    offset += 1;
3771
130
  }
3772
3773
259
  if (dmp.msg_type == STANAG) {
3774
110
    dtg = tvb_get_uint8 (tvb, offset);
3775
110
    tf = proto_tree_add_uint_format (message_tree, hf_message_dtg, tvb, offset, 1, dtg, "DTG: ");
3776
110
    field_tree = proto_item_add_subtree (tf, ett_message_dtg);
3777
110
    proto_tree_add_item (field_tree, hf_message_dtg_sign, tvb, offset, 1, ENC_BIG_ENDIAN);
3778
110
    proto_tree_add_item (field_tree, hf_message_dtg_val, tvb, offset, 1, ENC_BIG_ENDIAN);
3779
110
    secs = dmp_dec_dtg (dtg & 0x7F);
3780
110
    if (secs == DMP_TIME_NOT_PRESENT) {
3781
15
      proto_item_append_text (tf, "Not present");
3782
95
    } else if (secs == DMP_TIME_RESERVED) {
3783
5
      proto_item_append_text (tf, "Reserved (0x%2.2x)", dtg & 0x7F);
3784
90
    } else if (secs == 0) {
3785
3
      proto_item_append_text (tf, "0 minutes in the %s (%s)",
3786
3
                              tfs_get_string(dtg & 0x80, &dtg_sign),
3787
3
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time, ABSOLUTE_TIME_LOCAL, true));
3788
87
    } else {
3789
87
      proto_item_append_text (tf, "%s in the %s (%s)", signed_time_secs_to_str(pinfo->pool, secs),
3790
87
                              tfs_get_string(dtg & 0x80, &dtg_sign), (dtg & 0x80) ?
3791
56
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time + secs, ABSOLUTE_TIME_LOCAL, true) :
3792
87
                              abs_time_secs_to_str (pinfo->pool, dmp.subm_time - secs, ABSOLUTE_TIME_LOCAL, true));
3793
87
    }
3794
110
    offset += 1;
3795
110
  }
3796
3797
259
  if (dmp.msg_type == STANAG) {
3798
    /* SIC */
3799
106
    offset = dissect_dmp_sic (tvb, pinfo, message_tree, offset);
3800
153
  } else if (dmp.msg_type == REPORT || dmp.msg_type == NOTIF) {
3801
116
    if (dmp.version == DMP_VERSION_1 || dmp.msg_id_type == ONLY_DMP_ID) {
3802
      /* Subject Message Identifier */
3803
85
      dmp.subj_id = tvb_get_ntohs (tvb, offset);
3804
85
      proto_tree_add_item (message_tree, hf_message_subj_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3805
85
      hidden_item = proto_tree_add_item (message_tree, hf_dmp_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3806
85
      proto_item_set_hidden (hidden_item);
3807
85
      offset += 2;
3808
85
    } else if (dmp.msg_id_type == X400_MSG_ID || dmp.msg_id_type == NAT_MSG_ID) {
3809
16
      if (dmp.msg_type == REPORT) {
3810
        /* Subject MTS Identifier */
3811
13
        offset = dissect_mts_identifier (tvb, pinfo, message_tree, offset, true);
3812
13
      } else {
3813
        /* Subject IPM Identifier */
3814
3
        offset = dissect_ipm_identifier (tvb, pinfo, message_tree, offset, true);
3815
3
      }
3816
16
      if (dmp.subj_id) {
3817
3
        tf = proto_tree_add_uint (message_tree, hf_message_subj_id, tvb, offset, 0, dmp.subj_id);
3818
3
        proto_item_set_generated (tf);
3819
3
        hidden_item = proto_tree_add_uint (message_tree, hf_dmp_id, tvb, offset, 0, dmp.subj_id);
3820
3
        proto_item_set_generated (hidden_item);
3821
3
        proto_item_set_hidden (hidden_item);
3822
3
      }
3823
16
    }
3824
116
  }
3825
3826
259
  if (use_seq_ack_analysis) {
3827
216
    register_dmp_id (pinfo, 0);
3828
216
  }
3829
3830
259
  proto_item_set_len (en, offset - boffset);
3831
3832
259
  if  (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3833
    /* User Data */
3834
100
    offset = dissect_dmp_message (tvb, pinfo, dmp_tree, offset);
3835
159
  } else if (dmp.msg_type == REPORT) {
3836
    /* One or more Delivery Report or Non-Delivery Report Data */
3837
96
    rep_len = tvb_reported_length (tvb);
3838
96
    if (dmp.checksum) {
3839
46
      rep_len -= 2;
3840
46
    }
3841
3.35k
    while (offset < rep_len) {
3842
3.25k
      offset = dissect_dmp_report (tvb, pinfo, dmp_tree, offset, &prev_rec_no, rep_no++);
3843
3.25k
    }
3844
96
  } else if (dmp.msg_type == NOTIF) {
3845
    /* Notification Data */
3846
20
    offset = dissect_dmp_notification (tvb, pinfo, dmp_tree, offset);
3847
20
  }
3848
3849
259
  return offset;
3850
259
}
3851
3852
static int dissect_dmp_extensions (tvbuff_t *tvb, packet_info *pinfo _U_,
3853
                                    proto_tree *dmp_tree, int offset)
3854
28
{
3855
28
  proto_tree *exts_tree, *ext_tree, *hdr_tree;
3856
28
  proto_item *exts_item, *en;
3857
28
  uint8_t     ext_hdr, ext_length;
3858
28
  bool        more_extensions = true;
3859
28
  int         num_ext = 0, boffset = offset;
3860
3861
28
  exts_item = proto_tree_add_item (dmp_tree, hf_extensions, tvb, offset, -1, ENC_NA);
3862
28
  exts_tree = proto_item_add_subtree (exts_item, ett_extensions);
3863
3864
108
  while (more_extensions) {
3865
    /* Extensions Present */
3866
80
    ext_hdr = tvb_get_uint8 (tvb, offset);
3867
80
    more_extensions = (ext_hdr & 0x80);
3868
80
    ext_length = (ext_hdr & 0x7F) + 1;
3869
3870
80
    en = proto_tree_add_none_format (exts_tree, hf_extension, tvb, offset, ext_length + 1,
3871
80
                                     "Extension (#%d)", num_ext + 1);
3872
80
    ext_tree = proto_item_add_subtree (en, ett_extension);
3873
3874
80
    en = proto_tree_add_none_format (ext_tree, hf_extension_header, tvb, offset, 1,
3875
80
                                     "Extension Length: %u, More %s", ext_length,
3876
80
                                     (ext_hdr & 0x80) ? "Present" : "Not present");
3877
80
    hdr_tree = proto_item_add_subtree (en, ett_extension_header);
3878
80
    proto_tree_add_item (hdr_tree, hf_extension_more, tvb, offset, 1, ENC_BIG_ENDIAN);
3879
80
    proto_tree_add_item (hdr_tree, hf_extension_length, tvb, offset, 1, ENC_BIG_ENDIAN);
3880
80
    offset += 1;
3881
3882
80
    proto_tree_add_item (ext_tree, hf_extension_data, tvb, offset, ext_length, ENC_NA);
3883
80
    offset += ext_length;
3884
80
    num_ext++;
3885
80
  }
3886
3887
28
  proto_item_append_text (exts_item, " (%d item%s)", num_ext, plurality (num_ext, "", "s"));
3888
28
  proto_item_set_len (exts_item, offset - boffset);
3889
3890
28
  return offset;
3891
28
}
3892
3893
static int dissect_dmp (tvbuff_t *tvb, packet_info *pinfo,
3894
                         proto_tree *tree, void *data _U_)
3895
545
{
3896
545
  proto_tree *dmp_tree;
3897
545
  proto_item *ti;
3898
545
  uint16_t    checksum1 = 0, checksum2 = 1;
3899
545
  int         length, offset = 0;
3900
545
  bool        retrans_or_dup_ack = false;
3901
3902
545
  col_set_str (pinfo->cinfo, COL_PROTOCOL, "DMP");
3903
545
  col_clear (pinfo->cinfo, COL_INFO);
3904
3905
  /* Initialize global data structure */
3906
545
  memset (&dmp, 0, sizeof (dmp));
3907
3908
545
  ti = proto_tree_add_item (tree, proto_dmp, tvb, offset, -1, ENC_NA);
3909
545
  dmp_tree = proto_item_add_subtree (ti, ett_dmp);
3910
3911
545
  offset = dissect_dmp_envelope (tvb, pinfo, dmp_tree, offset);
3912
3913
545
  if (dmp.version > DMP_VERSION_2) {
3914
    /* Unsupported DMP Version, no point to continue */
3915
26
    col_add_fstr (pinfo->cinfo, COL_INFO, "Unsupported Version: %d", dmp.version);
3916
26
    return 0;
3917
26
  }
3918
3919
519
  if (dmp.extensions) {
3920
28
    offset = dissect_dmp_extensions (tvb, pinfo, dmp_tree, offset);
3921
28
  }
3922
3923
519
  if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3924
172
      (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF))
3925
259
  {
3926
259
    offset = dissect_dmp_content (tvb, pinfo, dmp_tree, offset);
3927
260
  } else if (dmp.msg_type == ACK) {
3928
46
    offset = dissect_dmp_ack (tvb, pinfo, dmp_tree, offset);
3929
46
  }
3930
3931
519
  if (dmp.checksum) {
3932
53
    length = tvb_captured_length (tvb);
3933
53
    checksum1 = crc16_x25_ccitt_tvb (tvb, length - 2);
3934
53
    checksum2 = tvb_get_ntohs (tvb, offset);
3935
3936
53
    proto_tree_add_checksum(dmp_tree, tvb, offset, hf_checksum, hf_checksum_status, &ei_checksum_bad, pinfo, checksum1, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
3937
53
    offset += 2;
3938
53
  }
3939
3940
519
  if (use_seq_ack_analysis) {
3941
133
    dmp_add_seq_ack_analysis (tvb, pinfo, dmp_tree, offset);
3942
133
  }
3943
3944
519
  if (((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3945
45
       (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF)) &&
3946
111
      dmp.id_val && dmp.id_val->msg_resend_count)
3947
55
  {
3948
55
    unsigned retrans_num;
3949
55
    if (dmp.msg_type == REPORT) {
3950
4
      retrans_num = dmp.id_val->rep_id;
3951
51
    } else if (dmp.msg_type == NOTIF) {
3952
3
      retrans_num = dmp.id_val->not_id;
3953
48
    } else {
3954
48
      retrans_num = dmp.id_val->msg_id;
3955
48
    }
3956
55
    col_append_fstr (pinfo->cinfo, COL_INFO, "[Retrans %d#%d] ",
3957
55
                     retrans_num, dmp.id_val->msg_resend_count);
3958
55
    retrans_or_dup_ack = true;
3959
464
  } else if (dmp.msg_type == ACK && dmp.id_val && dmp.id_val->ack_resend_count) {
3960
6
    col_append_fstr (pinfo->cinfo, COL_INFO, "[Dup ACK %d#%d] ",
3961
6
                     dmp.id_val->ack_id, dmp.id_val->ack_resend_count);
3962
6
    retrans_or_dup_ack = true;
3963
6
  }
3964
519
  if (dmp_align && !retrans_or_dup_ack) {
3965
0
    if (dmp.msg_type == ACK) {
3966
      /* ACK does not have "Msg Id" */
3967
0
      col_append_fstr (pinfo->cinfo, COL_INFO, "%-45.45s", msg_type_to_str (pinfo->pool));
3968
0
    } else {
3969
0
      col_append_fstr (pinfo->cinfo, COL_INFO, "%-31.31s", msg_type_to_str (pinfo->pool));
3970
0
    }
3971
519
  } else {
3972
519
    col_append_str (pinfo->cinfo, COL_INFO, msg_type_to_str (pinfo->pool));
3973
519
  }
3974
519
  if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3975
45
      (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF))
3976
111
  {
3977
111
    if (dmp_align && !retrans_or_dup_ack) {
3978
0
      col_append_fstr (pinfo->cinfo, COL_INFO, " Msg Id: %5d", dmp.msg_id);
3979
111
    } else {
3980
111
      col_append_fstr (pinfo->cinfo, COL_INFO, ", Msg Id: %d", dmp.msg_id);
3981
111
    }
3982
111
  }
3983
519
  if ((dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF) ||
3984
110
      (dmp.msg_type == ACK))
3985
38
  {
3986
38
    if (dmp_align && !retrans_or_dup_ack) {
3987
0
      col_append_fstr (pinfo->cinfo, COL_INFO, "  Subj Id: %5d",
3988
0
                       dmp.subj_id);
3989
38
    } else {
3990
38
      col_append_fstr (pinfo->cinfo, COL_INFO, ", Subj Id: %d",
3991
38
                       dmp.subj_id);
3992
38
    }
3993
38
  }
3994
519
  if (dmp.checksum && (checksum1 != checksum2)) {
3995
34
    col_append_str (pinfo->cinfo, COL_INFO, ", Checksum incorrect");
3996
34
  }
3997
3998
519
  proto_item_append_text (ti, ", Version: %d%s, %s", dmp.version,
3999
519
                          (dmp.prot_id == PROT_NAT ? " (national)" : ""),
4000
519
                          msg_type_to_str(pinfo->pool));
4001
4002
519
  return offset;
4003
545
}
4004
4005
void proto_register_dmp (void)
4006
14
{
4007
14
  static hf_register_info hf[] = {
4008
    /*
4009
    ** DMP Identifier
4010
    */
4011
14
    { &hf_dmp_id,
4012
14
      { "DMP Identifier", "dmp.id", FT_UINT16, BASE_DEC,
4013
14
        NULL, 0x0, NULL, HFILL} },
4014
4015
    /* MTS Identifier */
4016
14
    { &hf_mts_id,
4017
14
      { "MTS Identifier", "dmp.mts", FT_STRING, BASE_NONE,
4018
14
        NULL, 0x0, NULL, HFILL } },
4019
4020
    /* IPM Identifier */
4021
14
    { &hf_ipm_id,
4022
14
      { "IPM Identifier", "dmp.ipm", FT_STRING, BASE_NONE,
4023
14
        NULL, 0x0, NULL, HFILL } },
4024
4025
    /*
4026
    ** Envelope
4027
    */
4028
14
    { &hf_envelope,
4029
14
      { "Envelope", "dmp.envelope", FT_NONE, BASE_NONE,
4030
14
        NULL, 0x0, NULL, HFILL} },
4031
4032
    /* Protocol data */
4033
14
    { &hf_envelope_protocol_id,
4034
14
      { "Protocol Identifier", "dmp.protocol_id", FT_UINT8,
4035
14
        BASE_HEX, NULL, 0xF8, NULL, HFILL} },
4036
14
    { &hf_envelope_version,
4037
14
      { "Protocol Version", "dmp.version", FT_UINT8, BASE_DEC,
4038
14
        VALS(version_vals), 0x07, NULL, HFILL } },
4039
14
    { &hf_envelope_version_value,
4040
14
      { "Protocol Version", "dmp.version_value", FT_UINT8, BASE_DEC,
4041
14
        VALS(version_vals), 0x07, NULL, HFILL } },
4042
4043
    /* Envelope elements (byte 1) */
4044
14
    { &hf_envelope_hop_count,
4045
14
      { "Hop Count", "dmp.hop_count", FT_UINT8, BASE_DEC,
4046
14
        NULL, 0xE0, NULL, HFILL } },
4047
14
    { &hf_envelope_hop_count_value,
4048
14
      { "Hop Count", "dmp.hop_count_value", FT_UINT8, BASE_DEC,
4049
14
        NULL, 0xE0, NULL, HFILL } },
4050
14
    { &hf_envelope_rec_present,
4051
14
      { "Recipient Present", "dmp.rec_present", FT_BOOLEAN, 8,
4052
14
        TFS (&tfs_present_absent), 0x20, NULL, HFILL } },
4053
14
    { &hf_envelope_addr_enc,
4054
14
      { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
4055
14
        TFS (&addr_enc), 0x10, NULL, HFILL } },
4056
14
    { &hf_envelope_checksum,
4057
14
      { "Checksum", "dmp.checksum_used", FT_BOOLEAN, 8,
4058
14
        TFS (&tfs_used_notused), 0x08, "Checksum Used", HFILL } },
4059
14
    { &hf_envelope_type,
4060
14
      { "Content Type", "dmp.content_type", FT_UINT8, BASE_DEC,
4061
14
        VALS(type_vals), 0x07, NULL, HFILL } },
4062
4063
    /* Envelope elements (byte 2) */
4064
14
    { &hf_envelope_extensions,
4065
14
      { "Extensions", "dmp.extensions_used", FT_BOOLEAN, 8,
4066
14
        TFS (&tfs_present_absent), 0x80, "Extensions Used", HFILL } },
4067
14
    { &hf_envelope_msg_id_type,
4068
14
      { "Message Identifier Type", "dmp.msg_id_type", FT_UINT8, BASE_DEC,
4069
14
        VALS(msg_id_type_vals), 0x60, NULL, HFILL } },
4070
14
    { &hf_envelope_msg_id_length,
4071
14
      { "Message Identifier Length", "dmp.msg_id_short", FT_UINT8, BASE_DEC,
4072
14
        VALS(msg_id_length_vals), 0x10, NULL, HFILL} },
4073
14
    { &hf_envelope_mts_id_length,
4074
14
      { "MTS Identifier Length", "dmp.mts_id_length", FT_UINT8, BASE_DEC,
4075
14
        NULL, 0x1F, NULL, HFILL } },
4076
14
    { &hf_envelope_ipm_id_modifier,
4077
14
      { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8, BASE_DEC,
4078
14
        VALS(ipm_id_modifier), 0xC0, NULL, HFILL } },
4079
14
    { &hf_envelope_ipm_id_length,
4080
14
      { "IPM Identifier Length", "dmp.ipm_id_length", FT_UINT8, BASE_DEC,
4081
14
        NULL, 0x3F, NULL, HFILL } },
4082
4083
14
    { &hf_thales_ipm_id_modifier,
4084
14
      { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8, BASE_DEC,
4085
14
        VALS(thales_ipm_id_modifier), 0xC0, "Thales XOmail IPM Identifier Modifier", HFILL } },
4086
4087
    /* Message identifier */
4088
14
    { &hf_envelope_msg_id,
4089
14
      { "Message Identifier", "dmp.msg_id", FT_UINT16, BASE_DEC,
4090
14
        NULL, 0x0, NULL, HFILL} },
4091
14
    { &hf_envelope_msg_id_12bit,
4092
14
      { "Message Identifier", "dmp.msg_id", FT_UINT16, BASE_DEC,
4093
14
        NULL, 0x0FFF, NULL, HFILL} },
4094
4095
    /* MTS Identifier */
4096
14
    { &hf_envelope_mts_id,
4097
14
      { "MTS Identifier", "dmp.mts_id", FT_STRING, BASE_NONE,
4098
14
        NULL, 0x0, NULL, HFILL } },
4099
4100
    /* IPM Identifier */
4101
14
    { &hf_envelope_ipm_id,
4102
14
      { "IPM Identifier", "dmp.ipm_id", FT_STRING, BASE_NONE,
4103
14
        NULL, 0x0, NULL, HFILL } },
4104
4105
    /* Extensions */
4106
14
    { &hf_extensions,
4107
14
      { "Extensions", "dmp.extensions", FT_NONE, BASE_NONE,
4108
14
        NULL, 0x0, NULL, HFILL} },
4109
14
    { &hf_extension,
4110
14
      { "Extension", "dmp.extension", FT_NONE, BASE_NONE,
4111
14
        NULL, 0x0, NULL, HFILL } },
4112
14
    { &hf_extension_header,
4113
14
      { "Extension Header", "dmp.extension_header", FT_NONE, BASE_NONE,
4114
14
        NULL, 0x0, NULL, HFILL} },
4115
14
    { &hf_extension_more,
4116
14
      { "More Extensions", "dmp.extension_more", FT_BOOLEAN, 8,
4117
14
        TFS (&tfs_present_absent), 0x80, NULL, HFILL } },
4118
14
    { &hf_extension_length,
4119
14
      { "Extension Length (minus one)", "dmp.extension_length", FT_UINT8, BASE_DEC,
4120
14
        NULL, 0x7F, "Extension Length minus one", HFILL } },
4121
14
    { &hf_extension_data,
4122
14
      { "Extension Data", "dmp.extension_data", FT_BYTES, BASE_NONE,
4123
14
        NULL, 0x0, NULL, HFILL } },
4124
4125
    /* Submission time */
4126
14
    { &hf_envelope_subm_time,
4127
14
      { "Submission Time", "dmp.subm_time", FT_UINT16, BASE_HEX,
4128
14
        NULL, 0x0, NULL, HFILL } },
4129
14
    { &hf_envelope_time_diff_present,
4130
14
      { "Time Diff", "dmp.time_diff_present", FT_BOOLEAN, 16,
4131
14
        TFS (&tfs_present_absent), 0x8000, "Time Diff Present", HFILL } },
4132
14
    { &hf_envelope_subm_time_value,
4133
14
      { "Submission Time Value", "dmp.subm_time_value", FT_UINT16,
4134
14
        BASE_HEX, NULL, 0x7FFF, NULL, HFILL } },
4135
14
    { &hf_envelope_time_diff,
4136
14
      { "Time Difference", "dmp.time_diff", FT_UINT8, BASE_HEX,
4137
14
        NULL, 0x0, NULL, HFILL } },
4138
14
    { &hf_envelope_time_diff_value,
4139
14
      { "Time Difference Value", "dmp.time_diff_value", FT_UINT8,
4140
14
        BASE_HEX, NULL, 0x0, NULL, HFILL } },
4141
4142
    /* Envelope flags */
4143
14
    { &hf_envelope_flags,
4144
14
      { "Flags", "dmp.envelope_flags", FT_UINT8, BASE_DEC,
4145
14
        NULL, 0x0, "Envelope Flags", HFILL} },
4146
14
    { &hf_envelope_content_id_discarded,
4147
14
      { "Content Identifier discarded", "dmp.cont_id_discarded",
4148
14
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
4149
14
        NULL, HFILL } },
4150
14
    { &hf_envelope_recip_reassign_prohib,
4151
14
      { "Recipient reassign prohibited","dmp.recip_reassign_prohib",
4152
14
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
4153
14
        NULL, HFILL } },
4154
14
    { &hf_envelope_dl_expansion_prohib,
4155
14
      { "DL expansion prohibited", "dmp.dl_expansion_prohib",
4156
14
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, NULL,
4157
14
        HFILL } },
4158
4159
    /* Recipient Count */
4160
14
    { &hf_envelope_recipients,
4161
14
      { "Recipient Count", "dmp.rec_count", FT_UINT8, BASE_DEC,
4162
14
        NULL, 0x1F, NULL, HFILL} },
4163
14
    { &hf_envelope_ext_recipients,
4164
14
      { "Extended Recipient Count", "dmp.ext_rec_count", FT_UINT16,
4165
14
        BASE_DEC, NULL, 0x7FFF, NULL, HFILL} },
4166
4167
    /*
4168
    ** Address
4169
    */
4170
14
    { &hf_addr_recipient,
4171
14
      { "Recipient Number", "dmp.recipient", FT_NONE, BASE_NONE,
4172
14
        NULL, 0x0, NULL, HFILL } },
4173
14
    { &hf_addr_originator,
4174
14
      { "Originator", "dmp.originator", FT_NONE, BASE_NONE,
4175
14
        NULL, 0x0, NULL, HFILL } },
4176
14
    { &hf_addr_reporting_name,
4177
14
      { "Reporting Name Number", "dmp.reporting_name", FT_NONE,
4178
14
        BASE_NONE, NULL, 0x0, NULL, HFILL } },
4179
14
    { &hf_addr_dl_expanded,
4180
14
      { "DL Expanded", "dmp.dl_expanded", FT_BOOLEAN, BASE_NONE,
4181
14
        NULL, 0x0, "Message has been DL expanded", HFILL } },
4182
14
    { &hf_addr_int_rec,
4183
14
      { "Intended Recipient", "dmp.int_rec", FT_BOOLEAN, BASE_NONE,
4184
14
        NULL, 0x0, "Message has an intended recipient", HFILL } },
4185
4186
    /*
4187
    ** Address Direct
4188
    */
4189
14
    { &hf_addr_dir_addr_ext,
4190
14
      { "Address Extended", "dmp.addr_ext", FT_BOOLEAN, 8,
4191
14
        NULL, 0x80, NULL, HFILL } },
4192
14
    { &hf_addr_dir_rec_no,
4193
14
      { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8,
4194
14
        BASE_DEC, NULL, 0xF0, NULL, HFILL } },
4195
14
    { &hf_addr_dir_rec_no_generated,
4196
14
      { "Recipient Number", "dmp.rec_no", FT_UINT32,
4197
14
        BASE_DEC, NULL, 0x0, "Recipient Number Offset", HFILL } },
4198
14
    { &hf_addr_dir_rec_no1,
4199
14
      { "Recipient Number (bits 3-0)", "dmp.rec_no_offset1", FT_UINT8,
4200
14
        BASE_DEC, NULL, 0xF0, "Recipient Number (bits 3-0) Offset", HFILL } },
4201
14
    { &hf_addr_dir_rec_no2,
4202
14
      { "Recipient Number (bits 9-4)", "dmp.rec_no_offset2", FT_UINT8,
4203
14
        BASE_DEC, NULL, 0x3F, "Recipient Number (bits 9-4) Offset", HFILL } },
4204
14
    { &hf_addr_dir_rec_no3,
4205
14
      { "Recipient Number (bits 14-10)", "dmp.rec_no_offset3", FT_UINT8,
4206
14
        BASE_DEC, NULL, 0x1F, "Recipient Number (bits 14-10) Offset",HFILL } },
4207
14
    { &hf_addr_dir_rep_req1,
4208
14
      { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
4209
14
        VALS (report_vals_ext), 0x0C, NULL, HFILL } },
4210
14
    { &hf_addr_dir_rep_req2,
4211
14
      { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
4212
14
        VALS (report_vals_ext), 0xC0, NULL, HFILL } },
4213
14
    { &hf_addr_dir_rep_req3,
4214
14
      { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
4215
14
        VALS (report_vals), 0xC0, NULL, HFILL } },
4216
14
    { &hf_addr_dir_not_req1,
4217
14
      { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
4218
14
        VALS (notif_vals_ext), 0x03, NULL, HFILL } },
4219
14
    { &hf_addr_dir_not_req2,
4220
14
      { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
4221
14
        VALS (notif_vals_ext), 0xC0, NULL, HFILL } },
4222
14
    { &hf_addr_dir_not_req3,
4223
14
      { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
4224
14
        VALS (notif_vals), 0xC0, NULL, HFILL } },
4225
14
    { &hf_addr_dir_action,
4226
14
      { "Action", "dmp.action", FT_BOOLEAN, 8,
4227
14
        TFS (&tfs_yes_no), 0x80, NULL, HFILL } },
4228
14
    { &hf_addr_dir_address,
4229
14
      { "Direct Address", "dmp.direct_addr", FT_UINT8,
4230
14
        BASE_DEC, NULL, 0x7F, NULL, HFILL } },
4231
14
    { &hf_addr_dir_address_generated,
4232
14
      { "Direct Address", "dmp.direct_addr", FT_UINT32,
4233
14
        BASE_DEC, NULL, 0x0, NULL, HFILL } },
4234
14
    { &hf_addr_dir_address1,
4235
14
      { "Direct Address (bits 6-0)", "dmp.direct_addr1", FT_UINT8,
4236
14
        BASE_DEC, NULL, 0x7F, NULL, HFILL } },
4237
14
    { &hf_addr_dir_address2,
4238
14
      { "Direct Address (bits 12-7)", "dmp.direct_addr2", FT_UINT8,
4239
14
        BASE_DEC, NULL, 0x3F, NULL, HFILL } },
4240
14
    { &hf_addr_dir_address3,
4241
14
      { "Direct Address (bits 18-13)", "dmp.direct_addr3", FT_UINT8,
4242
14
        BASE_DEC, NULL, 0x3F, NULL, HFILL } },
4243
4244
    /*
4245
    ** Address Extended
4246
    */
4247
14
    { &hf_addr_ext_form,
4248
14
      { "Address Form", "dmp.addr_form", FT_UINT8, BASE_DEC,
4249
14
        VALS (addr_form), 0xE0, NULL, HFILL } },
4250
14
    { &hf_addr_ext_form_orig_v1,
4251
14
      { "Address Form", "dmp.addr_form", FT_UINT8, BASE_DEC,
4252
14
        VALS (addr_form_orig_v1), 0xE0, NULL, HFILL } },
4253
14
    { &hf_addr_ext_form_orig,
4254
14
      { "Address Form", "dmp.addr_form", FT_UINT8, BASE_DEC,
4255
14
        VALS (addr_form_orig), 0xE0, NULL, HFILL } },
4256
14
    { &hf_addr_ext_action,
4257
14
      { "Action", "dmp.action", FT_BOOLEAN, 8,
4258
14
        TFS (&tfs_yes_no), 0x10, NULL, HFILL } },
4259
14
    { &hf_addr_ext_rep_req,
4260
14
      { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
4261
14
        VALS (report_vals), 0x0C, NULL, HFILL } },
4262
14
    { &hf_addr_ext_not_req,
4263
14
      { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
4264
14
        VALS (notif_vals), 0x03, NULL, HFILL } },
4265
14
    { &hf_addr_ext_rec_ext,
4266
14
      { "Recipient Number Extended", "dmp.rec_no_ext", FT_BOOLEAN, 8,
4267
14
        NULL, 0x80, NULL, HFILL } },
4268
14
    { &hf_addr_ext_rec_no,
4269
14
      { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8,
4270
14
        BASE_DEC, NULL, 0x7F, NULL, HFILL } },
4271
14
    { &hf_addr_ext_rec_no_generated,
4272
14
      { "Recipient Number", "dmp.rec_no", FT_UINT32,
4273
14
        BASE_DEC, NULL, 0x0, NULL, HFILL } },
4274
14
    { &hf_addr_ext_rec_no1,
4275
14
      { "Recipient Number (bits 6-0)", "dmp.rec_no_offset1", FT_UINT8,
4276
14
        BASE_DEC, NULL, 0x7F, "Recipient Number (bits 6-0) Offset", HFILL } },
4277
14
    { &hf_addr_ext_rec_no2,
4278
14
      { "Recipient Number (bits 14-7)", "dmp.rec_no_offset2", FT_UINT8,
4279
14
        BASE_DEC, NULL, 0x0, "Recipient Number (bits 14-7) Offset", HFILL } },
4280
14
    { &hf_addr_ext_address,
4281
14
      { "Extended Address", "dmp.addr_form_ext", FT_NONE, BASE_NONE,
4282
14
        NULL, 0x0, NULL, HFILL } },
4283
14
    { &hf_addr_ext_type,
4284
14
      { "Address Type", "dmp.addr_type", FT_UINT8, BASE_DEC,
4285
14
        VALS (ext_addr_type), 0xE0, NULL, HFILL } },
4286
14
    { &hf_addr_ext_type_ext,
4287
14
      { "Address Type Extended", "dmp.addr_type_ext", FT_UINT8,
4288
14
        BASE_DEC, VALS (ext_addr_type_ext), 0xE0, NULL,
4289
14
        HFILL } },
4290
14
    { &hf_addr_ext_length,
4291
14
      { "Address Length", "dmp.addr_length", FT_UINT8,
4292
14
        BASE_DEC, NULL, 0x1F, NULL, HFILL } },
4293
14
    { &hf_addr_ext_length_generated,
4294
14
      { "Address Length", "dmp.addr_length", FT_UINT32,
4295
14
        BASE_DEC, NULL, 0x0, NULL, HFILL } },
4296
14
    { &hf_addr_ext_length1,
4297
14
      { "Address Length (bits 4-0)", "dmp.addr_length1", FT_UINT8,
4298
14
        BASE_DEC, NULL, 0x1F, NULL, HFILL } },
4299
14
    { &hf_addr_ext_length2,
4300
14
      { "Address Length (bits 9-5)", "dmp.addr_length2", FT_UINT8,
4301
14
        BASE_DEC, NULL, 0x1F, NULL, HFILL } },
4302
14
    { &hf_addr_ext_asn1_ber,
4303
14
      { "ASN.1 BER-encoded OR-name", "dmp.or_name", FT_NONE,
4304
14
        BASE_NONE, NULL, 0x0, NULL, HFILL } },
4305
14
    { &hf_addr_ext_asn1_per,
4306
14
      { "ASN.1 PER-encoded OR-name", "dmp.asn1_per", FT_BYTES,
4307
14
        BASE_NONE, NULL, 0x0, NULL, HFILL } },
4308
14
    { &hf_addr_ext_unknown,
4309
14
      { "Unknown encoded address", "dmp.addr_unknown", FT_BYTES,
4310
14
        BASE_NONE, NULL, 0x0, NULL, HFILL } },
4311
4312
    /*
4313
    ** Message content
4314
    */
4315
14
    { &hf_message_content,
4316
14
      { "Message Content", "dmp.message", FT_NONE, BASE_NONE,
4317
14
        NULL, 0x0, NULL, HFILL } },
4318
14
    { &hf_report_content,
4319
14
      { "Report Content", "dmp.report", FT_NONE, BASE_NONE,
4320
14
        NULL, 0x0, NULL, HFILL } },
4321
14
    { &hf_notif_content,
4322
14
      { "Notification Content", "dmp.notification", FT_NONE, BASE_NONE,
4323
14
        NULL, 0x0, NULL, HFILL } },
4324
4325
14
    { &hf_message_st_type,
4326
14
      { "Message type", "dmp.msg_type", FT_UINT8, BASE_DEC,
4327
14
        VALS (message_type_vals), 0xC0, NULL, HFILL } },
4328
14
    { &hf_message_precedence,
4329
14
      { "Precedence", "dmp.precedence", FT_UINT8, BASE_DEC,
4330
14
        VALS (precedence), 0x1C, NULL, HFILL } },
4331
14
    { &hf_message_importance,
4332
14
      { "Importance", "dmp.importance", FT_UINT8, BASE_DEC,
4333
14
        VALS (importance), 0x1C, NULL, HFILL } },
4334
14
    { &hf_message_body_format,
4335
14
      { "Body format", "dmp.body_format", FT_UINT8, BASE_DEC,
4336
14
        VALS (body_format_vals), 0x03, NULL, HFILL } },
4337
4338
    /* Security Values */
4339
14
    { &hf_message_sec_label,
4340
14
      { "Security Label", "dmp.sec_label", FT_STRING, BASE_NONE,
4341
14
        NULL, 0x0, NULL, HFILL } },
4342
14
    { &hf_message_sec_class_val,
4343
14
      { "Security Classification", "dmp.sec_class", FT_UINT8,
4344
14
        BASE_DEC, NULL, 0xE0, NULL, HFILL} },
4345
14
    { &hf_message_sec_pol,
4346
14
      { "Security Policy", "dmp.sec_pol", FT_UINT8, BASE_DEC,
4347
14
        VALS (sec_pol), 0x1C, NULL, HFILL } },
4348
14
    { &hf_message_heading_flags,
4349
14
      { "Heading Flags", "dmp.heading_flags", FT_NONE, BASE_NONE,
4350
14
        NULL, 0x0, NULL, HFILL } },
4351
14
    { &hf_message_auth_users,
4352
14
      { "Authorizing users discarded", "dmp.auth_discarded",
4353
14
        FT_BOOLEAN, 8, TFS (&tfs_yes_no), 0x02,
4354
14
        NULL, HFILL } },
4355
14
    { &hf_message_subject_disc,
4356
14
      { "Subject discarded", "dmp.subject_discarded", FT_BOOLEAN, 8,
4357
14
        TFS (&tfs_yes_no), 0x01, NULL, HFILL } },
4358
4359
    /* National Policy Identifier */
4360
14
    { &hf_message_national_policy_id,
4361
14
      { "National Policy Identifier", "dmp.nat_pol_id", FT_UINT8,
4362
14
        BASE_DEC, VALS(nat_pol_id), 0x0, NULL,
4363
14
        HFILL } },
4364
4365
    /* Mission Policy Identifier */
4366
14
    { &hf_message_mission_policy_id,
4367
14
      { "Mission Policy Identifier", "dmp.mission_pol_id", FT_UINT8,
4368
14
        BASE_DEC, NULL, 0x0, NULL,
4369
14
        HFILL } },
4370
4371
    /* Security Categories */
4372
14
    { &hf_message_sec_cat_nat,
4373
14
      { "Security Categories", "dmp.sec_cat", FT_UINT8, BASE_HEX,
4374
14
        NULL, 0x0, NULL, HFILL } },
4375
14
    { &hf_message_sec_cat_val,
4376
14
      { "Security Categories", "dmp.sec_cat", FT_UINT8, BASE_HEX,
4377
14
        NULL, 0x0, NULL, HFILL } },
4378
14
    { &hf_message_sec_cat_cl,
4379
14
      { "Clear", "dmp.sec_cat.cl", FT_BOOLEAN, 8,
4380
14
        TFS (&tfs_set_notset), 0x80, NULL, HFILL } },
4381
14
    { &hf_message_sec_cat_cs,
4382
14
      { "Crypto Security", "dmp.sec_cat.cs", FT_BOOLEAN, 8,
4383
14
        TFS (&tfs_set_notset), 0x40, NULL, HFILL } },
4384
14
    { &hf_message_sec_cat_ex,
4385
14
      { "Exclusive", "dmp.sec_cat.ex", FT_BOOLEAN, 8,
4386
14
        TFS (&tfs_set_notset), 0x20, NULL, HFILL } },
4387
14
    { &hf_message_sec_cat_ne,
4388
14
      { "National Eyes Only", "dmp.sec_cat.ne", FT_BOOLEAN, 8,
4389
14
        TFS (&tfs_set_notset), 0x10, NULL, HFILL } },
4390
14
    { &hf_message_sec_cat_permissive,
4391
14
      { "Releasable to", "dmp.sec_cat.permissive", FT_UINT8, BASE_HEX,
4392
14
        VALS (nat_pol_id), 0xFC, NULL, HFILL } },
4393
14
    { &hf_message_sec_cat_country_code,
4394
14
      { "Country Code", "dmp.sec_cat.country", FT_UINT8, BASE_DEC,
4395
14
        NULL, 0x00, NULL, HFILL } },
4396
14
    { &hf_message_sec_cat_restrictive,
4397
14
      { "Restrictive", "dmp.sec_cat.restrictive", FT_UINT8, BASE_HEX,
4398
14
        NULL, 0xFC, NULL, HFILL } },
4399
14
    { &hf_message_sec_cat_extended,
4400
14
      { "Extended", "dmp.sec_cat.extended", FT_UINT8, BASE_HEX,
4401
14
        VALS (ext_sec_cat), 0x03, "Extended Security Category", HFILL } },
4402
14
    { &hf_message_sec_cat_bit0,
4403
14
      { "Bit 0", "dmp.sec_cat.bit0", FT_BOOLEAN, 8,
4404
14
        TFS (&tfs_set_notset), 0x01, NULL, HFILL } },
4405
14
    { &hf_message_sec_cat_bit1,
4406
14
      { "Bit 1", "dmp.sec_cat.bit1", FT_BOOLEAN, 8,
4407
14
        TFS (&tfs_set_notset), 0x02, NULL, HFILL } },
4408
14
    { &hf_message_sec_cat_bit2,
4409
14
      { "Bit 2", "dmp.sec_cat.bit2", FT_BOOLEAN, 8,
4410
14
        TFS (&tfs_set_notset), 0x04, NULL, HFILL } },
4411
14
    { &hf_message_sec_cat_bit3,
4412
14
      { "Bit 3", "dmp.sec_cat.bit3", FT_BOOLEAN, 8,
4413
14
        TFS (&tfs_set_notset), 0x08, NULL, HFILL } },
4414
14
    { &hf_message_sec_cat_bit4,
4415
14
      { "Bit 4", "dmp.sec_cat.bit4", FT_BOOLEAN, 8,
4416
14
        TFS (&tfs_set_notset), 0x10, NULL, HFILL } },
4417
14
    { &hf_message_sec_cat_bit5,
4418
14
      { "Bit 5", "dmp.sec_cat.bit5", FT_BOOLEAN, 8,
4419
14
        TFS (&tfs_set_notset), 0x20, NULL, HFILL } },
4420
14
    { &hf_message_sec_cat_bit6,
4421
14
      { "Bit 6", "dmp.sec_cat.bit6", FT_BOOLEAN, 8,
4422
14
        TFS (&tfs_set_notset), 0x40, NULL, HFILL } },
4423
14
    { &hf_message_sec_cat_bit7,
4424
14
      { "Bit 7", "dmp.sec_cat.bit7", FT_BOOLEAN, 8,
4425
14
        TFS (&tfs_set_notset), 0x80, NULL, HFILL } },
4426
4427
    /* Expiry Time */
4428
14
    { &hf_message_exp_time,
4429
14
      { "Expiry Time", "dmp.expiry_time", FT_UINT8, BASE_HEX,
4430
14
        NULL, 0x0, NULL, HFILL } },
4431
14
    { &hf_message_exp_time_val,
4432
14
      { "Expiry Time Value", "dmp.expiry_time_val", FT_UINT8, BASE_HEX,
4433
14
        NULL, 0x0, NULL, HFILL } },
4434
4435
    /* DTG */
4436
14
    { &hf_message_dtg,
4437
14
      { "DTG", "dmp.dtg", FT_UINT8, BASE_HEX,
4438
14
        NULL, 0x0, NULL, HFILL } },
4439
14
    { &hf_message_dtg_sign,
4440
14
      { "DTG in the", "dmp.dtg.sign", FT_BOOLEAN, 8, TFS (&dtg_sign),
4441
14
        0x80, "Sign", HFILL } },
4442
14
    { &hf_message_dtg_val,
4443
14
      { "DTG Value", "dmp.dtg.val", FT_UINT8, BASE_HEX, NULL,
4444
14
        0x7F, NULL, HFILL } },
4445
4446
    /* SIC */
4447
14
    { &hf_message_sic,
4448
14
      { "SIC", "dmp.sic", FT_STRING, BASE_NONE,
4449
14
        NULL, 0x0, NULL, HFILL } },
4450
14
    { &hf_message_sic_key,
4451
14
      { "SICs", "dmp.sic_key", FT_NONE, BASE_NONE,
4452
14
        NULL, 0x0, "SIC Content", HFILL } },
4453
14
    { &hf_message_sic_key_values,
4454
14
      { "Content Byte", "dmp.sic_key.values", FT_UINT8, BASE_HEX,
4455
14
        NULL, 0x0, "SIC Content Byte", HFILL } },
4456
14
    { &hf_message_sic_key_type,
4457
14
      { "Type", "dmp.sic_key.type", FT_UINT8, BASE_HEX,
4458
14
        VALS (sic_key_type), 0xF0, "SIC Content Type", HFILL } },
4459
14
    { &hf_message_sic_key_chars,
4460
14
      { "Valid Characters", "dmp.sic_key.chars", FT_BOOLEAN, 8,
4461
14
        TFS (&sic_key_chars), 0x08, "SIC Valid Characters", HFILL } },
4462
14
    { &hf_message_sic_key_num,
4463
14
      { "Number of SICs", "dmp.sic_key.num", FT_UINT8, BASE_HEX,
4464
14
        VALS (sic_key_num), 0x07, NULL, HFILL } },
4465
14
    { &hf_message_sic_bitmap,
4466
14
      { "Length Bitmap (0 = 3 bytes, 1 = 4-8 bytes)", "dmp.sic_bitmap",
4467
14
        FT_UINT8, BASE_HEX, NULL, 0xFF, "SIC Length Bitmap", HFILL } },
4468
14
    { &hf_message_sic_bits,
4469
14
      { "Bit 7-4", "dmp.sic_bits", FT_UINT8, BASE_HEX,
4470
14
        VALS(sic_bit_vals), 0xF0, "SIC Bit 7-4, Characters [A-Z0-9] only",
4471
14
        HFILL } },
4472
14
    { &hf_message_sic_bits_any,
4473
14
      { "Bit 7-4", "dmp.sic_bits_any", FT_UINT8, BASE_HEX,
4474
14
        VALS(sic_bit_any_vals), 0xF0, "SIC Bit 7-4, Any valid characters",
4475
14
        HFILL } },
4476
4477
    /* Subject Message Id */
4478
14
    { &hf_message_subj_id,
4479
14
      { "Subject Message Identifier", "dmp.subj_id", FT_UINT16,
4480
14
        BASE_DEC, NULL, 0x0, NULL, HFILL } },
4481
4482
    /* Subject MTS Identifier */
4483
14
    { &hf_message_subj_mts_id,
4484
14
      { "Subject MTS Identifier", "dmp.subj_mts_id", FT_STRING, BASE_NONE,
4485
14
        NULL, 0x0, NULL, HFILL } },
4486
4487
    /* Subject IPM Identifier */
4488
14
    { &hf_message_subj_ipm_id,
4489
14
      { "Subject IPM Identifier", "dmp.subj_ipm_id", FT_STRING, BASE_NONE,
4490
14
        NULL, 0x0, NULL, HFILL } },
4491
4492
    /*
4493
    ** Message body
4494
    */
4495
14
    { &hf_message_body,
4496
14
      { "Message Body", "dmp.body", FT_NONE, BASE_NONE, NULL,
4497
14
        0x0, NULL, HFILL} },
4498
4499
    /* Body Id */
4500
14
    { &hf_message_eit,
4501
14
      { "EIT", "dmp.body.eit", FT_UINT8, BASE_DEC,
4502
14
        VALS(eit_vals), 0xE0, "Encoded Information Type", HFILL } },
4503
14
    { &hf_message_compr,
4504
14
      { "Compression", "dmp.body.compression", FT_UINT8, BASE_DEC,
4505
14
        VALS(compression_vals), 0x18, NULL, HFILL } },
4506
4507
    /* Subject */
4508
14
    { &hf_message_subject,
4509
14
      { "Subject", "dmp.subject", FT_STRINGZ, BASE_NONE,
4510
14
        NULL, 0x0, NULL, HFILL } },
4511
4512
    /* Message Body */
4513
14
    { &hf_message_body_data,
4514
14
      { "User data", "dmp.body.data", FT_BYTES, BASE_NONE,
4515
14
        NULL, 0x0, NULL, HFILL } },
4516
14
    { &hf_message_body_compressed,
4517
14
      { "Compressed User data", "dmp.body.compressed", FT_NONE, BASE_NONE,
4518
14
        NULL, 0x0, NULL, HFILL } },
4519
14
    { &hf_message_body_plain,
4520
14
      { "Message Body", "dmp.body.plain", FT_STRING, BASE_NONE,
4521
14
        NULL, 0x0, NULL, HFILL } },
4522
14
    { &hf_message_body_structured,
4523
14
      { "Structured Body", "dmp.body.structured", FT_BYTES, BASE_NONE,
4524
14
        NULL, 0x0, NULL, HFILL } },
4525
4526
    /*
4527
    ** Report
4528
    */
4529
14
    { &hf_delivery_report,
4530
14
      { "Delivery Report", "dmp.dr", FT_NONE, BASE_NONE, NULL,
4531
14
        0x0, NULL, HFILL} },
4532
14
    { &hf_non_delivery_report,
4533
14
      { "Non-Delivery Report", "dmp.ndr", FT_NONE, BASE_NONE, NULL,
4534
14
        0x0, NULL, HFILL} },
4535
4536
14
    { &hf_report_type,
4537
14
      { "Report Type", "dmp.report_type", FT_BOOLEAN, 8,
4538
14
        TFS (&report_type), 0x80, NULL, HFILL } },
4539
14
    { &hf_report_info_present_dr,
4540
14
      { "Info Present", "dmp.info_present", FT_BOOLEAN, 8,
4541
14
        TFS (&tfs_present_absent), 0x40, NULL, HFILL } },
4542
14
    { &hf_report_addr_enc_dr,
4543
14
      { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
4544
14
        TFS (&addr_enc), 0x20, NULL, HFILL } },
4545
14
    { &hf_report_del_time,
4546
14
      { "Delivery Time", "dmp.delivery_time", FT_UINT8, BASE_HEX,
4547
14
        NULL, 0x0, NULL, HFILL } },
4548
14
    { &hf_report_del_time_val,
4549
14
      { "Delivery Time Value", "dmp.delivery_time_val", FT_UINT8,
4550
14
        BASE_HEX, NULL, 0x0, NULL, HFILL } },
4551
14
    { &hf_report_addr_enc_ndr,
4552
14
      { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
4553
14
        TFS (&addr_enc), 0x40, NULL, HFILL } },
4554
14
    { &hf_report_reason,
4555
14
      { "Reason (P1)", "dmp.report_reason", FT_UINT8, BASE_DEC,
4556
14
        VALS (p1_NonDeliveryReasonCode_vals), 0x3F,
4557
14
        NULL, HFILL } },
4558
14
    { &hf_report_info_present_ndr,
4559
14
      { "Info Present", "dmp.info_present", FT_BOOLEAN, 8,
4560
14
        TFS (&tfs_present_absent), 0x80, NULL, HFILL } },
4561
14
    { &hf_report_diagn,
4562
14
      { "Diagnostic (P1)", "dmp.report_diagnostic", FT_UINT8, BASE_DEC,
4563
14
        VALS (p1_NonDeliveryDiagnosticCode_vals), 0x7F,
4564
14
        NULL, HFILL } },
4565
14
    { &hf_report_suppl_info_len,
4566
14
      { "Supplementary Information", "dmp.suppl_info_len", FT_UINT8,
4567
14
        BASE_DEC, NULL, 0x0, "Supplementary Information Length", HFILL } },
4568
14
    { &hf_report_suppl_info,
4569
14
      { "Supplementary Information", "dmp.suppl_info", FT_STRINGZ,
4570
14
        BASE_NONE, NULL, 0x0, NULL, HFILL } },
4571
4572
    /*
4573
    ** Notification
4574
    */
4575
14
    { &hf_receipt_notif,
4576
14
      { "Receipt Notification (RN)", "dmp.rn", FT_NONE, BASE_NONE,
4577
14
        NULL, 0x0, NULL, HFILL} },
4578
14
    { &hf_non_receipt_notif,
4579
14
      { "Non-Receipt Notification (NRN)", "dmp.nrn", FT_NONE, BASE_NONE,
4580
14
        NULL, 0x0, NULL, HFILL} },
4581
14
    { &hf_other_notif,
4582
14
      { "Other Notification (ON)", "dmp.on", FT_NONE, BASE_NONE,
4583
14
        NULL, 0x0, NULL, HFILL} },
4584
4585
14
    { &hf_notif_type,
4586
14
      { "Notification Type", "dmp.notif_type", FT_UINT8, BASE_DEC,
4587
14
        VALS (notif_type), 0x03, NULL, HFILL } },
4588
14
    { &hf_notif_rec_time,
4589
14
      { "Receipt Time", "dmp.receipt_time", FT_UINT8, BASE_HEX,
4590
14
        NULL, 0x0, NULL, HFILL } },
4591
14
    { &hf_notif_rec_time_val,
4592
14
      { "Receipt Time Value", "dmp.receipt_time_val", FT_UINT8,
4593
14
        BASE_HEX, NULL, 0x0, NULL, HFILL } },
4594
14
    { &hf_notif_suppl_info_len,
4595
14
      { "Supplementary Information", "dmp.suppl_info_len",
4596
14
        FT_UINT8, BASE_DEC, NULL, 0x0, "Supplementary Information Length",
4597
14
        HFILL } },
4598
14
    { &hf_notif_suppl_info,
4599
14
      { "Supplementary Information", "dmp.suppl_info",
4600
14
        FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL,
4601
14
        HFILL } },
4602
14
    { &hf_notif_non_rec_reason,
4603
14
      { "Non-Receipt Reason", "dmp.notif_non_rec_reason",
4604
14
        FT_UINT8, BASE_DEC, VALS (p22_NonReceiptReasonField_vals), 0x0,
4605
14
        NULL, HFILL } },
4606
14
    { &hf_notif_discard_reason,
4607
14
      { "Discard Reason", "dmp.notif_discard_reason", FT_UINT8,
4608
14
        BASE_DEC, VALS (p22_DiscardReasonField_vals), 0x0,
4609
14
        NULL, HFILL } },
4610
14
    { &hf_notif_on_type,
4611
14
      { "ON Type", "dmp.notif_on_type", FT_UINT8, BASE_DEC,
4612
14
        VALS (on_type), 0x0, NULL, HFILL } },
4613
14
    { &hf_notif_acp127,
4614
14
      { "ACP127 Recipient", "dmp.acp127recip_len", FT_UINT8,
4615
14
        BASE_DEC, NULL, 0x0, "ACP 127 Recipient Length", HFILL } },
4616
14
    { &hf_notif_acp127recip,
4617
14
      { "ACP127 Recipient", "dmp.acp127recip", FT_STRINGZ,
4618
14
        BASE_NONE, NULL, 0x0, "ACP 127 Recipient", HFILL } },
4619
4620
    /*
4621
    ** Acknowledgement
4622
    */
4623
14
    { &hf_ack,
4624
14
      { "Acknowledgement", "dmp.ack", FT_NONE, BASE_NONE,
4625
14
        NULL, 0x0, NULL, HFILL } },
4626
14
    { &hf_ack_reason,
4627
14
      { "Ack Reason", "dmp.ack_reason", FT_UINT8, BASE_DEC,
4628
14
        VALS (ack_reason), 0x0, NULL, HFILL } },
4629
14
    { &hf_ack_diagnostic,
4630
14
      { "Ack Diagnostic", "dmp.ack_diagnostic", FT_UINT8, BASE_DEC,
4631
14
        NULL, 0x0, NULL, HFILL } },
4632
14
    { &hf_ack_recips,
4633
14
      { "Recipient List", "dmp.ack_rec_list", FT_NONE, BASE_NONE,
4634
14
        NULL, 0x0, NULL, HFILL } },
4635
4636
    /*
4637
    ** Checksum
4638
    */
4639
14
    { &hf_checksum,
4640
14
      { "Checksum", "dmp.checksum", FT_UINT16, BASE_HEX,
4641
14
        NULL, 0x0, NULL, HFILL } },
4642
14
    { &hf_checksum_status,
4643
14
      { "Checksum Status", "dmp.checksum.status", FT_UINT8, BASE_NONE,
4644
14
        VALS(proto_checksum_vals), 0x0, NULL, HFILL } },
4645
4646
    /*
4647
    ** Ack matching / Resend
4648
    */
4649
14
    { &hf_analysis_ack_time,
4650
14
      { "Acknowledgement Time", "dmp.analysis.ack_time", FT_RELATIVE_TIME, BASE_NONE,
4651
14
        NULL, 0x0, "The time between the Message and the Acknowledge", HFILL } },
4652
14
    { &hf_analysis_rep_time,
4653
14
      { "Report Reply Time", "dmp.analysis.report_time", FT_RELATIVE_TIME, BASE_NONE,
4654
14
        NULL, 0x0, "The time between the Message and the Report", HFILL } },
4655
14
    { &hf_analysis_not_time,
4656
14
      { "Notification Reply Time", "dmp.analysis.notif_time", FT_RELATIVE_TIME, BASE_NONE,
4657
14
        NULL, 0x0, "The time between the Message and the Notification", HFILL } },
4658
14
    { &hf_analysis_total_time,
4659
14
      { "Total Time", "dmp.analysis.total_time", FT_RELATIVE_TIME, BASE_NONE,
4660
14
        NULL, 0x0, "The time between the first Message and the Acknowledge", HFILL } },
4661
14
    { &hf_analysis_retrans_time,
4662
14
      { "Retransmission Time", "dmp.analysis.retrans_time", FT_RELATIVE_TIME, BASE_NONE,
4663
14
        NULL, 0x0, "The time between the last Message and this Message", HFILL } },
4664
14
    { &hf_analysis_total_retrans_time,
4665
14
      { "Total Retransmission Time", "dmp.analysis.total_retrans_time", FT_RELATIVE_TIME, BASE_NONE,
4666
14
        NULL, 0x0, "The time between the first Message and this Message", HFILL } },
4667
14
    { &hf_analysis_msg_num,
4668
14
      { "Message in", "dmp.analysis.msg_in", FT_FRAMENUM, BASE_NONE,
4669
14
        NULL, 0x0, "This packet has a Message in this frame", HFILL } },
4670
14
    { &hf_analysis_acks_msg_num,
4671
14
      { "This is an Ack to the Message in", "dmp.analysis.acks_msg_in", FT_FRAMENUM, BASE_NONE,
4672
14
        FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0, "This packet ACKs a Message in this frame", HFILL } },
4673
14
    { &hf_analysis_ack_num,
4674
14
      { "Acknowledgement in", "dmp.analysis.ack_in", FT_FRAMENUM, BASE_NONE,
4675
14
        NULL, 0x0, "This packet has an Acknowledgement in this frame", HFILL } },
4676
14
    { &hf_analysis_acks_rep_num,
4677
14
      { "This is an Ack to the Report in", "dmp.analysis.acks_report_in", FT_FRAMENUM, BASE_NONE,
4678
14
        FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0, "This packet ACKs a Report in this frame", HFILL } },
4679
#if 0
4680
    { &hf_analysis_rep_num,
4681
      { "Report in", "dmp.analysis.report_in", FT_FRAMENUM, BASE_NONE,
4682
        NULL, 0x0, "This packet has a Report in this frame", HFILL } },
4683
    { &hf_analysis_not_num,
4684
      { "Notification in", "dmp.analysis.notif_in", FT_FRAMENUM, BASE_NONE,
4685
        NULL, 0x0, "This packet has a Notification in this frame", HFILL } },
4686
#endif
4687
14
    { &hf_analysis_acks_not_num,
4688
14
      { "This is an Ack to the Notification in", "dmp.analysis.acks_notif_in", FT_FRAMENUM, BASE_NONE,
4689
14
        FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0, "This packet ACKs a Notification in this frame", HFILL } },
4690
14
    { &hf_analysis_ack_missing,
4691
14
      { "Acknowledgement missing", "dmp.analysis.ack_missing", FT_NONE, BASE_NONE,
4692
14
        NULL, 0x0, "The acknowledgement for this packet is missing", HFILL } },
4693
14
    { &hf_analysis_retrans_no,
4694
14
      { "Retransmission #", "dmp.analysis.retrans_no", FT_UINT32, BASE_DEC,
4695
14
        NULL, 0x0, "Retransmission count", HFILL } },
4696
14
    { &hf_analysis_ack_dup_no,
4697
14
      { "Duplicate ACK #", "dmp.analysis.dup_ack_no", FT_UINT32, BASE_DEC,
4698
14
        NULL, 0x0, "Duplicate Acknowledgement count", HFILL } },
4699
14
    { &hf_analysis_msg_resend_from,
4700
14
      { "Retransmission of Message sent in", "dmp.analysis.msg_first_sent_in",
4701
14
        FT_FRAMENUM, BASE_NONE,
4702
14
        NULL, 0x0, "This Message was first sent in this frame", HFILL } },
4703
14
    { &hf_analysis_rep_resend_from,
4704
14
      { "Retransmission of Report sent in", "dmp.analysis.report_first_sent_in",
4705
14
        FT_FRAMENUM, BASE_NONE,
4706
14
        NULL, 0x0, "This Report was first sent in this frame", HFILL } },
4707
14
    { &hf_analysis_not_resend_from,
4708
14
      { "Retransmission of Notification sent in", "dmp.analysis.notif_first_sent_in",
4709
14
        FT_FRAMENUM, BASE_NONE,
4710
14
        NULL, 0x0, "This Notification was first sent in this frame", HFILL } },
4711
14
    { &hf_analysis_ack_resend_from,
4712
14
      { "Retransmission of Acknowledgement sent in", "dmp.analysis.ack_first_sent_in",
4713
14
        FT_FRAMENUM, BASE_NONE,
4714
14
        NULL, 0x0, "This Acknowledgement was first sent in this frame", HFILL } },
4715
4716
    /*
4717
    ** Reserved values
4718
    */
4719
14
    { &hf_reserved_0x01,
4720
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4721
14
        NULL, 0x01, NULL, HFILL } },
4722
14
    { &hf_reserved_0x02,
4723
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4724
14
        NULL, 0x02, NULL, HFILL } },
4725
14
    { &hf_reserved_0x04,
4726
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4727
14
        NULL, 0x04, NULL, HFILL } },
4728
14
    { &hf_reserved_0x07,
4729
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4730
14
        NULL, 0x07, NULL, HFILL } },
4731
14
    { &hf_reserved_0x08,
4732
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4733
14
        NULL, 0x08, NULL, HFILL } },
4734
14
    { &hf_reserved_0x0F,
4735
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4736
14
        NULL, 0x0F, NULL, HFILL } },
4737
14
    { &hf_reserved_0x1F,
4738
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4739
14
        NULL, 0x1F, NULL, HFILL } },
4740
14
    { &hf_reserved_0x20,
4741
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4742
14
        NULL, 0x20, NULL, HFILL } },
4743
14
    { &hf_reserved_0x40,
4744
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4745
14
        NULL, 0x40, NULL, HFILL } },
4746
14
    { &hf_reserved_0xC0,
4747
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4748
14
        NULL, 0xC0, NULL, HFILL } },
4749
14
    { &hf_reserved_0xE0,
4750
14
      { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4751
14
        NULL, 0xE0, NULL, HFILL } },
4752
14
    { &hf_reserved_0x8000,
4753
14
      { "Reserved", "dmp.reserved", FT_UINT16, BASE_DEC,
4754
14
        NULL, 0x8000, NULL, HFILL } },
4755
14
  };
4756
4757
14
  static int *ett[] = {
4758
14
    &ett_dmp,
4759
14
    &ett_envelope,
4760
14
    &ett_envelope_version,
4761
14
    &ett_envelope_hop_count,
4762
14
    &ett_envelope_rec_present,
4763
14
    &ett_envelope_addr_enc,
4764
14
    &ett_envelope_checksum,
4765
14
    &ett_envelope_extensions,
4766
14
    &ett_envelope_msg_id_type,
4767
14
    &ett_envelope_msg_id,
4768
14
    &ett_envelope_mts_id_length,
4769
14
    &ett_envelope_ipm_id_length,
4770
14
    &ett_envelope_cont_type,
4771
14
    &ett_envelope_subm_time,
4772
14
    &ett_envelope_time_diff,
4773
14
    &ett_envelope_flags,
4774
14
    &ett_envelope_recipients,
4775
14
    &ett_envelope_ext_recipients,
4776
14
    &ett_envelope_addresses,
4777
14
    &ett_address,
4778
14
    &ett_address_direct,
4779
14
    &ett_address_rec_no,
4780
14
    &ett_address_extended,
4781
14
    &ett_address_ext_form,
4782
14
    &ett_address_ext_rec_no,
4783
14
    &ett_address_ext_action,
4784
14
    &ett_address_ext_rep_req,
4785
14
    &ett_address_ext_not_req,
4786
14
    &ett_address_ext_type,
4787
14
    &ett_address_ext_length,
4788
14
    &ett_extensions,
4789
14
    &ett_extension,
4790
14
    &ett_extension_header,
4791
14
    &ett_content,
4792
14
    &ett_message,
4793
14
    &ett_message_st_type,
4794
14
    &ett_message_reserved,
4795
14
    &ett_message_precedence,
4796
14
    &ett_message_importance,
4797
14
    &ett_message_body_format,
4798
14
    &ett_message_sec_class,
4799
14
    &ett_message_sec_pol,
4800
14
    &ett_message_sec_cat,
4801
14
    &ett_message_heading_flags,
4802
14
    &ett_message_exp_time,
4803
14
    &ett_message_dtg,
4804
14
    &ett_message_sic,
4805
14
    &ett_message_sic_key,
4806
14
    &ett_message_sic_bitmap,
4807
14
    &ett_message_sic_bits,
4808
14
    &ett_message_eit,
4809
14
    &ett_message_compr,
4810
14
    &ett_message_body_reserved,
4811
14
    &ett_message_body,
4812
14
    &ett_report,
4813
14
    &ett_report_type,
4814
14
    &ett_report_info_present_dr,
4815
14
    &ett_report_info_present_ndr,
4816
14
    &ett_report_addr_enc_dr,
4817
14
    &ett_report_addr_enc_ndr,
4818
14
    &ett_report_reserved,
4819
14
    &ett_report_del_time,
4820
14
    &ett_report_reason,
4821
14
    &ett_report_suppl_info,
4822
14
    &ett_report_diagn,
4823
14
    &ett_notif,
4824
14
    &ett_notif_type,
4825
14
    &ett_notif_rec_time,
4826
14
    &ett_notif_suppl_info,
4827
14
    &ett_notif_acp127recip,
4828
14
    &ett_ack,
4829
14
    &ett_ack_recips,
4830
14
    &ett_analysis
4831
14
  };
4832
4833
14
  static ei_register_info ei[] = {
4834
14
    { &ei_reserved_value,
4835
14
      { "dmp.reserved.expert", PI_UNDECODED, PI_WARN,
4836
14
        "Reserved value", EXPFILL } },
4837
14
    { &ei_message_sic_illegal,
4838
14
      { "dmp.sic.illegal", PI_UNDECODED, PI_NOTE,
4839
14
        "Illegal SIC", EXPFILL } },
4840
14
    { &ei_analysis_ack_unexpected,
4841
14
      { "dmp.analysis.ack_unexpected", PI_SEQUENCE, PI_NOTE,
4842
14
        "Unexpected ACK", EXPFILL } },
4843
14
    { &ei_analysis_ack_missing,
4844
14
      { "dmp.analysis.ack_missing.expert", PI_SEQUENCE, PI_NOTE,
4845
14
        "Acknowledgement missing", EXPFILL } },
4846
14
    { &ei_analysis_msg_missing,
4847
14
      { "dmp.analysis.msg_missing", PI_SEQUENCE, PI_NOTE,
4848
14
        "Message missing", EXPFILL } },
4849
14
    { &ei_analysis_retrans_no,
4850
14
      { "dmp.analysis.retrans_no.expert", PI_SEQUENCE, PI_NOTE,
4851
14
        "Retransmission #", EXPFILL } },
4852
14
    { &ei_analysis_ack_dup_no,
4853
14
      { "dmp.analysis.dup_ack_no.expert", PI_SEQUENCE, PI_NOTE,
4854
14
        "Dup ACK #", EXPFILL } },
4855
14
    { &ei_addr_ext_rec_no_generated,
4856
14
      { "dmp.rec_no.expert", PI_MALFORMED, PI_WARN,
4857
14
        "Recipient number too big", EXPFILL } },
4858
14
    { &ei_ack_reason,
4859
14
      { "dmp.ack_reason.expert", PI_RESPONSE_CODE, PI_NOTE,
4860
14
        "ACK reason", EXPFILL } },
4861
14
    { &ei_envelope_version_value,
4862
14
      { "dmp.version_value.unsupported", PI_UNDECODED, PI_ERROR,
4863
14
        "Unsupported DMP Version", EXPFILL } },
4864
14
    { &ei_envelope_msg_id,
4865
14
      { "dmp.msg_id.short_id", PI_PROTOCOL, PI_NOTE,
4866
14
        "Id < 4096 - should use ShortId", EXPFILL } },
4867
14
    { &ei_7bit_string_unused_bits,
4868
14
      { "dmp.7bit_string.unused_bits", PI_PROTOCOL, PI_WARN,
4869
14
        "Unused bits in last byte shall be null", EXPFILL } },
4870
14
    { &ei_message_compr,
4871
14
      { "dmp.body.compression.unknown", PI_UNDECODED, PI_WARN,
4872
14
        "Unknown compression algorithm", EXPFILL } },
4873
14
    { &ei_message_body_uncompress,
4874
14
      { "dmp.body.uncompress.fail", PI_UNDECODED, PI_WARN,
4875
14
        "Error: Unable to uncompress content", EXPFILL } },
4876
14
    { &ei_checksum_bad,
4877
14
      { "dmp.checksum_bad.expert", PI_CHECKSUM, PI_WARN,
4878
14
        "Bad checksum", EXPFILL } },
4879
14
    { &ei_too_many_sec_cat,
4880
14
      { "dmp.too_many_security_categories", PI_PROTOCOL, PI_ERROR,
4881
14
        "Too many security categories", EXPFILL } },
4882
14
  };
4883
4884
14
  static uat_field_t attributes_flds[] = {
4885
14
    UAT_FLD_VS(dmp_security_class,nation, "Nation", nat_pol_id, 0),
4886
14
    UAT_FLD_DEC(dmp_security_class,sec_class, "Classification", "Security Classification"),
4887
14
    UAT_FLD_CSTRING(dmp_security_class,name, "Name", "Classification Name"),
4888
14
    UAT_END_FIELDS
4889
14
  };
4890
4891
14
  uat_t *attributes_uat = uat_new("DMP Security Classifications",
4892
14
                                  sizeof(dmp_security_class_t),
4893
14
                                  "dmp_security_classifications",
4894
14
                                  true,
4895
14
                                  &dmp_security_classes,
4896
14
                                  &num_dmp_security_classes,
4897
14
                                  UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
4898
14
                                  NULL,
4899
14
                                  dmp_class_copy_cb,
4900
14
                                  NULL,
4901
14
                                  dmp_class_free_cb,
4902
14
                                  NULL,
4903
14
                                  NULL,
4904
14
                                  attributes_flds);
4905
4906
14
  module_t *dmp_module;
4907
14
  expert_module_t* expert_dmp;
4908
4909
14
  proto_dmp = proto_register_protocol (PNAME, PSNAME, PFNAME);
4910
4911
14
  dmp_handle = register_dissector(PFNAME, dissect_dmp, proto_dmp);
4912
4913
14
  proto_register_field_array (proto_dmp, hf, array_length (hf));
4914
14
  proto_register_subtree_array (ett, array_length (ett));
4915
14
  expert_dmp = expert_register_protocol(proto_dmp);
4916
14
  expert_register_field_array(expert_dmp, ei, array_length(ei));
4917
4918
14
  dmp_id_hash_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dmp_id_hash, dmp_id_hash_equal);
4919
14
  dmp_long_id_hash_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash, g_str_equal);
4920
4921
  /* Build national values */
4922
14
  build_national_strings ();
4923
4924
  /* Register our configuration options */
4925
14
  dmp_module = prefs_register_protocol (proto_dmp, NULL);
4926
4927
14
  prefs_register_obsolete_preference (dmp_module, "udp_port");
4928
14
  prefs_register_obsolete_preference (dmp_module, "udp_port_second");
4929
4930
14
  prefs_register_enum_preference (dmp_module, "national_decode",
4931
14
                                  "National decoding",
4932
14
                                  "Select the type of decoding for nationally-defined values",
4933
14
                                  &dmp_nat_decode, national_decoding,
4934
14
                                  false);
4935
14
  prefs_register_enum_preference (dmp_module, "local_nation",
4936
14
                                  "Nation of local server",
4937
14
                                  "Select the nation of sending server.  This is used when presenting"
4938
14
                                  " security classification values in messages with security"
4939
14
                                  " policy set to National (nation of local server)",
4940
14
                                  &dmp_local_nation, dmp_national_values,
4941
14
                                  false);
4942
14
  prefs_register_uat_preference (dmp_module, "classes_table",
4943
14
                                 "National Security Classifications",
4944
14
                                 "Translation table for national security classifications.  This is used"
4945
14
                                 " when presenting security classification values in messages with"
4946
14
                                 " security policy set to National or Extended National",
4947
14
                                 attributes_uat);
4948
14
  prefs_register_bool_preference (dmp_module, "seq_ack_analysis",
4949
14
                                  "SEQ/ACK Analysis",
4950
14
                                  "Calculate sequence/acknowledgement analysis",
4951
14
                                  &use_seq_ack_analysis);
4952
14
  prefs_register_bool_preference (dmp_module, "align_ids",
4953
14
                                  "Align identifiers in info list",
4954
14
                                  "Align identifiers in info list"
4955
14
                                  " (does not align when retransmission or"
4956
14
                                  " duplicate acknowledgement indication)",
4957
14
                                  &dmp_align);
4958
14
  prefs_register_obsolete_preference(dmp_module, "subject_as_id");
4959
14
  prefs_register_obsolete_preference(dmp_module, "struct_print");
4960
14
  prefs_register_obsolete_preference(dmp_module, "struct_offset");
4961
14
  prefs_register_obsolete_preference(dmp_module, "struct_length");
4962
14
}
4963
4964
void proto_reg_handoff_dmp (void)
4965
14
{
4966
14
  dissector_add_uint ("s5066sis.ctl.appid", S5066_CLIENT_S4406_ANNEX_E_TMI_4_DMP, dmp_handle);
4967
14
  dissector_add_uint_range_with_preference("udp.port", DEFAULT_DMP_PORT_RANGE, dmp_handle);
4968
14
}
4969
4970
/*
4971
 * Editor modelines
4972
 *
4973
 * Local Variables:
4974
 * c-basic-offset: 2
4975
 * tab-width: 8
4976
 * indent-tabs-mode: nil
4977
 * End:
4978
 *
4979
 * ex: set shiftwidth=2 tabstop=8 expandtab:
4980
 * :indentSize=2:tabSize=8:noTabs=true:
4981
 */
4982