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.
8 * Copyright 2006, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
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
22 * - Dissect extended Restrictive security categories
23 * - Add Transmission/Retransmission statistics
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>
37 #include <epan/proto_data.h>
39 #include <epan/exceptions.h>
41 #include <wsutil/str_util.h>
42 #include <wsutil/array.h>
44 #include "packet-p1.h"
45 #include "packet-p22.h"
46 #include "packet-s5066sis.h"
48 void proto_register_dmp(void);
49 void proto_reg_handoff_dmp(void);
51 #define PNAME "Direct Message Profile"
55 /* Default UDP Port Number */
56 #define DEFAULT_DMP_PORT_RANGE "5031"
58 /* Protocol Identifier */
62 /* Versions supported */
63 #define DMP_VERSION_1 1
64 #define DMP_VERSION_2 2
66 /* Message Type (dmp.msg_type) */
73 /* Message Identifier Type (dmp.msg_id_type) */
74 #define ONLY_DMP_ID 0x0
75 #define X400_MSG_ID 0x1
76 #define NAT_MSG_ID 0x2
78 /* Report Type (dmp.report_type) */
82 /* Notification Type (dmp.notif_type) */
87 /* Address Encoding (dmp.addr_enc) */
88 #define DIRECT_ADDR 0x0
89 #define EXTENDED_ADDR 0x1
91 /* Address type (internal values) */
95 #define ORIG_P2_ADDRESS 4
97 /* Extended Address Form (dmp_addr_form) */
100 #define P1_EXTENDED 0x2
101 #define P2_EXTENDED 0x3
102 #define P1_P2_DIRECT 0x4
103 #define P1_DIRECT_P2_EXTENDED 0x5
104 #define P1_EXTENDED_P2_DIRECT 0x6
105 #define P1_P2_EXTENDED 0x7
107 /* Extended Address Type */
111 /* Security Policy (dmp_sec_pol) */
114 #define EXTENDED_NATIONAL 0x6
115 #define EXTENDED_MISSION 0x7
117 #define SEC_CAT_EXT_NONE 0x0
118 #define SEC_CAT_EXT_PERMISSIVE 0x1
119 #define SEC_CAT_EXT_RESTRICTIVE 0x2
121 /* Body Format (dmp.body_format) */
122 #define FREE_TEXT 0x0
123 #define FREE_TEXT_SUBJECT 0x1
124 #define STRUCTURED 0x2
126 /* Encoded Information Types */
127 #define EIT_BILATERAL 0x3
129 /* Compression Algorithm */
130 #define ALGORITHM_NONE 0x0
131 #define ALGORITHM_ZLIB 0x1
133 /* National Decoding */
134 #define NAT_DECODE_NONE 0
135 #define NAT_DECODE_DMP 1
136 #define NAT_DECODE_THALES 2
138 #define IPM_MODIFIER_X400 0
140 /* Internal values for not present and reserved time values */
141 #define DMP_TIME_NOT_PRESENT -1
142 #define DMP_TIME_RESERVED -2
144 #define ILLEGAL_FORMAT "<Illegal format>"
145 #define TIME_NOT_REPRESENTABLE "<Time not representable>"
147 /* Maximum lengths */
148 #define MAX_SIC_LEN 30
150 static int proto_dmp
;
152 static int hf_dmp_id
;
153 static int hf_mts_id
;
154 static int hf_ipm_id
;
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
;
188 static int hf_thales_ipm_id_modifier
;
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
;
197 static int hf_message_content
;
198 static int hf_report_content
;
199 static int hf_notif_content
;
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
;
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
;
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
;
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
;
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
;
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
;
333 static int hf_ack_reason
;
334 static int hf_ack_diagnostic
;
335 static int hf_ack_recips
;
337 static int hf_checksum
;
338 static int hf_checksum_status
;
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
;
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
;
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
;
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
;
406 static int ett_extensions
;
407 static int ett_extension
;
408 static int ett_extension_header
;
410 static int ett_content
;
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
;
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
;
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
;
452 static int ett_ack_recips
;
454 static int ett_analysis
;
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_dir_rec_no_generated
;
462 static expert_field ei_checksum_bad
;
463 static expert_field ei_message_body_uncompress
;
464 static expert_field ei_addr_ext_rec_no_generated
;
465 static expert_field ei_envelope_msg_id
;
466 static expert_field ei_7bit_string_unused_bits
;
467 static expert_field ei_analysis_ack_missing
;
468 static expert_field ei_analysis_ack_dup_no
;
469 static expert_field ei_analysis_ack_unexpected
;
470 static expert_field ei_analysis_msg_missing
;
471 static expert_field ei_analysis_retrans_no
;
472 static expert_field ei_too_many_sec_cat
;
474 static dissector_handle_t dmp_handle
;
476 typedef struct _dmp_id_key
{
482 typedef struct _dmp_id_val
{
483 int msg_type
; /* Message type */
484 unsigned prev_msg_id
; /* Previous message package num */
485 unsigned msg_id
; /* Message package num */
486 unsigned ack_id
; /* Acknowledgement package num */
487 unsigned rep_id
; /* Report package num */
488 unsigned not_id
; /* Notification package num */
489 nstime_t msg_time
; /* Message receive time */
490 nstime_t first_msg_time
; /* First message receive time */
491 nstime_t prev_msg_time
; /* Previous message receive time */
492 nstime_t rep_not_msg_time
; /* Report or Notification time */
493 uint32_t msg_resend_count
; /* Message resend counter */
494 uint32_t ack_resend_count
; /* Acknowledgement resend counter */
497 static wmem_map_t
*dmp_id_hash_table
;
498 static wmem_map_t
*dmp_long_id_hash_table
;
500 /* Global values used in several functions */
501 static struct dmp_data
{
513 uint8_t mts_id_length
;
514 proto_item
*mts_id_item
;
522 bool ack_rec_present
;
526 /* User definable values */
527 static int dmp_nat_decode
= NAT_DECODE_DMP
;
528 static int dmp_local_nation
;
529 static bool use_seq_ack_analysis
= true;
530 static bool dmp_align
;
532 typedef struct _dmp_security_class_t
{
536 } dmp_security_class_t
;
538 static dmp_security_class_t
*dmp_security_classes
;
539 static unsigned num_dmp_security_classes
;
541 static const true_false_string addr_enc
= {
542 "Use Extended Encoding", "Use Direct Encoding"
545 static const true_false_string dtg_sign
= {
549 static const true_false_string report_type
= {
550 "Non-Delivery Report", "Delivery Report"
553 static const value_string version_vals
[] = {
564 static const value_string type_vals
[] = {
566 { 0x1, "Message (E-Mail)" },
568 { 0x3, "Notification" },
569 { 0x4, "Acknowledgement" },
570 { 0x5, "Unknown Content" },
571 { 0x6, "Unknown Content" },
572 { 0x7, "Unknown Content" },
575 static const value_string msg_id_type_vals
[] = {
576 { 0x0, "DMP Identifiers only" },
577 { 0x1, "X.400 Message Identifiers" },
578 { 0x2, "Nationally-defined" },
582 static const value_string msg_id_length_vals
[] = {
583 { 0x0, "Full (16 bits)" },
584 { 0x1, "Short (12 bits)" },
587 static const value_string report_vals
[] = {
588 { 0x0, "No Report" },
589 { 0x1, "Non-Delivery Report" },
590 { 0x2, "Delivery Report" },
594 static const value_string report_vals_ext
[] = {
595 { 0x0, "No Report" },
596 { 0x1, "Non-Delivery Report" },
597 { 0x2, "Delivery Report" },
598 { 0x3, "Recipient Number Extended" },
601 /* Note the space in front of these values */
602 static const value_string report_vals_short
[] = {
607 static const value_string notif_vals
[] = {
608 { 0x0, "No Notification" },
609 { 0x1, "Non-Receipt Notification" },
610 { 0x2, "Receipt Notification" },
614 static const value_string notif_vals_ext
[] = {
615 { 0x0, "No Notification" },
616 { 0x1, "Non-Receipt Notification" },
617 { 0x2, "Receipt Notification" },
618 { 0x3, "Direct Address Extended" },
621 /* Note the space in front of these values */
622 static const value_string notif_vals_short
[] = {
627 static const value_string notif_type
[] = {
628 { 0x0, "Receipt Notification (RN)" },
629 { 0x1, "Non-Receipt Notification (NRN)" },
630 { 0x2, "Other Notification (ON)" },
631 { 0x3, "Unknown Notification" },
634 /* Note the space behind these values */
635 static const value_string addr_type_str
[] = {
637 { P1_ADDRESS
, "P1 " },
638 { P2_ADDRESS
, "P22/P772 " },
639 { ORIG_P2_ADDRESS
, "P22 " },
642 static const value_string addr_form
[] = {
643 { 0x0, "P1 Direct" },
644 { 0x1, "P22/P772 Direct" },
645 { 0x2, "P1 Extended" },
646 { 0x3, "P22/P772 Extended" },
647 { 0x4, "P1 and P22/P772 Direct" },
648 { 0x5, "P1 Direct and P22/P772 Extended" },
649 { 0x6, "P1 Extended and P22/P772 Direct" },
650 { 0x7, "P1 and P22/P772 Extended" },
653 static const value_string addr_form_orig_v1
[] = {
664 static const value_string addr_form_orig
[] = {
669 { 0x4, "Originator and P2 Direct" },
670 { 0x5, "Originator Direct and P2 Extended" },
671 { 0x6, "Originator Extended and P2 Direct" },
672 { 0x7, "Originator and P2 Extended" },
675 static const value_string ext_addr_type
[] = {
676 { 0x0, "ASN.1 BER-encoded OR-name" },
677 { 0x1, "ASN.1 PER-encoded OR-name" },
683 { 0x7, "Address Length Extended" },
686 static const value_string ext_addr_type_ext
[] = {
687 { 0x0, "ASN.1 BER-encoded OR-name" },
688 { 0x1, "ASN.1 PER-encoded OR-name" },
697 static const value_string ext_addr_type_short
[] = {
698 { 0x0, "OR-name (BER)" },
699 { 0x1, "OR-name (PER)" },
708 static const value_string message_type_vals
[] = {
709 { 0x0, "Operation" },
715 static const value_string precedence
[] = {
719 { 0x3, "Immediate" },
722 { 0x6, "Priority, Info Precedence: Routine" },
723 { 0x7, "Immediate, Info Precedence: Routine" },
726 static const value_string importance
[] = {
737 static const value_string sec_class
[] = {
739 { 0x1, "Unclassified" },
740 /* { 0x2, "Reserved" }, */
741 { 0x3, "Restricted" },
742 /* { 0x4, "Reserved" }, */
743 { 0x5, "Confidential" },
745 { 0x7, "Top secret" },
748 static const value_string sec_pol
[] = {
749 { 0x0, "Network defined" },
750 { 0x1, "Network defined" },
751 { 0x2, "Network defined" },
752 { 0x3, "Network defined" },
754 { 0x5, "National (nation of local server)" },
755 { 0x6, "Extended, National" },
756 { 0x7, "Extended, Mission Defined" },
759 /* For name we use the ISO 3166-1 Alfa-3 value for the country,
760 * for description we use the Country Name and
761 * for value we use the DMP value for National Policy Identifier.
763 static const enum_val_t dmp_national_values
[] = {
764 { "xxx", "None", 0x00 },
765 { "alb", "Albania", 0x1B },
766 { "arm", "Armenia", 0x20 },
767 { "aut", "Austria", 0x21 },
768 { "aze", "Azerbaijan", 0x22 },
769 { "blr", "Belarus", 0x23 },
770 { "bel", "Belgium", 0x01 },
771 { "bih", "Bosnia and Hercegowina", 0x24 },
772 { "bgr", "Bulgaria", 0x02 },
773 { "can", "Canada", 0x03 },
774 { "hrv", "Croatia", 0x1C },
775 { "cze", "Czech Republic", 0x04 },
776 { "dnk", "Denmark", 0x05 },
777 { "est", "Estonia", 0x06 },
778 { "eapc", "Euro-Atlantic Partnership Council (EAPC)", 0x3A },
779 { "eu", "European Union (EU)", 0x3B },
780 { "fin", "Finland", 0x25 },
781 { "mkd", "Former Yugoslav Republic of Macedonia", 0x26 },
782 { "fra", "France", 0x07 },
783 { "geo", "Georgia", 0x27 },
784 { "deu", "Germany", 0x08 },
785 { "grc", "Greece", 0x09 },
786 { "hun", "Hungary", 0x0A },
787 { "isl", "Iceland", 0x0B },
788 { "isaf", "International Security Assistance Force (ISAF)", 0x3C },
789 { "irl", "Ireland", 0x28 },
790 { "ita", "Italy", 0x0C },
791 { "kaz", "Kazakhstan", 0x29 },
792 { "kgz", "Kyrgyztan", 0x2A },
793 { "lva", "Latvia", 0x0D },
794 { "ltu", "Lithuania", 0x0E },
795 { "lux", "Luxembourg", 0x0F },
796 { "mlt", "Malta", 0x2B },
797 { "mda", "Moldova", 0x2C },
798 { "mne", "Montenegro", 0x2D },
799 { "nld", "Netherlands", 0x10 },
800 { "nor", "Norway", 0x11 },
801 { "pfp", "Partnership for Peace (PfP)", 0x3D },
802 { "pol", "Poland", 0x12 },
803 { "ptr", "Portugal", 0x13 },
804 { "rou", "Romania", 0x14 },
805 { "rus", "Russian Federation", 0x2E },
806 { "srb", "Serbia", 0x2F },
807 { "svk", "Slovakia", 0x15 },
808 { "svn", "Slovenia", 0x16 },
809 { "esp", "Spain", 0x17 },
810 { "swe", "Sweden", 0x30 },
811 { "che", "Switzerland", 0x31 },
812 { "tjk", "Tajikistan", 0x32 },
813 { "tur", "Turkey", 0x18 },
814 { "tkm", "Turkmenistan", 0x33 },
815 { "gbr", "United Kingdom", 0x19 },
816 { "usa", "United States", 0x1A },
817 { "ukr", "Ukraine", 0x34 },
818 { "uzb", "Uzbekistan", 0x35 },
819 { "weu", "Western European Union (WEU)", 0x3E },
823 #define MAX_NATIONAL_VALUES array_length(dmp_national_values)
824 /* Will be built in build_national_strings() */
825 static value_string nat_pol_id
[MAX_NATIONAL_VALUES
];
827 static const value_string ext_sec_cat
[] = {
828 { 0x0, "Not present" },
829 { 0x1, "Permissive category follows" },
830 { 0x2, "Restrictive category follows" },
834 static const value_string sic_key_type
[] = {
835 { 0xc, "2 or more 3-character SICs" },
836 { 0xd, "1 or more 3-to-8 character SICs" },
839 static const true_false_string sic_key_chars
= {
840 "Any", "[A-Z0-9] only"
843 static const value_string sic_key_num
[] = {
855 static const value_string sic_bit_vals
[] = {
856 { 0, "length:6, bytes:4" },
857 { 1, "length:6, bytes:4" },
858 { 2, "length:6, bytes:4" },
859 { 3, "length:6, bytes:4" },
860 { 4, "length:6, bytes:4" },
861 { 5, "length:6, bytes:4" },
862 { 6, "length:6, bytes:4" },
863 { 7, "length:6, bytes:4" },
864 { 8, "length:6, bytes:4" },
866 { 10, "length:5, bytes:4" },
867 { 11, "length:8, bytes:6" },
868 { 12, "length:4, bytes:3" },
869 { 13, "length:4, bytes:3" },
870 { 14, "length:7, bytes:5" },
871 { 15, "length:7, bytes:5" },
874 static const value_string sic_bit_any_vals
[] = {
875 { 0, "length:5, bytes:4" },
876 { 1, "length:5, bytes:4" },
877 { 2, "length:5, bytes:4" },
878 { 3, "length:5, bytes:4" },
879 { 4, "length:5, bytes:4" },
880 { 5, "length:5, bytes:4" },
881 { 6, "length:5, bytes:4" },
882 { 7, "length:5, bytes:4" },
883 { 8, "length:5, bytes:4" },
884 { 9, "length:8, bytes:7" },
885 { 10, "length:4, bytes:4" },
886 { 11, "length:7, bytes:6" },
887 { 12, "length:6, bytes:5" },
888 { 13, "length:6, bytes:5" },
889 { 14, "length:6, bytes:5" },
890 { 15, "length:6, bytes:5" },
893 static const value_string body_format_vals
[] = {
894 { 0x0, "Free text" },
895 { 0x1, "Free text including subject" },
896 { 0x2, "Structured" },
900 static const value_string eit_vals
[] = {
903 { 0x2, "General text" },
904 { 0x3, "Bilaterally defined (binary data)" },
911 static const value_string compression_vals
[] = {
912 { 0x0, "No compression" },
913 { 0x1, "ZLib compressed" },
918 static const value_string ack_reason
[] = {
919 { 0x00, "Successful, positive acknowledgement" },
920 { 0x01, "Unspecified error" },
921 { 0x02, "Checksum incorrect" },
924 static const value_string non_del_reason
[] = {
925 { 0x3D, "Unknown reason" },
926 { 0x3E, "Reason code greater than 0x3c (60)" },
927 { 0x3F, "Reserved" },
930 static const value_string non_del_diagn
[] = {
931 { 0x7C, "Diagnostic not specified" },
932 { 0x7D, "Unknown diagnostic" },
933 { 0x7E, "Diagnostic code greater than 0x7b (123)" },
934 { 0x7F, "Reserved" },
937 static const value_string discard_reason
[] = {
938 { 0xFE, "Discard Reason absent" },
939 { 0xFF, "Reserved" },
942 static const value_string on_type
[] = {
943 { 0x00, "acp127-nn" },
944 { 0x01, "acp127-pn" },
945 { 0x02, "acp127-tn" },
948 static const value_string ack_msg_type
[] = {
949 { STANAG
, " (message)" },
950 { IPM
, " (e-mail)" },
951 { REPORT
, " (report)" },
952 { NOTIF
, " (notif)" },
956 static const enum_val_t national_decoding
[] = {
957 { "none", "None (raw data)", NAT_DECODE_NONE
},
958 { "dmp", "As for regular", NAT_DECODE_DMP
},
959 { "thales", "Thales XOmail", NAT_DECODE_THALES
},
963 static const value_string ipm_id_modifier
[] = {
964 { 0x0, "X.400 IPM Identifier" },
965 { 0x1, "Nationally-defined" },
966 { 0x2, "Nationally-defined" },
967 { 0x3, "Nationally-defined" },
971 static const value_string thales_ipm_id_modifier
[] = {
972 { 0x0, "X.400 IPM Identifier" },
973 { 0x1, "3 or 5 digits" },
979 UAT_VS_DEF(dmp_security_class
, nation
, dmp_security_class_t
, unsigned, 0, "None")
980 UAT_DEC_CB_DEF(dmp_security_class
, sec_class
, dmp_security_class_t
)
981 UAT_CSTRING_CB_DEF(dmp_security_class
, name
, dmp_security_class_t
)
984 dmp_class_copy_cb(void *dest
, const void *orig
, size_t len _U_
)
986 dmp_security_class_t
*u
= (dmp_security_class_t
*)dest
;
987 const dmp_security_class_t
*o
= (const dmp_security_class_t
*)orig
;
989 u
->nation
= o
->nation
;
990 u
->sec_class
= o
->sec_class
;
991 u
->name
= g_strdup(o
->name
);
997 dmp_class_free_cb(void *r
)
999 dmp_security_class_t
*u
= (dmp_security_class_t
*)r
;
1004 static char *dmp_national_sec_class (unsigned nation
, unsigned dmp_sec_class
)
1008 for (i
= 0; i
< num_dmp_security_classes
; i
++) {
1009 dmp_security_class_t
*u
= &(dmp_security_classes
[i
]);
1011 if (u
->nation
== nation
&& u
->sec_class
== dmp_sec_class
) {
1019 static void build_national_strings (void)
1024 ** We use values from dmp_national_values to build value_string for nat_pol_id.
1026 for (i
= 0; i
< MAX_NATIONAL_VALUES
; i
++) {
1027 nat_pol_id
[i
].value
= dmp_national_values
[i
].value
;
1028 nat_pol_id
[i
].strptr
= dmp_national_values
[i
].description
;
1032 static const char *get_nat_pol_id_short (int nation
)
1035 while (dmp_national_values
[i
].name
) {
1036 if (dmp_national_values
[i
].value
== nation
) {
1037 return dmp_national_values
[i
].name
;
1045 static const char *msg_type_to_str (void)
1047 const char *msg_type
;
1048 bool have_msg
= false;
1050 switch (dmp
.msg_type
) {
1053 /* Include message type and precedence */
1054 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "%s (%s) [%s]",
1055 val_to_str_const (dmp
.msg_type
, type_vals
, "Unknown"),
1056 val_to_str_const (dmp
.st_type
, message_type_vals
, "Unknown"),
1057 (dmp
.prec
== 0x6 || dmp
.prec
== 0x7) ?
1058 val_to_str_const (dmp
.prec
-4, precedence
, "Unknown") :
1059 val_to_str_const (dmp
.prec
, precedence
, "Unknown"));
1063 /* Include importance */
1064 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "%s [%s]",
1065 val_to_str_const (dmp
.msg_type
, type_vals
, "Unknown"),
1066 val_to_str_const (dmp
.prec
, importance
, "Unknown"));
1070 /* Include report types included */
1071 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "Report (%s%s%s)",
1072 dmp
.dr
? "DR" : "", (dmp
.dr
&& dmp
.ndr
) ? " and " : "",
1073 dmp
.ndr
? "NDR" : "");
1077 msg_type
= val_to_str_const (dmp
.notif_type
, notif_type
, "Unknown");
1081 /* If we have msg_time we have a matching packet */
1082 have_msg
= (dmp
.id_val
&&
1083 (dmp
.id_val
->msg_time
.secs
>0 || dmp
.id_val
->msg_time
.nsecs
>0));
1084 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "Acknowledgement%s%s",
1085 have_msg
? val_to_str (dmp
.id_val
->msg_type
, ack_msg_type
,
1086 " (unknown:%d)") : "",
1087 dmp
.ack_reason
? " [negative]" : "");
1091 msg_type
= "Unknown";
1098 static const char *non_del_reason_str (uint32_t value
)
1101 /* Standard values according to P1 */
1102 return val_to_str_const (value
, p1_NonDeliveryReasonCode_vals
, "Unknown");
1104 return val_to_str_const (value
, non_del_reason
, "Unknown");
1108 static const char *non_del_diagn_str (uint32_t value
)
1111 /* Standard values according to P1 */
1112 return val_to_str_const (value
, p1_NonDeliveryDiagnosticCode_vals
, "Unknown");
1114 return val_to_str_const (value
, non_del_diagn
, "Unknown");
1118 static const char *nrn_reason_str (uint32_t value
)
1120 /* Standard values according to P22 */
1121 return val_to_str_const (value
, p22_NonReceiptReasonField_vals
, "Reserved");
1124 static const char *discard_reason_str (uint32_t value
)
1127 /* Standard values according to P22 */
1128 return val_to_str_const (value
, p22_DiscardReasonField_vals
, "Reserved");
1130 return val_to_str_const (value
, discard_reason
, "Unknown");
1134 /* Ref chapter 6.2.8.10 TimeDifference */
1135 static int32_t dmp_dec_time_diff (uint8_t dmp_time_diff
)
1137 int32_t time_diff
= 0;
1139 if (dmp_time_diff
<= 0x01) {
1140 /* Reserved - low value */
1141 time_diff
= DMP_TIME_RESERVED
;
1142 } else if (dmp_time_diff
<= 0x1D) {
1143 /* Number of 2-second units (2-58 seconds) */
1144 time_diff
= dmp_time_diff
* 2;
1145 } else if (dmp_time_diff
<= 0x91) {
1146 /* Number of 15-second units (1 min - 29 min 45 sec) */
1147 time_diff
= (dmp_time_diff
- 0x1D + 3) * 15;
1148 } else if (dmp_time_diff
<= 0xDF) {
1149 /* Number of 5-minute units (30 min - 6 hours 55 min) */
1150 time_diff
= (dmp_time_diff
- 0x91 + 5) * 5*60;
1151 } else if (dmp_time_diff
<= 0xF7) {
1152 /* Number of 30-minute units (7 hours - 18 hours 30 min) */
1153 time_diff
= (dmp_time_diff
- 0xDF + 7) * 30*60;
1155 /* Reserved - high value */
1156 time_diff
= DMP_TIME_RESERVED
;
1163 * Ref chapter 6.3.7.2.10 ExpiryTime
1164 * and chapter 6.3.9.2.2 DeliveryTime
1166 static int32_t dmp_dec_exp_del_time (uint8_t timev
, bool expiry_time
)
1168 int32_t time_value
= 0;
1170 if (expiry_time
&& (timev
== 0x00)) {
1171 /* No expiry time */
1172 time_value
= DMP_TIME_NOT_PRESENT
;
1173 } else if (timev
<= 0x1D) {
1174 /* Number of 2-second units (2-58 seconds) */
1175 time_value
= timev
* 2;
1176 } else if (timev
<= 0x91) {
1177 /* Number of 15-second units (1 min - 29 min 45 sec) */
1178 time_value
= (timev
- 0x1D + 3) * 15;
1179 } else if (timev
<= 0xBB) {
1180 /* Number of 5-minute units (30 min - 3 hours 55 min) */
1181 time_value
= (timev
- 0x91 + 5) * 5*60;
1182 } else if (timev
<= 0xE3) {
1183 /* Number of 30-minute units (4 hours - 23 hours 30 min) */
1184 time_value
= (timev
- 0xBB + 7) * 30*60;
1185 } else if (timev
< 0xFF) {
1186 /* Number of 2-hour units (24 - 78 hours) */
1187 time_value
= (timev
- 0xE3 + 11) * 2*3600;
1190 time_value
= DMP_TIME_RESERVED
;
1196 static int32_t dmp_dec_exp_time (uint8_t expiry_time
)
1198 return dmp_dec_exp_del_time (expiry_time
, true);
1201 static int32_t dmp_dec_del_time (uint8_t delivery_time
)
1203 return dmp_dec_exp_del_time (delivery_time
, false);
1206 /* Ref chapter 6.3.7.2.11 DTG */
1207 static int32_t dmp_dec_dtg (uint32_t dtg
)
1213 value
= DMP_TIME_NOT_PRESENT
;
1214 } else if (dtg
<= 0x3C) {
1215 /* Number of minutes (0-59 min) */
1216 value
= (dtg
- 1) * 60;
1217 } else if (dtg
<= 0x64) {
1218 /* Number of 15-minute units (1 hour - 10 hours 45 min) */
1219 value
= (dtg
- 0x3C + 3) * 15 * 60;
1220 } else if (dtg
< 0x7F) {
1221 /* Number of hours (11-36 hours) */
1222 value
= (dtg
- 0x64 + 10) * 3600;
1225 value
= DMP_TIME_RESERVED
;
1232 * Ref chapter 7.10.11.1 Submission time
1234 * start_time (current time)
1235 * delta1 = E (encoded submission time)
1236 * delta2 = C (encoded current time)
1237 * 0x01C2 = Pn + 15min (maximum point for S1)
1238 * 0x7E38 = Pn+1 - 15min (minimum point for S3)
1239 * 0x7FF8 = Pn+1 (length of P (period))
1241 static int32_t dmp_dec_subm_time (uint16_t delta1
, int32_t start_time
)
1243 int32_t subm_time
= start_time
;
1246 delta2
= (uint16_t) ((subm_time
/ 2) % 0x7FF8);
1248 if ((delta1
< 0x01C2) && (delta2
>= delta1
+ 0x7E38)) {
1249 subm_time
+= 2 * (0x7FF8 - delta2
+ delta1
);
1250 } else if ((delta1
>= 0x01C2) && (delta2
< delta1
- 0x01C2)) {
1251 subm_time
-= 2 * (0x7FF8 - delta1
+ delta2
);
1253 subm_time
-= 2 * (delta2
- delta1
);
1259 /* Ref chapter 6.3.7.2.12 SIC */
1260 static bool dmp_dec_xbyte_sic (uint64_t bin
, char *sic
,
1261 uint8_t no_char
, bool any
)
1263 bool failure
= false;
1268 if (no_char
>= MAX_SIC_LEN
) {
1269 /* Illegal length */
1270 snprintf (sic
, MAX_SIC_LEN
, "Illegal length: %d", no_char
);
1280 for (i
= 0; i
< no_char
; i
++) {
1281 p
= (uint64_t) pow (multiplier
, no_char
- 1 - i
);
1284 sic
[i
] = (char) tmp
;
1287 } else if (sic
[i
] <= 35) {
1288 sic
[i
] += ('A' - 10);
1292 } else if (sic
[i
] <= 61) {
1293 sic
[i
] += ('a' - 36);
1294 } else if (sic
[i
] == 62) {
1296 } else if (sic
[i
] == 63) {
1298 } else if (sic
[i
] == 64) {
1300 } else if (sic
[i
] == 65) {
1302 } else if (sic
[i
] == 66) {
1304 } else if (sic
[i
] == 67) {
1306 } else if (sic
[i
] == 68) {
1308 } else if (sic
[i
] == 69) {
1310 } else if (sic
[i
] == 70) {
1312 } else if (sic
[i
] == 71) {
1314 } else if (sic
[i
] == 72) {
1316 } else if (sic
[i
] == 73) {
1322 if (!g_ascii_isprint(sic
[i
])) {
1332 static unsigned dmp_id_hash (const void *k
)
1334 const dmp_id_key
*dmpx
=(const dmp_id_key
*)k
;
1338 static int dmp_id_hash_equal (const void *k1
, const void *k2
)
1340 const dmp_id_key
*dmp1
=(const dmp_id_key
*)k1
;
1341 const dmp_id_key
*dmp2
=(const dmp_id_key
*)k2
;
1342 if (dmp1
->id
!= dmp2
->id
)
1345 return (addresses_equal (&dmp1
->src
, &dmp2
->src
) &&
1346 addresses_equal (&dmp1
->dst
, &dmp2
->dst
));
1349 static void register_dmp_id (packet_info
*pinfo
, uint8_t reason
)
1351 dmp_id_val
*dmp_data
= NULL
, *pkg_data
= NULL
;
1352 dmp_id_key
*dmp_key
= NULL
;
1354 unsigned msg_id
= 0;
1356 if (pinfo
->flags
.in_error_pkt
) {
1357 /* No analysis of error packets */
1361 nstime_set_zero(&msg_time
);
1363 dmp_key
= wmem_new (wmem_file_scope(), dmp_id_key
);
1365 if (!pinfo
->fd
->visited
&&
1366 (dmp
.msg_type
== REPORT
|| dmp
.msg_type
== NOTIF
))
1368 /* Try to match corresponding message */
1369 dmp_key
->id
= (unsigned) dmp
.subj_id
;
1370 copy_address_wmem(wmem_file_scope(), &dmp_key
->src
, &(pinfo
->dst
));
1371 copy_address_wmem(wmem_file_scope(), &dmp_key
->dst
, &(pinfo
->src
));
1373 dmp_data
= (dmp_id_val
*) wmem_map_lookup (dmp_id_hash_table
, dmp_key
);
1377 if (dmp_data
->prev_msg_id
> 0) {
1378 msg_id
= dmp_data
->prev_msg_id
;
1380 msg_id
= dmp_data
->msg_id
;
1382 msg_time
= dmp_data
->msg_time
;
1386 if (dmp
.msg_type
== ACK
) {
1387 dmp_key
->id
= (unsigned) dmp
.subj_id
;
1388 copy_address_wmem(wmem_file_scope(), &dmp_key
->src
, &(pinfo
->dst
));
1389 copy_address_wmem(wmem_file_scope(), &dmp_key
->dst
, &(pinfo
->src
));
1391 dmp_key
->id
= (unsigned) dmp
.msg_id
;
1392 copy_address_wmem(wmem_file_scope(), &dmp_key
->src
, &(pinfo
->src
));
1393 copy_address_wmem(wmem_file_scope(), &dmp_key
->dst
, &(pinfo
->dst
));
1396 dmp_data
= (dmp_id_val
*) wmem_map_lookup (dmp_id_hash_table
, dmp_key
);
1398 if (!pinfo
->fd
->visited
) {
1400 if (dmp
.msg_type
== ACK
) {
1401 /* Only save this data if positive ack */
1403 if (dmp_data
->ack_id
== 0) {
1404 /* Only save reference to first ACK */
1405 dmp_data
->ack_id
= pinfo
->num
;
1407 /* Only count when resending */
1408 dmp_data
->ack_resend_count
++;
1412 /* Message resent */
1413 dmp_data
->msg_resend_count
++;
1414 dmp_data
->prev_msg_id
= pinfo
->num
;
1415 dmp_data
->prev_msg_time
= dmp_data
->msg_time
;
1416 dmp_data
->msg_time
= pinfo
->abs_ts
;
1420 dmp_data
= wmem_new0 (wmem_file_scope(), dmp_id_val
);
1421 dmp_data
->msg_type
= dmp
.msg_type
;
1423 if (dmp
.msg_type
== ACK
) {
1424 /* No matching message for this ack */
1425 dmp_data
->ack_id
= pinfo
->num
;
1427 dmp_data
->first_msg_time
= pinfo
->abs_ts
;
1428 dmp_data
->msg_time
= pinfo
->abs_ts
;
1430 if (dmp
.msg_type
== REPORT
) {
1431 dmp_data
->rep_id
= pinfo
->num
;
1432 dmp_data
->msg_id
= msg_id
;
1433 dmp_data
->rep_not_msg_time
= msg_time
;
1434 } else if (dmp
.msg_type
== NOTIF
) {
1435 dmp_data
->not_id
= pinfo
->num
;
1436 dmp_data
->msg_id
= msg_id
;
1437 dmp_data
->rep_not_msg_time
= msg_time
;
1439 dmp_data
->msg_id
= pinfo
->num
;
1442 wmem_map_insert (dmp_id_hash_table
, dmp_key
, dmp_data
);
1446 pkg_data
= wmem_new (wmem_file_scope(), dmp_id_val
);
1447 *pkg_data
= *dmp_data
;
1448 p_add_proto_data(wmem_file_scope(), pinfo
, proto_dmp
, 0, pkg_data
);
1450 /* Fetch last values from data saved in packet */
1451 pkg_data
= (dmp_id_val
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_dmp
, 0);
1453 if (dmp_data
&& pkg_data
&& dmp
.msg_type
!= ACK
&& pkg_data
->ack_id
== 0) {
1454 pkg_data
->ack_id
= dmp_data
->ack_id
;
1458 DISSECTOR_ASSERT (pkg_data
);
1459 dmp
.id_val
= pkg_data
;
1462 static void dmp_add_seq_ack_analysis (tvbuff_t
*tvb
, packet_info
*pinfo
,
1463 proto_tree
*dmp_tree
, int offset
)
1465 proto_tree
*analysis_tree
= NULL
;
1466 proto_item
*en
= NULL
, *eh
= NULL
;
1469 if (dmp
.msg_type
> ACK
|| (dmp
.msg_type
< ACK
&& !dmp
.checksum
) ||
1470 dmp
.id_val
== NULL
|| pinfo
->flags
.in_error_pkt
)
1472 /* No need for seq/ack analysis */
1476 analysis_tree
= proto_tree_add_subtree(dmp_tree
, tvb
, 0, 0, ett_analysis
, &en
, "SEQ/ACK analysis");
1477 proto_item_set_generated (en
);
1479 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
1480 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
)) {
1481 if (dmp
.id_val
->ack_id
) {
1482 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_num
, tvb
,
1483 0, 0, dmp
.id_val
->ack_id
);
1484 proto_item_set_generated (en
);
1485 if (!dmp
.checksum
) {
1486 proto_item_append_text (en
, " (unexpected)");
1487 expert_add_info(pinfo
, en
, &ei_analysis_ack_unexpected
);
1489 } else if (dmp
.checksum
&& !dmp
.id_val
->msg_resend_count
) {
1490 en
= proto_tree_add_item (analysis_tree
, hf_analysis_ack_missing
, tvb
, offset
, 0, ENC_NA
);
1491 if (pinfo
->fd
->visited
) {
1492 /* We do not know this on first visit and we do not want to
1493 add a entry in the "Expert Severity Info" for this note */
1494 expert_add_info(pinfo
, en
, &ei_analysis_ack_missing
);
1495 proto_item_set_generated (en
);
1499 if (dmp
.msg_type
== REPORT
) {
1500 if (dmp
.id_val
->msg_id
) {
1501 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_num
,
1502 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1503 proto_item_set_generated (en
);
1505 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->rep_not_msg_time
);
1506 en
= proto_tree_add_time (analysis_tree
, hf_analysis_rep_time
,
1508 proto_item_set_generated (en
);
1510 proto_tree_add_expert (analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1512 } else if (dmp
.msg_type
== NOTIF
) {
1513 if (dmp
.id_val
->msg_id
) {
1514 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_num
,
1515 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1516 proto_item_set_generated (en
);
1518 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->rep_not_msg_time
);
1519 en
= proto_tree_add_time (analysis_tree
, hf_analysis_not_time
,
1521 proto_item_set_generated (en
);
1523 proto_tree_add_expert (analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1527 if (dmp
.id_val
->msg_resend_count
) {
1528 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_retrans_no
,
1529 tvb
, 0, 0, dmp
.id_val
->msg_resend_count
);
1530 proto_item_set_generated (en
);
1532 expert_add_info_format(pinfo
, en
, &ei_analysis_retrans_no
, "Retransmission #%d", dmp
.id_val
->msg_resend_count
);
1534 if (dmp
.msg_type
== REPORT
) {
1535 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_rep_resend_from
,
1536 tvb
, 0, 0, dmp
.id_val
->rep_id
);
1537 } else if (dmp
.msg_type
== NOTIF
) {
1538 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_not_resend_from
,
1539 tvb
, 0, 0, dmp
.id_val
->not_id
);
1541 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_resend_from
,
1542 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1544 proto_item_set_generated (en
);
1546 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->prev_msg_time
);
1547 en
= proto_tree_add_time (analysis_tree
, hf_analysis_retrans_time
,
1549 proto_item_set_generated (en
);
1551 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->first_msg_time
);
1552 eh
= proto_tree_add_time (analysis_tree
, hf_analysis_total_retrans_time
,
1554 proto_item_set_generated (eh
);
1556 if (dmp
.id_val
->first_msg_time
.secs
== dmp
.id_val
->prev_msg_time
.secs
&&
1557 dmp
.id_val
->first_msg_time
.nsecs
== dmp
.id_val
->prev_msg_time
.nsecs
) {
1558 /* Time values does not differ, hide the total time */
1559 proto_item_set_hidden (eh
);
1562 } else if (dmp
.msg_type
== ACK
) {
1563 if (dmp
.id_val
->msg_type
!= ACK
) {
1564 if (dmp
.id_val
->msg_type
== REPORT
) {
1565 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_acks_rep_num
,
1566 tvb
, 0, 0, dmp
.id_val
->rep_id
);
1567 } else if (dmp
.id_val
->msg_type
== NOTIF
) {
1568 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_acks_not_num
,
1569 tvb
, 0, 0, dmp
.id_val
->not_id
);
1571 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_acks_msg_num
,
1572 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1574 proto_item_set_generated (en
);
1576 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->msg_time
);
1577 en
= proto_tree_add_time (analysis_tree
, hf_analysis_ack_time
,
1579 proto_item_set_generated (en
);
1581 nstime_delta (&ns
, &pinfo
->abs_ts
, &dmp
.id_val
->first_msg_time
);
1582 eh
= proto_tree_add_time (analysis_tree
, hf_analysis_total_time
,
1584 proto_item_set_generated (eh
);
1586 if (dmp
.id_val
->first_msg_time
.secs
== dmp
.id_val
->msg_time
.secs
&&
1587 dmp
.id_val
->first_msg_time
.nsecs
== dmp
.id_val
->msg_time
.nsecs
) {
1588 /* Time values does not differ, hide the total time */
1589 proto_item_set_hidden (eh
);
1591 /* Different times, add a reference to the message we have ack'ed */
1592 proto_item_append_text (en
, " (from frame %d)",
1593 dmp
.id_val
->prev_msg_id
);
1596 proto_tree_add_expert (analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1599 if (dmp
.id_val
->ack_resend_count
) {
1600 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_dup_no
,
1601 tvb
, 0, 0, dmp
.id_val
->ack_resend_count
);
1602 proto_item_set_generated (en
);
1604 expert_add_info_format(pinfo
, en
, &ei_analysis_ack_dup_no
, "Dup ACK #%d", dmp
.id_val
->ack_resend_count
);
1606 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_resend_from
,
1607 tvb
, 0, 0, dmp
.id_val
->ack_id
);
1608 proto_item_set_generated (en
);
1613 static const char *dissect_7bit_string (tvbuff_t
*tvb
, int offset
, int length
, unsigned char *byte_rest
)
1615 unsigned char *encoded
, *decoded
;
1616 unsigned char rest
= 0, bits
= 1;
1626 encoded
= (unsigned char *)tvb_memdup (wmem_packet_scope(), tvb
, offset
, length
);
1627 decoded
= (unsigned char *)wmem_alloc0 (wmem_packet_scope(), (size_t)(length
* 1.2) + 1);
1628 for (i
= 0; i
< length
; i
++) {
1629 decoded
[len
++] = encoded
[i
] >> bits
| rest
;
1630 rest
= (encoded
[i
] << (7 - bits
) & 0x7F);
1632 decoded
[len
++] = rest
;
1647 static const char *dissect_thales_mts_id (tvbuff_t
*tvb
, int offset
, int length
, unsigned char *byte_rest
)
1649 /* Thales XOmail uses this format: "MTA-NAME/000000000000" */
1650 if (length
>= 7 && length
<= 22) {
1651 return wmem_strdup_printf (wmem_packet_scope(), "%s/%08X%04X",
1652 dissect_7bit_string (tvb
, offset
, length
- 6, byte_rest
),
1653 tvb_get_ntohl (tvb
, offset
+ length
- 6),
1654 tvb_get_ntohs (tvb
, offset
+ length
- 2));
1657 return ILLEGAL_FORMAT
;
1660 static const char *dissect_thales_ipm_id (tvbuff_t
*tvb
, int offset
, int length
, int modifier
, unsigned char *byte_rest
)
1662 /* Thales XOmail uses this format: "<prefix>0000 YYMMDDhhmmssZ" */
1663 if (length
>= 6 && length
<= 20 && modifier
>= 0 && modifier
<= 2) {
1664 unsigned number
= tvb_get_ntohs (tvb
, offset
+ length
- 6);
1665 uint8_t number_len
= modifier
+ 2;
1666 time_t timev
= tvb_get_ntohl(tvb
, offset
+ length
- 4);
1667 struct tm
*tmp
= gmtime(&timev
);
1670 return TIME_NOT_REPRESENTABLE
;
1672 if (modifier
== 1 && number
>= 1024) {
1673 /* The number is in the range 65536-99999 */
1675 number
+= (65536 - 1024);
1678 return wmem_strdup_printf (wmem_packet_scope(), "%s%0*d %02d%02d%02d%02d%02d%02dZ",
1679 (length
== 6) ? "" : dissect_7bit_string (tvb
, offset
, length
- 6, byte_rest
),
1681 tmp
->tm_year
% 100, tmp
->tm_mon
+ 1, tmp
->tm_mday
,
1682 tmp
->tm_hour
, tmp
->tm_min
, tmp
->tm_sec
);
1685 return ILLEGAL_FORMAT
;
1688 /* Ref chapter 6.3.7.2.12 SIC */
1689 static int dissect_dmp_sic (tvbuff_t
*tvb
, packet_info
*pinfo
,
1690 proto_tree
*message_tree
, int offset
)
1692 proto_tree
*sic_tree
= NULL
, *bitmap_tree
= NULL
, *key_tree
= NULL
;
1693 proto_item
*sf
= NULL
, *bf
= NULL
, *kf
= NULL
;
1695 uint8_t key
, bitmap
, no
, i
, length
= 0;
1696 bool any
, no_sic
= false, failure
= false;
1697 int bytes
= 0, boffset
= offset
;
1700 key
= tvb_get_uint8 (tvb
, offset
);
1701 sic
= (char *)wmem_alloc (pinfo
->pool
, MAX_SIC_LEN
);
1704 /* 2 bytes, single 3-character SIC, characters [A-Z0-9] only */
1706 value
= tvb_get_ntohs (tvb
, offset
);
1707 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, false);
1708 sf
= proto_tree_add_string_format_value(message_tree
, hf_message_sic
, tvb
,
1710 "%s [A-Z0-9 only]%s", sic
,
1711 failure
? " (invalid)": "");
1713 expert_add_info(pinfo
, sf
, &ei_message_sic_illegal
);
1717 } else if (key
<= 0xBD) {
1718 /* 3 bytes, single 3-character SIC, any valid character */
1720 value
= tvb_get_ntohl (tvb
, offset
);
1721 value
= (value
>> 8) & 0x48FFFF;
1722 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, true);
1723 sf
= proto_tree_add_string_format_value(message_tree
, hf_message_sic
, tvb
,
1725 "%s [any character]%s", sic
,
1726 failure
? " (invalid)": "");
1728 expert_add_info(pinfo
, sf
, &ei_message_sic_illegal
);
1732 } else if (key
<= 0xBF) {
1733 /* Reserved (not used) */
1734 snprintf (sic
, MAX_SIC_LEN
, "Reserved");
1737 } else if (key
<= 0xCF) {
1738 /* 2 or more 3-character SICs */
1740 sf
= proto_tree_add_item (message_tree
, hf_message_sic_key
, tvb
, offset
, 1, ENC_NA
);
1741 sic_tree
= proto_item_add_subtree (sf
, ett_message_sic
);
1743 kf
= proto_tree_add_item (sic_tree
, hf_message_sic_key_values
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1744 key_tree
= proto_item_add_subtree (kf
, ett_message_sic_key
);
1746 proto_tree_add_item (key_tree
, hf_message_sic_key_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1747 proto_tree_add_item (key_tree
, hf_message_sic_key_chars
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1748 proto_tree_add_item (key_tree
, hf_message_sic_key_num
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1752 no
= (key
& 0x07) + 1;
1753 for (i
= 0; i
< no
; i
++) {
1755 value
= tvb_get_ntohl (tvb
, offset
);
1756 value
= (value
>> 8) & 0x48FFFF;
1759 value
= tvb_get_ntohs (tvb
, offset
);
1762 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, any
);
1763 bf
= proto_tree_add_string_format (sic_tree
, hf_message_sic
, tvb
,
1765 "SIC %d: %s%s", i
+ 1, sic
,
1766 failure
? " (invalid)": "");
1768 expert_add_info(pinfo
, bf
, &ei_message_sic_illegal
);
1772 proto_item_append_text (sf
, ": %d (3 %s character)", no
,
1773 any
? "any" : "[A-Z0-9]");
1775 } else if (key
<= 0xDF) {
1776 /* 1 or more 3 to 8 character SICs */
1778 sf
= proto_tree_add_item (message_tree
, hf_message_sic_key
, tvb
, offset
, 1, ENC_NA
);
1779 sic_tree
= proto_item_add_subtree (sf
, ett_message_sic
);
1781 kf
= proto_tree_add_item (sic_tree
, hf_message_sic_key_values
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1782 key_tree
= proto_item_add_subtree (kf
, ett_message_sic_key
);
1784 proto_tree_add_item (key_tree
, hf_message_sic_key_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1785 proto_tree_add_item (key_tree
, hf_message_sic_key_chars
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1786 proto_tree_add_item (key_tree
, hf_message_sic_key_num
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1789 bitmap
= tvb_get_uint8 (tvb
, offset
);
1790 bf
= proto_tree_add_uint_format (sic_tree
, hf_message_sic_bitmap
, tvb
,
1792 "Length Bitmap: 0x%2.2x", bitmap
);
1793 bitmap_tree
= proto_item_add_subtree (bf
, ett_message_sic_bitmap
);
1794 proto_tree_add_item (bitmap_tree
, hf_message_sic_bitmap
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1797 no
= (key
& 0x07) + 1;
1800 for (i
= 0; i
< no
; i
++) {
1801 if (bitmap
& (1 << (7 - i
))) {
1802 /* 4 - 8 character */
1803 key
= tvb_get_uint8 (tvb
, offset
);
1805 /* Any valid characters */
1806 if ((key
& 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1809 value
= tvb_get_ntohl (tvb
, offset
) & 0x0FFFFFFF;
1810 } else if ((key
& 0xC0) == 0xC0) { /* bit 7-4: 11xx */
1813 value
= ((uint64_t)key
& 0x3F)<<32|tvb_get_ntohl (tvb
, offset
+ 1);
1814 } else if ((key
& 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1817 value
= ((uint64_t)(tvb_get_ntohs (tvb
, offset
) & 0x0FFF)) << 32 |
1818 tvb_get_ntohl (tvb
, offset
+ 2);
1819 } else if ((key
& 0xF0) == 0x90) { /* bit 7-4: 1001 */
1822 value
= ((uint64_t)((tvb_get_ntohl (tvb
, offset
)>>8) & 0x0FFF))<<32 |
1823 tvb_get_ntohl (tvb
, offset
+ 3);
1824 } else { /* bit 7-4: 0xxx or 1000 */
1827 value
= tvb_get_ntohl (tvb
, offset
);
1830 /* Characters [A-Z0-9] only */
1831 if ((key
& 0xE0) == 0xC0) { /* bit 7-4: 110x */
1834 value
= (tvb_get_ntohl (tvb
, offset
) >> 8) & 0x1FFFFF;
1835 } else if ((key
& 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1838 value
= tvb_get_ntohl (tvb
, offset
) & 0x0FFFFFFF;
1839 } else if ((key
& 0xE0) == 0xE0) { /* bit 7-4: 111x */
1842 value
= ((uint64_t)key
& 0x1F)<<32 | tvb_get_ntohl (tvb
, offset
+1);
1843 } else if ((key
& 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1846 value
= ((uint64_t)tvb_get_ntohs (tvb
, offset
) & 0x0FFF) << 32 |
1847 tvb_get_ntohl (tvb
, offset
+ 2);
1848 } else { /* bit 7-4: 0xxx or 1000 */
1851 value
= tvb_get_ntohl (tvb
, offset
);
1857 value
= (tvb_get_ntohl (tvb
, offset
) >> 8) & 0x48FFFF;
1861 value
= tvb_get_ntohs (tvb
, offset
);
1866 failure
= dmp_dec_xbyte_sic (value
, sic
, length
, any
);
1867 bf
= proto_tree_add_string_format (sic_tree
, hf_message_sic
, tvb
,
1869 "SIC %d: %s (%d bytes: %" PRIx64
")%s",
1870 i
+ 1, sic
, bytes
, value
,
1871 failure
? " (invalid)": "");
1872 if (bitmap
& (1 << (7 - i
))) {
1873 /* Only if 4 - 8 character */
1874 bitmap_tree
= proto_item_add_subtree (bf
, ett_message_sic_bits
);
1876 proto_tree_add_item (bitmap_tree
, hf_message_sic_bits_any
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1878 proto_tree_add_item (bitmap_tree
, hf_message_sic_bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1882 expert_add_info(pinfo
, bf
, &ei_message_sic_illegal
);
1886 proto_item_append_text (sf
, ": %d (3-to-8 %s character)", no
,
1887 any
? "any" : "[A-Z0-9]");
1889 } else if (key
== 0xFE) {
1891 snprintf (sic
, MAX_SIC_LEN
, "Not present");
1895 /* Resered (not used) */
1896 snprintf (sic
, MAX_SIC_LEN
, "Reserved");
1901 /* Not added any SIC, dump text value */
1902 sf
= proto_tree_add_string (message_tree
, hf_message_sic
, tvb
, offset
, 1, sic
);
1906 proto_item_set_len (sf
, offset
- boffset
);
1911 /* Ref chapter 5.2.7.1 Direct Originator Encoding */
1912 static int dissect_dmp_direct_addr (tvbuff_t
*tvb
, packet_info
*pinfo
,
1913 proto_tree
*field_tree
, proto_item
*tf
,
1914 int offset
, int rec_no
,
1915 int rec_ofs
, int addr_type
)
1917 proto_tree
*addr_tree
= NULL
;
1918 proto_item
*en
= NULL
;
1922 value
= tvb_get_uint8 (tvb
, offset
);
1923 dir_addr
= (value
& 0x7F);
1925 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address1
, tvb
,
1927 "%sDirect Address (bits 6-0): %d",
1928 val_to_str_const (addr_type
, addr_type_str
, ""),
1930 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1931 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1932 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1936 value
= tvb_get_uint8 (tvb
, offset
);
1937 dir_addr
|= ((value
& 0x3F) << 7);
1938 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address2
, tvb
,
1940 "%sDirect Address (bits 12-7): %d",
1941 val_to_str_const (addr_type
, addr_type_str
, ""),
1943 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1944 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1945 en
= proto_tree_add_item (addr_tree
, hf_reserved_0x40
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1947 expert_add_info(pinfo
, en
, &ei_reserved_value
);
1949 proto_tree_add_item (addr_tree
, hf_addr_dir_address2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1954 value
= tvb_get_uint8 (tvb
, offset
);
1955 dir_addr
|= ((value
& 0x3F) << 13);
1956 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address3
, tvb
,
1958 "%sDirect Address (bits 18-13): %d",
1959 val_to_str_const (addr_type
,addr_type_str
,""),
1961 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1962 en
= proto_tree_add_item (addr_tree
, hf_reserved_0xC0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1964 expert_add_info(pinfo
, en
, &ei_reserved_value
);
1966 proto_tree_add_item (addr_tree
, hf_addr_dir_address3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1970 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address_generated
,
1971 tvb
, offset
, 0, dir_addr
,
1972 "%sDirect Address: %d",
1973 val_to_str_const (addr_type
, addr_type_str
, ""),
1975 proto_item_set_generated (en
);
1977 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address
, tvb
,
1979 "%sDirect Address: %d",
1980 val_to_str_const (addr_type
, addr_type_str
, ""),
1982 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1983 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1984 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1989 proto_item_append_text (tf
, " %d", rec_no
);
1990 if (rec_ofs
!= -1) {
1991 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
1994 proto_item_append_text (tf
, ", %sDirect Address: %d",
1995 val_to_str_const (addr_type
, addr_type_str
, ""), dir_addr
);
2000 /* Ref 5.3.14 Extended Address */
2001 static int dissect_dmp_ext_addr (tvbuff_t
*tvb
, packet_info
*pinfo
,
2002 proto_tree
*field_tree
, proto_item
*tf
,
2003 int offset
, int rec_no
, int rec_ofs
,
2006 proto_tree
*addr_tree
= NULL
, *ext_tree
= NULL
;
2007 proto_item
*en
= NULL
, *ef
= NULL
;
2010 int boffset
= offset
;
2011 bool addr_length_extended
= false;
2012 asn1_ctx_t asn1_ctx
;
2014 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
2016 value
= tvb_get_uint8 (tvb
, offset
);
2017 type
= (value
& 0xE0) >> 5;
2018 length
= (value
& 0x1F);
2019 ef
= proto_tree_add_none_format (field_tree
, hf_addr_ext_address
, tvb
,
2020 offset
, -1, "%sExtended Address",
2021 val_to_str_const (addr_type
, addr_type_str
, ""));
2022 ext_tree
= proto_item_add_subtree (ef
, ett_address_extended
);
2024 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_type
, tvb
,
2025 offset
, 1, value
, "Address Type: %s",
2026 val_to_str_const (type
, ext_addr_type
,
2028 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_type
);
2029 proto_tree_add_item (addr_tree
, hf_addr_ext_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2032 addr_length_extended
= true;
2033 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_length1
, tvb
,
2035 "Address Length (bits 4-0): %d", length
);
2036 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2037 proto_tree_add_item (addr_tree
, hf_addr_ext_length1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2041 value
= tvb_get_uint8 (tvb
, offset
);
2042 type
= ((value
& 0xE0) >> 5);
2043 length
|= ((value
& 0x1F) << 5);
2045 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_type_ext
, tvb
,
2046 offset
, 1, value
, "Address Type Ext: %s",
2047 val_to_str_const (type
, ext_addr_type_ext
,
2049 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_type
);
2050 proto_tree_add_item (addr_tree
, hf_addr_ext_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2052 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_length2
, tvb
,
2054 "Address Length (bits 9-5): %d",
2056 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2057 proto_tree_add_item (addr_tree
, hf_addr_ext_length2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2060 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_length
, tvb
,
2061 offset
, 1, value
, "Address Length: %d",
2063 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2064 proto_tree_add_item (addr_tree
, hf_addr_ext_length1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2068 if (type
== ASN1_BER
) {
2069 tvbuff_t
*next_tvb
= tvb_new_subset_length(tvb
, offset
, length
);
2071 dissect_p1_ORName (false, next_tvb
, 0, &asn1_ctx
, ext_tree
,
2072 hf_addr_ext_asn1_ber
);
2073 } else if (type
== ASN1_PER
) {
2074 proto_tree_add_item (ext_tree
, hf_addr_ext_asn1_per
, tvb
, offset
, length
, ENC_NA
);
2076 proto_tree_add_item (ext_tree
, hf_addr_ext_unknown
, tvb
, offset
, length
, ENC_NA
);
2080 if (addr_length_extended
) {
2081 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_length_generated
,
2082 tvb
, offset
, 0, length
,
2083 "Address Length: %d", length
);
2084 proto_item_set_generated (en
);
2087 proto_item_append_text (ef
, ", Type: %s, Length: %d",
2088 val_to_str_const (type
, ext_addr_type
, "Reserved"),
2092 proto_item_append_text (tf
, " %d", rec_no
);
2093 if (rec_ofs
!= -1) {
2094 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
2097 proto_item_append_text (tf
, ", %sExtended Address Type: %s",
2098 val_to_str_const (addr_type
, addr_type_str
, ""),
2099 val_to_str_const (type
, ext_addr_type_short
, "Reserved"));
2101 proto_item_set_len (ef
, offset
- boffset
);
2106 /* Ref chapter 5.2.8.1 Extended Originator Encoding */
2107 static int dissect_dmp_originator (tvbuff_t
*tvb
, packet_info
*pinfo
,
2108 proto_tree
*envelope_tree
, int offset
)
2110 proto_tree
*field_tree
= NULL
, *rec_tree
= NULL
;
2111 proto_item
*en
= NULL
, *tf
= NULL
;
2112 uint8_t value
, dmp_addr_form
;
2113 int boffset
= offset
;
2114 bool p2_addr
= false;
2116 tf
= proto_tree_add_item (envelope_tree
, hf_addr_originator
, tvb
, offset
, -1, ENC_NA
);
2117 field_tree
= proto_item_add_subtree (tf
, ett_address
);
2119 if (dmp
.addr_enc
== DIRECT_ADDR
) {
2120 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
,
2121 offset
, -1, -1, ORIGINATOR
);
2123 value
= tvb_get_uint8 (tvb
, offset
);
2124 dmp_addr_form
= (value
& 0xE0) >> 5;
2126 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2127 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form_orig_v1
, tvb
,
2130 val_to_str_const (dmp_addr_form
,
2131 addr_form_orig_v1
, "Reserved"));
2132 rec_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2133 proto_tree_add_item (rec_tree
, hf_addr_ext_form_orig_v1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2135 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form_orig
, tvb
,
2138 val_to_str_const (dmp_addr_form
,
2139 addr_form_orig
, "Reserved"));
2140 rec_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2141 proto_tree_add_item (rec_tree
, hf_addr_ext_form_orig
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2144 en
= proto_tree_add_item (rec_tree
, hf_reserved_0x1F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2146 expert_add_info(pinfo
, en
, &ei_reserved_value
);
2150 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2151 switch (dmp_addr_form
) {
2154 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2160 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2165 proto_item_append_text (tf
, " (invalid address form)");
2170 switch (dmp_addr_form
) {
2174 case P1_DIRECT_P2_EXTENDED
:
2175 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2181 case P1_EXTENDED_P2_DIRECT
:
2182 case P1_P2_EXTENDED
:
2183 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2188 proto_item_append_text (tf
, " (invalid address form)");
2193 switch (dmp_addr_form
) {
2196 case P1_EXTENDED_P2_DIRECT
:
2197 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2203 case P1_DIRECT_P2_EXTENDED
:
2204 case P1_P2_EXTENDED
:
2205 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2206 -1, ORIG_P2_ADDRESS
);
2214 if (dmp
.msg_type
== NOTIF
) {
2215 en
= proto_tree_add_boolean (field_tree
, hf_addr_int_rec
, tvb
,
2218 en
= proto_tree_add_boolean (field_tree
, hf_addr_dl_expanded
, tvb
,
2221 proto_item_set_generated (en
);
2224 proto_item_set_len (tf
, offset
- boffset
);
2229 static void dmp_add_recipient_info (proto_item
*tf
, uint8_t rep_req
,
2230 uint8_t not_req
, bool action
)
2232 if (rep_req
|| not_req
) {
2233 proto_item_append_text (tf
, ", Request:");
2236 proto_item_append_text (tf
, "%s",
2237 val_to_str_const (rep_req
, report_vals_short
, ""));
2240 dmp
.notif_req
= true;
2241 proto_item_append_text (tf
, "%s",
2242 val_to_str_const (not_req
, notif_vals_short
, ""));
2245 if (dmp
.msg_type
== STANAG
) {
2246 proto_item_append_text (tf
, " (Action)");
2247 } else if (dmp
.msg_type
== IPM
) {
2248 proto_item_append_text (tf
, " (To)");
2251 if (dmp
.msg_type
== STANAG
) {
2252 proto_item_append_text (tf
, " (Info)");
2253 } else if (dmp
.msg_type
== IPM
) {
2254 proto_item_append_text (tf
, " (Cc)");
2259 /* Ref chapter 5.2.7 Direct Recipient Encoding */
2260 static int dissect_dmp_direct_encoding (tvbuff_t
*tvb
, packet_info
*pinfo
,
2261 proto_tree
*field_tree
, proto_item
*tf
,
2262 int offset
, unsigned *prev_rec_no
)
2265 proto_tree
*addr_tree
= NULL
, *rec_tree
= NULL
;
2266 proto_item
*en
= NULL
;
2267 uint8_t rep_req
= 0, not_req
= 0, value
;
2268 int rec_no
, rec_ofs
= -1, dir_addr
;
2269 bool action
= false, dir_addr_extended
= false;
2271 value
= tvb_get_uint8 (tvb
, offset
);
2272 rec_no
= (value
& 0xF0) >> 4;
2273 rep_req
= (value
& 0x0C) >> 2;
2274 not_req
= (value
& 0x03);
2276 if (rep_req
== 0x03) {
2277 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_rec_no1
,
2278 tvb
, offset
, 1, value
,
2279 "Recipient Number (bits 3-0): %d"
2280 " (offset from previous)",
2281 (value
& 0xF0) >> 4);
2283 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_rec_no
,
2284 tvb
, offset
, 1, value
,
2285 "Recipient Number Offset: %d"
2286 " (offset from previous)",
2287 (value
& 0xF0) >> 4);
2289 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2290 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2291 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2292 proto_tree_add_item (rec_tree
, hf_addr_dir_not_req1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2295 value
= tvb_get_uint8 (tvb
, offset
);
2296 dir_addr
= (value
& 0x7F);
2297 action
= (value
& 0x80);
2298 if (not_req
== 0x03) {
2299 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address1
,
2300 tvb
, offset
, 1, value
,
2301 "Direct Address (bits 6-0): %d",
2304 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address
,
2305 tvb
, offset
, 1, value
,
2306 "Direct Address: %d",
2309 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2310 proto_tree_add_item (addr_tree
, hf_addr_dir_action
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2311 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2314 if (rep_req
== 0x03) {
2315 /* Extended Recipient Number 1 */
2316 value
= tvb_get_uint8 (tvb
, offset
);
2317 rec_no
|= ((value
& 0x3F) << 4);
2319 rep_req
= (value
& 0xC0) >> 6;
2321 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_rec_no2
,
2322 tvb
, offset
, 1, value
,
2323 "Recipient Number (bits 9-4): %d"
2324 " (offset from previous)",
2326 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2327 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2328 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2331 if (rep_req
== 0x03) {
2332 /* Extended Recipient Number 2 */
2333 value
= tvb_get_uint8 (tvb
, offset
);
2334 rec_no
|= ((value
& 0x1F) << 10);
2336 rep_req
= (value
& 0xC0) >> 6;
2338 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_rec_no3
,
2339 tvb
, offset
, 1, value
,
2340 "Recipient Number (bits 14-10): %d"
2341 " (offset from previous)",
2343 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2344 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2345 en
= proto_tree_add_item (rec_tree
, hf_reserved_0x20
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2347 expert_add_info(pinfo
, en
, &ei_reserved_value
);
2349 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2354 if (not_req
== 0x03) {
2355 /* Extended Direct Address 1 */
2356 dir_addr_extended
= true;
2357 value
= tvb_get_uint8 (tvb
, offset
);
2358 dir_addr
|= ((value
& 0x3F) << 7);
2359 not_req
= (value
& 0xC0) >> 6;
2361 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address2
, tvb
,
2363 "Direct Address (bits 12-7): %d",
2365 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2366 proto_tree_add_item (addr_tree
, hf_addr_dir_not_req2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2367 proto_tree_add_item (addr_tree
, hf_addr_dir_address2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2370 if (not_req
== 0x03) {
2371 /* Extended Direct Address 2 */
2372 value
= tvb_get_uint8 (tvb
, offset
);
2373 dir_addr
|= ((value
& 0x3F) << 13);
2374 not_req
= (value
& 0xC0) >> 6;
2376 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address3
, tvb
,
2378 "Direct Address (bits 18-13): %d",
2380 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2381 proto_tree_add_item (addr_tree
, hf_addr_dir_not_req3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2382 proto_tree_add_item (addr_tree
, hf_addr_dir_address3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2387 rec_no
+= *prev_rec_no
;
2388 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2391 *prev_rec_no
= rec_no
;
2393 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_rec_no_generated
,
2394 tvb
, offset
, 0, rec_no
,
2395 "Recipient Number: %d", rec_no
);
2396 if (rec_no
> 32767) {
2397 proto_item_append_text (en
, " (maximum 32767)");
2398 expert_add_info(pinfo
, en
, &ei_addr_dir_rec_no_generated
);
2400 proto_item_set_generated (en
);
2402 if (dir_addr_extended
) {
2403 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address_generated
,
2404 tvb
, offset
, 0, dir_addr
,
2405 "Direct Address: %d", dir_addr
);
2406 proto_item_set_generated (en
);
2409 proto_item_append_text (tf
, " %d", rec_no
);
2410 if (rec_ofs
!= -1) {
2411 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
2414 proto_item_append_text (tf
, ", Direct Address: %d", dir_addr
);
2415 dmp_add_recipient_info (tf
, rep_req
, not_req
, action
);
2420 /* Ref 5.2.8.2 Extended Recipient Encoding */
2421 static int dissect_dmp_ext_encoding (tvbuff_t
*tvb
, packet_info
*pinfo
,
2422 proto_tree
*field_tree
,
2423 proto_item
*tf
, int offset
,
2424 unsigned *prev_rec_no
)
2426 proto_tree
*addr_tree
= NULL
;
2427 proto_item
*en
= NULL
;
2428 uint8_t rep_req
= 0, not_req
= 0;
2429 uint8_t value
, dmp_addr_form
;
2430 bool action
= false;
2431 int rec_no
, rec_ofs
= -1;
2433 value
= tvb_get_uint8 (tvb
, offset
);
2434 dmp_addr_form
= (value
& 0xE0) >> 5;
2435 action
= (value
& 0x10);
2436 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form
, tvb
,
2439 val_to_str_const (dmp_addr_form
,
2440 addr_form
, "Reserved"));
2441 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2442 proto_tree_add_item (addr_tree
, hf_addr_ext_form
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2444 en
= proto_tree_add_boolean_format (field_tree
, hf_addr_ext_action
, tvb
,
2445 offset
, 1, value
, "Action: %s",
2446 action
? "Yes" : "No");
2447 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_action
);
2448 proto_tree_add_item (addr_tree
, hf_addr_ext_action
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2450 rep_req
= (value
& 0x0C) >> 2;
2451 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rep_req
, tvb
,
2453 "Report Request: %s",
2454 val_to_str_const ((value
& 0x0C) >> 2,
2455 report_vals
, "Reserved"));
2456 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rep_req
);
2457 proto_tree_add_item (addr_tree
, hf_addr_ext_rep_req
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2459 not_req
= (value
& 0x03);
2460 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_not_req
, tvb
,
2462 "Notification Request: %s",
2463 val_to_str_const (value
& 0x03,
2464 notif_vals
, "Reserved"));
2465 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_not_req
);
2466 proto_tree_add_item (addr_tree
, hf_addr_ext_not_req
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2469 value
= tvb_get_uint8 (tvb
, offset
);
2470 rec_no
= (value
& 0x7F);
2472 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rec_no1
, tvb
,
2474 "Recipient Number (bits 6-0): %d"
2475 " (offset from previous)",
2477 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2478 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2479 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2483 value
= tvb_get_uint8 (tvb
, offset
);
2484 rec_no
|= (value
<< 7);
2486 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rec_no2
, tvb
,
2488 "Recipient Number (bits 14-7): %d"
2489 " (offset from previous)", value
);
2490 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2491 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2495 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rec_no
, tvb
,
2497 "Recipient Number Offset: %d"
2498 " (offset from previous)",
2500 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2501 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2502 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2507 rec_no
+= *prev_rec_no
;
2508 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2511 *prev_rec_no
= rec_no
;
2513 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rec_no_generated
,
2514 tvb
, offset
, 0, rec_no
,
2515 "Recipient Number: %d", rec_no
);
2516 if (rec_no
> 32767) {
2517 proto_item_append_text (en
, " (maximum 32767)");
2518 expert_add_info(pinfo
, en
, &ei_addr_ext_rec_no_generated
);
2520 proto_item_set_generated (en
);
2522 switch (dmp_addr_form
) {
2526 case P1_DIRECT_P2_EXTENDED
:
2527 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2528 rec_no
, rec_ofs
, P1_ADDRESS
);
2532 case P1_EXTENDED_P2_DIRECT
:
2533 case P1_P2_EXTENDED
:
2534 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2535 rec_no
, rec_ofs
, P1_ADDRESS
);
2540 switch (dmp_addr_form
) {
2544 case P1_EXTENDED_P2_DIRECT
:
2545 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2546 rec_no
, rec_ofs
, P2_ADDRESS
);
2550 case P1_DIRECT_P2_EXTENDED
:
2551 case P1_P2_EXTENDED
:
2552 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2553 rec_no
, rec_ofs
, P2_ADDRESS
);
2558 dmp_add_recipient_info (tf
, rep_req
, not_req
, action
);
2563 /* Ref chapter 5.2 Address encoding */
2564 static int dissect_dmp_address (tvbuff_t
*tvb
, packet_info
*pinfo
,
2565 proto_tree
*envelope_tree
,
2566 int offset
, unsigned *prev_rec_no
,
2567 bool reporting_name
)
2569 proto_tree
*field_tree
= NULL
;
2570 proto_item
*tf
= NULL
;
2571 int boffset
= offset
;
2573 if (reporting_name
) {
2574 tf
= proto_tree_add_item (envelope_tree
, hf_addr_reporting_name
, tvb
, offset
, -1, ENC_NA
);
2576 tf
= proto_tree_add_none_format (envelope_tree
, hf_addr_recipient
, tvb
,
2577 offset
, -1, "Recipient Number");
2579 field_tree
= proto_item_add_subtree (tf
, ett_address
);
2581 if (dmp
.addr_enc
== DIRECT_ADDR
) {
2582 offset
= dissect_dmp_direct_encoding (tvb
, pinfo
, field_tree
, tf
,
2583 offset
, prev_rec_no
);
2585 offset
= dissect_dmp_ext_encoding (tvb
, pinfo
, field_tree
, tf
, offset
,
2589 proto_item_set_len (tf
, offset
- boffset
);
2594 /* Ref chapter 6.2.9 Acknowledgement */
2595 static int dissect_dmp_ack (tvbuff_t
*tvb
, packet_info
*pinfo
,
2596 proto_tree
*dmp_tree
, int offset
)
2598 proto_tree
*ack_tree
= NULL
, *recip_tree
= NULL
;
2599 proto_item
*en
= NULL
, *rt
= NULL
;
2600 proto_item
*hidden_item
;
2601 unsigned prev_rec_no
= 0;
2602 int rec_len
, rec_no
= 0;
2603 int boffset
= offset
;
2605 en
= proto_tree_add_item (dmp_tree
, hf_ack
, tvb
, offset
, 4, ENC_NA
);
2606 ack_tree
= proto_item_add_subtree (en
, ett_ack
);
2608 dmp
.ack_reason
= tvb_get_uint8 (tvb
, offset
);
2609 proto_item_append_text (en
, ", Reason: %s",
2610 val_to_str_const (dmp
.ack_reason
, ack_reason
, "Reserved"));
2612 rt
= proto_tree_add_item (ack_tree
, hf_ack_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2613 if (dmp
.ack_reason
!= 0) {
2614 expert_add_info_format(pinfo
, rt
, &ei_ack_reason
, "ACK reason: %s", val_to_str_const (dmp
.ack_reason
, ack_reason
, "Reserved"));
2618 proto_tree_add_item (ack_tree
, hf_ack_diagnostic
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2621 /* Subject Message Identifier */
2622 dmp
.subj_id
= tvb_get_ntohs (tvb
, offset
);
2623 proto_tree_add_item (ack_tree
, hf_message_subj_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2624 hidden_item
= proto_tree_add_item (ack_tree
, hf_dmp_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2625 proto_item_set_hidden (hidden_item
);
2628 if (use_seq_ack_analysis
) {
2629 register_dmp_id (pinfo
, dmp
.ack_reason
);
2632 if (dmp
.ack_rec_present
) {
2633 /* Recipient List */
2634 rec_len
= tvb_reported_length (tvb
);
2638 if (offset
< rec_len
) {
2639 rt
= proto_tree_add_item (ack_tree
, hf_ack_recips
, tvb
, offset
, -1, ENC_NA
);
2640 recip_tree
= proto_item_add_subtree (rt
, ett_ack_recips
);
2641 while (offset
< rec_len
) {
2642 offset
= dissect_dmp_address (tvb
, pinfo
, recip_tree
, offset
,
2643 &prev_rec_no
, false);
2646 proto_item_append_text (rt
, ", No Recipients: %d", rec_no
);
2647 proto_item_set_len (rt
, offset
- boffset
- 4);
2648 proto_item_set_len (en
, offset
- boffset
);
2655 static int dissect_mts_identifier (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2656 int offset
, bool subject
)
2658 proto_item
*ti
, *hidden_item
;
2660 unsigned char byte_rest
= 0;
2662 if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp_nat_decode
== NAT_DECODE_DMP
) {
2663 mts_id
= dissect_7bit_string (tvb
, offset
, dmp
.mts_id_length
, &byte_rest
);
2664 } else if (dmp_nat_decode
== NAT_DECODE_THALES
) {
2665 mts_id
= dissect_thales_mts_id (tvb
, offset
, dmp
.mts_id_length
, &byte_rest
);
2667 mts_id
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, dmp
.mts_id_length
);
2669 proto_item_append_text (dmp
.mts_id_item
, " (%zu bytes decompressed)", strlen(mts_id
));
2670 mts_id
= format_text(pinfo
->pool
, mts_id
, strlen(mts_id
));
2672 ti
= proto_tree_add_string (tree
, hf_message_subj_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2673 hidden_item
= proto_tree_add_string (tree
, hf_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2674 /* Read from hash, for analysis */
2675 dmp
.subj_id
= GPOINTER_TO_UINT (wmem_map_lookup (dmp_long_id_hash_table
, mts_id
));
2677 ti
= proto_tree_add_string (tree
, hf_envelope_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2678 hidden_item
= proto_tree_add_string (tree
, hf_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2679 /* Insert into hash, for analysis */
2680 wmem_map_insert (dmp_long_id_hash_table
, wmem_strdup (wmem_file_scope(), mts_id
), GUINT_TO_POINTER ((unsigned)dmp
.msg_id
));
2682 proto_item_set_hidden (hidden_item
);
2683 offset
+= dmp
.mts_id_length
;
2686 expert_add_info (pinfo
, ti
, &ei_7bit_string_unused_bits
);
2692 static int dissect_ipm_identifier (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2693 int offset
, bool subject
)
2695 proto_tree
*field_tree
;
2696 proto_item
*ti
, *tf
, *hidden_item
;
2698 int length
, modifier
, ipm_id_length
;
2699 unsigned char byte_rest
= 0;
2701 length
= tvb_get_uint8 (tvb
, offset
);
2702 modifier
= (length
& 0xC0) >> 6;
2703 ipm_id_length
= length
& 0x3F;
2705 tf
= proto_tree_add_uint_format (tree
, hf_envelope_ipm_id_length
,
2706 tvb
, offset
, 1, ipm_id_length
,
2707 "IPM Identifier Length: %u",
2709 field_tree
= proto_item_add_subtree (tf
, ett_envelope_ipm_id_length
);
2710 if ((dmp
.msg_id_type
== NAT_MSG_ID
|| modifier
!= IPM_MODIFIER_X400
) && dmp_nat_decode
== NAT_DECODE_THALES
) {
2711 proto_tree_add_item (field_tree
, hf_thales_ipm_id_modifier
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2713 proto_tree_add_item (field_tree
, hf_envelope_ipm_id_modifier
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2715 proto_tree_add_item (field_tree
, hf_envelope_ipm_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2718 if (modifier
== IPM_MODIFIER_X400
|| dmp_nat_decode
== NAT_DECODE_DMP
) {
2719 ipm_id
= dissect_7bit_string (tvb
, offset
, ipm_id_length
, &byte_rest
);
2720 } else if (dmp_nat_decode
== NAT_DECODE_THALES
) {
2721 ipm_id
= dissect_thales_ipm_id (tvb
, offset
, ipm_id_length
, modifier
, &byte_rest
);
2723 ipm_id
= tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, ipm_id_length
);
2725 proto_item_append_text (tf
, " (%zu bytes decompressed)", strlen(ipm_id
));
2726 ipm_id
= format_text(pinfo
->pool
, ipm_id
, strlen(ipm_id
));
2728 ti
= proto_tree_add_string (tree
, hf_message_subj_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2729 hidden_item
= proto_tree_add_string (tree
, hf_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2730 /* Read from hash, for analysis */
2731 dmp
.subj_id
= GPOINTER_TO_UINT (wmem_map_lookup (dmp_long_id_hash_table
, ipm_id
));
2733 ti
= proto_tree_add_string (tree
, hf_envelope_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2734 hidden_item
= proto_tree_add_string (tree
, hf_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2735 /* Insert into hash, for analysis */
2736 wmem_map_insert (dmp_long_id_hash_table
, wmem_strdup (wmem_file_scope(), ipm_id
), GUINT_TO_POINTER ((unsigned)dmp
.msg_id
));
2738 proto_item_set_hidden (hidden_item
);
2739 offset
+= ipm_id_length
;
2742 expert_add_info (pinfo
, ti
, &ei_7bit_string_unused_bits
);
2748 /* Ref chapter 6.2.7 Envelope structure */
2749 static int dissect_dmp_envelope (tvbuff_t
*tvb
, packet_info
*pinfo
,
2750 proto_tree
*dmp_tree
, int offset
)
2752 proto_tree
*envelope_tree
= NULL
;
2753 proto_tree
*field_tree
= NULL
;
2754 proto_item
*en
= NULL
, *tf
= NULL
, *vf
= NULL
;
2755 proto_item
*hidden_item
;
2756 uint8_t envelope
, time_diff
;
2757 uint16_t subm_time
, no_rec
, value16
;
2759 char *env_flags
= NULL
;
2760 unsigned prev_rec_no
= 0;
2761 int boffset
= offset
, i
;
2762 bool using_short_id
= false;
2764 en
= proto_tree_add_item (dmp_tree
, hf_envelope
, tvb
, offset
, 10, ENC_NA
);
2765 envelope_tree
= proto_item_add_subtree (en
, ett_envelope
);
2767 envelope
= tvb_get_uint8 (tvb
, offset
);
2768 dmp
.prot_id
= (envelope
& 0xF8) >> 3;
2769 dmp
.version
= (envelope
& 0x07) + 1;
2771 /* Protocol Version */
2772 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_version
,
2773 tvb
, offset
, 1, dmp
.version
,
2774 "Protocol Version: %d", dmp
.version
);
2776 field_tree
= proto_item_add_subtree (tf
, ett_envelope_version
);
2777 vf
= proto_tree_add_item (field_tree
, hf_envelope_protocol_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2778 if (dmp
.prot_id
== PROT_NAT
) {
2779 proto_item_append_text (vf
, " (national version of DMP)");
2780 proto_item_append_text (tf
, " (national)");
2781 } else if (dmp
.prot_id
== PROT_DMP
) {
2782 proto_item_append_text (vf
, " (correct)");
2784 proto_item_append_text (vf
, " (incorrect, should be 0x1d)");
2786 vf
= proto_tree_add_item (field_tree
, hf_envelope_version_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2789 if (dmp
.version
> DMP_VERSION_2
) {
2790 /* Unsupported DMP Version */
2791 proto_item_append_text (vf
, " (unsupported)");
2792 proto_item_append_text (tf
, " (unsupported)");
2793 expert_add_info_format(pinfo
, vf
, &ei_envelope_version_value
, "Unsupported DMP Version: %d", dmp
.version
);
2797 envelope
= tvb_get_uint8 (tvb
, offset
);
2798 dmp
.addr_enc
= ((envelope
& 0x10) >> 4);
2799 dmp
.checksum
= ((envelope
& 0x08) >> 3);
2800 dmp
.msg_type
= (envelope
& 0x07);
2802 if (dmp
.msg_type
!= ACK
) {
2804 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_hop_count
,
2805 tvb
, offset
, 1, envelope
,
2806 "Hop Count: %d", (envelope
& 0xE0) >> 5);
2807 field_tree
= proto_item_add_subtree (tf
, ett_envelope_hop_count
);
2808 proto_tree_add_item (field_tree
, hf_envelope_hop_count_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2810 if (dmp
.version
>= DMP_VERSION_2
) {
2811 /* Extensions Present */
2812 dmp
.extensions
= (envelope
& 0x80);
2813 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_extensions
,
2814 tvb
, offset
, 1, envelope
,
2816 tfs_get_string(envelope
& 0x80, &tfs_present_absent
));
2817 field_tree
= proto_item_add_subtree (tf
, ett_envelope_extensions
);
2818 proto_tree_add_item (field_tree
, hf_envelope_extensions
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2821 /* Recipient Present */
2822 dmp
.ack_rec_present
= (envelope
& 0x20);
2823 tf
= proto_tree_add_boolean_format (envelope_tree
,hf_envelope_rec_present
,
2824 tvb
, offset
, 1, envelope
,
2825 "Recipient Present: %s",
2826 tfs_get_string(envelope
& 0x20, &tfs_present_absent
));
2827 field_tree
= proto_item_add_subtree (tf
, ett_envelope_rec_present
);
2828 proto_tree_add_item (field_tree
, hf_envelope_rec_present
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2831 /* Address Encoding */
2832 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_addr_enc
,
2833 tvb
, offset
, 1, envelope
,
2834 "Address Encoding: %s",
2835 tfs_get_string(envelope
& 0x10, &addr_enc
));
2836 field_tree
= proto_item_add_subtree (tf
, ett_envelope_addr_enc
);
2837 proto_tree_add_item (field_tree
, hf_envelope_addr_enc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2839 /* Checksum Present */
2840 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_checksum
,
2841 tvb
, offset
, 1, envelope
,
2843 (envelope
& 0x08) ? "Used" : "Not used");
2844 field_tree
= proto_item_add_subtree (tf
, ett_envelope_checksum
);
2845 proto_tree_add_item (field_tree
, hf_envelope_checksum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2848 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_type
,
2849 tvb
, offset
, 1, envelope
,
2850 "Content Type: %s (%d)",
2851 val_to_str_const (envelope
& 0x07,
2852 type_vals
, "Unknown"),
2854 field_tree
= proto_item_add_subtree (tf
, ett_envelope_cont_type
);
2855 proto_tree_add_item (field_tree
, hf_envelope_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2857 proto_item_append_text (en
, ", Checksum %s", (envelope
>> 3) & 0x01 ? "Used" : "Not used");
2860 if (dmp
.msg_type
>= ACK
) {
2861 proto_item_set_len (en
, offset
- boffset
);
2865 if (dmp
.version
>= DMP_VERSION_2
) {
2866 envelope
= tvb_get_uint8 (tvb
, offset
);
2867 /* Extensions Present */
2868 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_extensions
,
2869 tvb
, offset
, 1, envelope
,
2871 (envelope
& 0x80) ? "Present" : "Absent");
2872 field_tree
= proto_item_add_subtree (tf
, ett_envelope_extensions
);
2873 proto_tree_add_item (field_tree
, hf_envelope_extensions
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2874 dmp
.extensions
= (envelope
& 0x80);
2876 /* Message Identifier Type */
2877 dmp
.msg_id_type
= (envelope
& 0x60) >> 5;
2878 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_msg_id_type
,
2879 tvb
, offset
, 1, envelope
,
2880 "Message Identifier Type: %s (%d)",
2881 val_to_str_const (dmp
.msg_id_type
, msg_id_type_vals
, "Unknown"),
2883 field_tree
= proto_item_add_subtree (tf
, ett_envelope_msg_id_type
);
2884 proto_tree_add_item (field_tree
, hf_envelope_msg_id_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2886 if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) {
2887 /* MTS Identifier Length */
2888 dmp
.mts_id_length
= (envelope
& 0x1F);
2889 dmp
.mts_id_item
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_mts_id_length
,
2890 tvb
, offset
, 1, envelope
,
2891 "MTS Identifier Length: %u",
2893 field_tree
= proto_item_add_subtree (dmp
.mts_id_item
, ett_envelope_mts_id_length
);
2894 proto_tree_add_item (field_tree
, hf_envelope_mts_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2897 proto_tree_add_item (field_tree
, hf_envelope_msg_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2898 if (envelope
& 0x10) {
2899 /* Using Short Identifier (12 bits) */
2900 using_short_id
= true;
2902 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x0F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2903 if (envelope
& 0x0F) {
2904 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
2911 /* Message Identifier */
2912 dmp
.msg_id
= tvb_get_ntohs (tvb
, offset
);
2913 if (using_short_id
) {
2914 dmp
.msg_id
&= 0x0FFF;
2916 tf
= proto_tree_add_uint (envelope_tree
, hf_envelope_msg_id
, tvb
, offset
, 2, dmp
.msg_id
);
2917 hidden_item
= proto_tree_add_uint (envelope_tree
, hf_dmp_id
, tvb
, offset
, 2, dmp
.msg_id
);
2918 if (using_short_id
) {
2919 field_tree
= proto_item_add_subtree (tf
, ett_envelope_msg_id
);
2920 proto_tree_add_item (field_tree
, hf_envelope_msg_id_12bit
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2921 } else if (dmp
.version
>= DMP_VERSION_2
&& dmp
.msg_id_type
== ONLY_DMP_ID
&& dmp
.msg_id
< 4096) {
2922 expert_add_info(pinfo
, tf
, &ei_envelope_msg_id
);
2924 proto_item_set_hidden (hidden_item
);
2927 if (dmp
.version
>= DMP_VERSION_2
) {
2928 if ((dmp
.msg_type
!= REPORT
) && (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
)) {
2929 offset
= dissect_mts_identifier (tvb
, pinfo
, envelope_tree
, offset
, false);
2933 /* Submission Time */
2934 subm_time
= tvb_get_ntohs (tvb
, offset
);
2935 dmp
.subm_time
= dmp_dec_subm_time ((uint16_t)(subm_time
& 0x7FFF),
2936 (int32_t) pinfo
->abs_ts
.secs
);
2937 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_subm_time
, tvb
,
2938 offset
, 2, subm_time
,
2939 "Submission time: %s",
2940 (subm_time
& 0x7FFF) >= 0x7FF8 ?
2942 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
, ABSOLUTE_TIME_LOCAL
, true));
2943 field_tree
= proto_item_add_subtree (tf
, ett_envelope_subm_time
);
2944 proto_tree_add_item (field_tree
, hf_envelope_time_diff_present
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2945 proto_tree_add_item (field_tree
, hf_envelope_subm_time_value
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2948 if (subm_time
& 0x8000) {
2949 /* Timed Difference */
2950 time_diff
= tvb_get_uint8 (tvb
, offset
);
2951 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_time_diff
,
2952 tvb
, offset
, 1, time_diff
,
2953 "Time Difference: ");
2954 field_tree
= proto_item_add_subtree (tf
, ett_envelope_time_diff
);
2955 proto_tree_add_item (field_tree
, hf_envelope_time_diff_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2956 secs
= dmp_dec_time_diff (time_diff
);
2957 if (secs
== DMP_TIME_RESERVED
) {
2958 proto_item_append_text (tf
, "Reserved (0x%2.2x)", time_diff
);
2960 proto_item_append_text (tf
, "%s", signed_time_secs_to_str(pinfo
->pool
, secs
));
2965 /* Envelope Flags */
2966 envelope
= tvb_get_uint8 (tvb
, offset
);
2967 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_flags
,
2968 tvb
, offset
, 1, envelope
,
2971 field_tree
= proto_item_add_subtree (tf
, ett_envelope_flags
);
2972 proto_tree_add_item (field_tree
, hf_envelope_content_id_discarded
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2973 proto_tree_add_item (field_tree
, hf_envelope_recip_reassign_prohib
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2974 proto_tree_add_item (field_tree
, hf_envelope_dl_expansion_prohib
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2976 if (envelope
& 0xE0) {
2977 env_flags
= wmem_strdup_printf (pinfo
->pool
, "%s%s%s",
2978 (envelope
& 0x80) ? ", ContId discarded" : "",
2979 (envelope
& 0x40) ? ", Reass prohibited" : "",
2980 (envelope
& 0x20) ? ", DLE prohibited" : "");
2981 proto_item_append_text (tf
, ":%s", &env_flags
[1]);
2983 proto_item_append_text (tf
, " (none)");
2986 /* Recipient Count */
2987 no_rec
= (envelope
& 0x1F);
2988 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_recipients
,
2989 tvb
, offset
, 1, envelope
,
2990 "Recipient Count: %d", no_rec
);
2992 field_tree
= proto_item_add_subtree (tf
, ett_envelope_recipients
);
2993 proto_tree_add_item (field_tree
, hf_envelope_recipients
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2997 /* Extended Recipient Count */
2998 value16
= tvb_get_ntohs (tvb
, offset
);
2999 no_rec
= value16
& 0x7FFF;
3000 tf
= proto_tree_add_uint_format (envelope_tree
,hf_envelope_ext_recipients
,
3001 tvb
, offset
, 2, value16
,
3002 "Extended Recipient Count: %d%s", no_rec
,
3004 " (incorrect, reserved value)" : ""));
3006 field_tree
= proto_item_add_subtree (tf
, ett_envelope_ext_recipients
);
3007 en
= proto_tree_add_item (field_tree
, hf_reserved_0x8000
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3008 if (value16
& 0x8000) {
3009 expert_add_info(pinfo
, en
, &ei_reserved_value
);
3011 proto_tree_add_item (field_tree
, hf_envelope_ext_recipients
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3015 if (dmp
.msg_type
!= REPORT
) {
3016 /* Originator - Not present for reports */
3017 offset
= dissect_dmp_originator (tvb
, pinfo
, envelope_tree
, offset
);
3020 for (i
= 0; i
< no_rec
; i
++) {
3022 offset
= dissect_dmp_address (tvb
, pinfo
, envelope_tree
, offset
,
3023 &prev_rec_no
, false);
3026 if (dmp
.version
>= DMP_VERSION_2
) {
3027 if ((dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) &&
3028 dmp
.notif_req
&& (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
))
3030 offset
= dissect_ipm_identifier (tvb
, pinfo
, envelope_tree
, offset
, false);
3034 proto_item_set_len (en
, offset
- boffset
);
3040 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3041 * and chapter 6.3.8.1 IPM 88 message structure
3043 static int dissect_dmp_message (tvbuff_t
*tvb
, packet_info
*pinfo
,
3044 proto_tree
*dmp_tree
, int offset
)
3046 tvbuff_t
*body_tvb
= NULL
;
3047 proto_tree
*message_tree
= NULL
;
3048 proto_tree
*field_tree
= NULL
;
3049 proto_item
*en
= NULL
, *tf
= NULL
, *tr
= NULL
;
3050 uint8_t message
, eit
= 0, compr_alg
= ALGORITHM_NONE
;
3051 int len
, boffset
= offset
, body_offset
= 0, body_len
= 0;
3053 en
= proto_tree_add_item (dmp_tree
, hf_message_body
, tvb
, offset
, -1, ENC_NA
);
3054 message_tree
= proto_item_add_subtree (en
, ett_message
);
3056 if (dmp
.body_format
== FREE_TEXT_SUBJECT
) {
3057 len
= tvb_strsize (tvb
, offset
);
3058 proto_tree_add_item (message_tree
, hf_message_subject
, tvb
, offset
, len
, ENC_ASCII
);
3062 if (dmp
.body_format
== FREE_TEXT
|| dmp
.body_format
== FREE_TEXT_SUBJECT
) {
3063 message
= tvb_get_uint8 (tvb
, offset
);
3064 eit
= (message
& 0xE0) >> 5;
3065 compr_alg
= (message
& 0x18) >> 3;
3066 /* Encoded Information Type */
3067 tf
= proto_tree_add_uint_format (message_tree
, hf_message_eit
,
3068 tvb
, offset
, 1, message
, "EIT: %s (%d)",
3069 val_to_str_const (eit
, eit_vals
, "Unknown"),
3071 field_tree
= proto_item_add_subtree (tf
, ett_message_eit
);
3072 proto_tree_add_item (field_tree
, hf_message_eit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3073 proto_item_append_text (en
, ", Type: %s",
3074 val_to_str_const (eit
, eit_vals
, "Unknown"));
3076 /* Compression Algorithm */
3077 tf
= proto_tree_add_uint_format (message_tree
, hf_message_compr
,
3078 tvb
, offset
, 1, message
,
3079 "Compression Algorithm: %s (%d)",
3080 val_to_str_const (compr_alg
, compression_vals
, "Unknown"),
3082 field_tree
= proto_item_add_subtree (tf
, ett_message_compr
);
3083 tr
= proto_tree_add_item (field_tree
, hf_message_compr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3084 if (compr_alg
== ALGORITHM_ZLIB
) {
3085 proto_item_append_text (en
, " (compressed)");
3086 } else if (compr_alg
!= ALGORITHM_NONE
) {
3087 expert_add_info(pinfo
, tr
, &ei_message_compr
);
3090 if (message
& 0x07) {
3092 tf
= proto_tree_add_uint_format (message_tree
, hf_reserved_0x07
,
3093 tvb
, offset
, 1, message
,
3094 "Reserved: %d", message
& 0x07);
3095 field_tree
= proto_item_add_subtree (tf
, ett_message_body_reserved
);
3096 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x07
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3097 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3102 len
= tvb_reported_length_remaining (tvb
, offset
);
3106 THROW_MESSAGE(ReportedBoundsError
, "Packet length too short");
3110 if (compr_alg
== ALGORITHM_ZLIB
) {
3111 tf
= proto_tree_add_item (message_tree
, hf_message_body_compressed
,
3112 tvb
, offset
, len
, ENC_NA
);
3113 proto_item_append_text (tf
, ", Length: %d", len
);
3115 tf
= proto_tree_add_item (message_tree
, hf_message_body_data
,
3116 tvb
, offset
, len
, ENC_NA
);
3117 proto_item_set_text (tf
, "User data, Length: %d", len
);
3120 if (dmp
.body_format
== STRUCTURED
) {
3121 /* Structured Message ID */
3122 field_tree
= proto_item_add_subtree (tf
, ett_message_body
);
3123 proto_tree_add_item (field_tree
, hf_message_body_structured
, tvb
, offset
, len
, ENC_NA
);
3124 } else if (len
> 0 && (dmp
.body_format
== FREE_TEXT
||
3125 dmp
.body_format
== FREE_TEXT_SUBJECT
)) {
3126 if (compr_alg
== ALGORITHM_ZLIB
) {
3127 if ((body_tvb
= tvb_child_uncompress_zlib(tvb
, tvb
, offset
, len
)) != NULL
) {
3128 body_len
= tvb_captured_length (body_tvb
);
3129 add_new_data_source (pinfo
, body_tvb
, "Uncompressed User data");
3130 tf
= proto_tree_add_item (message_tree
, hf_message_body_data
,
3131 body_tvb
, 0, body_len
, ENC_NA
);
3132 proto_item_set_text (tf
, "User data, Length: %d", body_len
);
3133 proto_item_set_generated (tf
);
3135 proto_tree_add_expert (message_tree
, pinfo
, &ei_message_body_uncompress
, tvb
, offset
, len
);
3139 body_offset
= offset
;
3143 if (eit
!= EIT_BILATERAL
&& body_len
> 0) {
3144 field_tree
= proto_item_add_subtree (tf
, ett_message_body
);
3145 proto_tree_add_item (field_tree
, hf_message_body_plain
, body_tvb
,
3146 body_offset
, body_len
, ENC_ASCII
);
3151 proto_item_set_len (en
, offset
- boffset
);
3156 /* Ref chapter 6.3.9.1 Report structure */
3157 static int dissect_dmp_report (tvbuff_t
*tvb
, packet_info
*pinfo
,
3158 proto_tree
*dmp_tree
, int offset
,
3159 unsigned *prev_rec_no
, int num
)
3161 proto_tree
*report_tree
= NULL
;
3162 proto_tree
*field_tree
= NULL
;
3163 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3167 int len
, boffset
= offset
;
3170 report
= tvb_get_uint8 (tvb
, offset
);
3171 rep_type
= (report
& 0x80) >> 7;
3173 en
= proto_tree_add_item (dmp_tree
, hf_non_delivery_report
, tvb
, offset
, 4, ENC_NA
);
3175 en
= proto_tree_add_item (dmp_tree
, hf_delivery_report
, tvb
, offset
, 4, ENC_NA
);
3177 proto_item_append_text (en
, " (#%d)", num
);
3179 report_tree
= proto_item_add_subtree (en
, ett_report
);
3182 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_type
,
3183 tvb
, offset
, 1, report
,
3185 tfs_get_string(rep_type
, &report_type
));
3186 field_tree
= proto_item_add_subtree (tf
, ett_report_type
);
3187 proto_tree_add_item (field_tree
, hf_report_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3189 if (rep_type
== DR
) {
3192 info_present
= (report
& 0x40);
3193 tf
= proto_tree_add_boolean_format (report_tree
,hf_report_info_present_dr
,
3194 tvb
, offset
, 1, report
,
3196 tfs_get_string(report
& 0x40, &tfs_present_absent
));
3197 field_tree
= proto_item_add_subtree (tf
, ett_report_info_present_dr
);
3198 proto_tree_add_item (field_tree
, hf_report_info_present_dr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3200 /* Address Encoding */
3201 dmp
.addr_enc
= ((report
& 0x20) >> 5);
3202 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_addr_enc_dr
,
3203 tvb
, offset
, 1, report
,
3204 "Address Encoding: %s",
3205 tfs_get_string(report
& 0x20, &addr_enc
));
3206 field_tree
= proto_item_add_subtree (tf
, ett_report_addr_enc_dr
);
3207 proto_tree_add_item (field_tree
, hf_report_addr_enc_dr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3209 if (report
& 0x1F) {
3211 tf
= proto_tree_add_uint_format (report_tree
, hf_reserved_0x1F
,
3212 tvb
, offset
, 1, report
,
3213 "Reserved: %d", report
& 0x1F);
3214 field_tree
= proto_item_add_subtree (tf
, ett_report_reserved
);
3215 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x1F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3216 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3222 report
= tvb_get_uint8 (tvb
, offset
);
3223 tf
= proto_tree_add_uint_format (report_tree
, hf_report_del_time
,
3224 tvb
, offset
, 1, report
,
3226 field_tree
= proto_item_add_subtree (tf
, ett_report_del_time
);
3227 ei
= proto_tree_add_item (field_tree
, hf_report_del_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3228 secs
= dmp_dec_del_time (report
);
3229 if (secs
== DMP_TIME_RESERVED
) {
3230 proto_item_append_text (tf
, "Reserved (0x%2.2x)", report
);
3231 proto_item_append_text (ei
, " (Reserved)");
3233 proto_item_append_text (tf
, "%s (%s)", signed_time_secs_to_str(pinfo
->pool
, secs
),
3234 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, true));
3235 proto_item_append_text (ei
, " (%s from submission time)", signed_time_secs_to_str(pinfo
->pool
, secs
));
3239 /* Address Encoding */
3240 dmp
.addr_enc
= ((report
& 0x40) >> 6);
3241 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_addr_enc_ndr
,
3242 tvb
, offset
, 1, report
,
3243 "Address Encoding: %s",
3244 tfs_get_string(report
& 0x40, &addr_enc
));
3245 field_tree
= proto_item_add_subtree (tf
, ett_report_addr_enc_ndr
);
3246 proto_tree_add_item (field_tree
, hf_report_addr_enc_ndr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3249 tf
= proto_tree_add_uint_format (report_tree
, hf_report_reason
,
3250 tvb
, offset
, 1, report
,
3251 "Reason%s: %s (%d)",
3252 ((report
& 0x3F) < 0x3D) ? " (P1)":"",
3253 non_del_reason_str (report
& 0x3F),
3255 field_tree
= proto_item_add_subtree (tf
, ett_report_reason
);
3256 proto_tree_add_item (field_tree
, hf_report_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3260 report
= tvb_get_uint8 (tvb
, offset
);
3261 info_present
= (report
& 0x80);
3262 tf
= proto_tree_add_boolean_format (report_tree
,
3263 hf_report_info_present_ndr
,
3264 tvb
, offset
, 1, report
,
3265 "Info Present: %s", (report
& 0x80) ? "Present" : "Absent");
3266 field_tree
= proto_item_add_subtree (tf
, ett_report_info_present_ndr
);
3267 proto_tree_add_item (field_tree
, hf_report_info_present_ndr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3270 tf
= proto_tree_add_uint_format (report_tree
, hf_report_diagn
,
3271 tvb
, offset
, 1, report
,
3272 "Diagnostic%s: %s (%d)",
3273 ((report
& 0x7F) < 0x7C) ? " (P1)":"",
3274 non_del_diagn_str (report
& 0x7F),
3276 field_tree
= proto_item_add_subtree (tf
, ett_report_diagn
);
3277 proto_tree_add_item (field_tree
, hf_report_diagn
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3281 offset
= dissect_dmp_address (tvb
, pinfo
, report_tree
, offset
,
3285 /* Supplementary Information */
3286 len
= tvb_strsize (tvb
, offset
);
3287 tf
= proto_tree_add_uint_format (report_tree
, hf_report_suppl_info_len
,
3288 tvb
, offset
, len
, len
,
3289 "Supplementary Information, Length: %d",
3292 if ((offset
- boffset
+ len
) > 128) {
3293 proto_item_append_text (tf
, " (incorrect, should be less than %d)",
3294 128 - (offset
- boffset
));
3296 field_tree
= proto_item_add_subtree (tf
, ett_report_suppl_info
);
3297 proto_tree_add_item (field_tree
, hf_report_suppl_info
, tvb
, offset
, len
, ENC_ASCII
);
3302 proto_item_set_len (en
, offset
- boffset
);
3307 /* Ref chapter 6.3.10.1 Notification structure */
3308 static int dissect_dmp_notification (tvbuff_t
*tvb
, packet_info
*pinfo
,
3309 proto_tree
*dmp_tree
, int offset
)
3311 proto_tree
*notif_tree
= NULL
;
3312 proto_tree
*field_tree
= NULL
;
3313 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3314 uint8_t notif
, rec_time
, on_typex
= 0xFF;
3315 int len
, boffset
= offset
;
3318 if (dmp
.notif_type
== RN
) {
3319 en
= proto_tree_add_item (dmp_tree
, hf_receipt_notif
, tvb
, offset
, 4, ENC_NA
);
3320 } else if (dmp
.notif_type
== NRN
) {
3321 en
= proto_tree_add_item (dmp_tree
, hf_non_receipt_notif
, tvb
, offset
, 4, ENC_NA
);
3322 } else if (dmp
.notif_type
== ON
) {
3323 en
= proto_tree_add_item (dmp_tree
, hf_other_notif
, tvb
, offset
, 4, ENC_NA
);
3327 notif_tree
= proto_item_add_subtree (en
, ett_notif
);
3329 if (dmp
.notif_type
== RN
|| dmp
.notif_type
== ON
) {
3331 rec_time
= tvb_get_uint8 (tvb
, offset
);
3332 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_rec_time
,
3333 tvb
, offset
, 1, rec_time
,
3335 field_tree
= proto_item_add_subtree (tf
, ett_notif_rec_time
);
3336 ei
= proto_tree_add_item (field_tree
, hf_notif_rec_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3337 secs
= dmp_dec_exp_time (rec_time
);
3338 if (secs
== DMP_TIME_NOT_PRESENT
) {
3339 proto_item_append_text (tf
, "Not present");
3340 proto_item_append_text (ei
, " (not present)");
3341 } else if (secs
== DMP_TIME_RESERVED
) {
3342 proto_item_append_text (tf
, "Reserved (0x%2.2x)", rec_time
);
3343 proto_item_append_text (ei
, " (Reserved)");
3345 proto_item_append_text (tf
, "%s (%s)", signed_time_secs_to_str(pinfo
->pool
, secs
),
3346 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, true));
3347 proto_item_append_text (ei
, " (%s from submission time)", signed_time_secs_to_str(pinfo
->pool
, secs
));
3351 if (dmp
.notif_type
== ON
) {
3353 on_typex
= tvb_get_uint8 (tvb
, offset
);
3354 proto_tree_add_item (notif_tree
, hf_notif_on_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3358 /* Supplementary Information */
3359 len
= tvb_strsize (tvb
, offset
);
3360 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_suppl_info_len
,
3361 tvb
, offset
, len
, len
,
3362 "Supplementary Information, Length: %d",
3365 if ((offset
- boffset
+ len
) > 128) {
3366 proto_item_append_text (tf
, " (incorrect, should be less than %d)",
3367 128 - (offset
- boffset
));
3369 field_tree
= proto_item_add_subtree (tf
, ett_notif_suppl_info
);
3370 proto_tree_add_item (field_tree
, hf_notif_suppl_info
, tvb
, offset
, len
, ENC_ASCII
);
3374 if ((dmp
.notif_type
== ON
) && (on_typex
< 0x03)) {
3375 /* ACP127 Recipient */
3376 len
= tvb_strsize (tvb
, offset
);
3377 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_acp127
,
3378 tvb
, offset
, len
, len
,
3379 "ACP127 Recipient, Length: %d",
3383 proto_item_append_text (tf
, " (incorrect, must be less than 64)");
3385 field_tree
= proto_item_add_subtree (tf
, ett_notif_acp127recip
);
3386 proto_tree_add_item (field_tree
, hf_notif_acp127recip
, tvb
, offset
, len
, ENC_ASCII
);
3390 } else if (dmp
.notif_type
== NRN
) {
3391 /* Non-Recipient Reason */
3392 notif
= tvb_get_uint8 (tvb
, offset
);
3393 proto_tree_add_uint_format (notif_tree
, hf_notif_non_rec_reason
,
3394 tvb
, offset
, 1, notif
,
3395 "Non-Receipt Reason%s: %s (%d)",
3396 (notif
< 0x10) ? " (P22)" : "",
3397 nrn_reason_str (notif
), notif
);
3400 /* Discard Reason */
3401 notif
= tvb_get_uint8 (tvb
, offset
);
3402 proto_tree_add_uint_format (notif_tree
, hf_notif_discard_reason
,
3403 tvb
, offset
, 1, notif
,
3404 "Discard Reason%s: %s (%d)",
3405 (notif
< 0x10) ? " (P22)" : "",
3406 discard_reason_str (notif
), notif
);
3410 proto_item_set_len (en
, offset
- boffset
);
3415 /* Ref chapter 6.2.1.2.8 SecurityCategories */
3416 static int dissect_dmp_security_category (tvbuff_t
*tvb
, packet_info
*pinfo
,
3418 const char **label_string
,
3419 int offset
, uint8_t *ext
)
3421 proto_tree
*field_tree
= NULL
;
3422 proto_item
*tf
= NULL
, *tr
= NULL
;
3423 char *sec_cat
= NULL
;
3425 bool country_code
= false;
3427 message
= tvb_get_uint8 (tvb
, offset
);
3428 tf
= proto_tree_add_uint_format (tree
, hf_message_sec_cat_nat
, tvb
,
3429 offset
, 1, message
, "Security Categories");
3430 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_cat
);
3434 case SEC_CAT_EXT_NONE
:
3435 proto_tree_add_item (field_tree
, hf_message_sec_cat_cl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3436 proto_tree_add_item (field_tree
, hf_message_sec_cat_cs
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3437 proto_tree_add_item (field_tree
, hf_message_sec_cat_ex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3438 proto_tree_add_item (field_tree
, hf_message_sec_cat_ne
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3440 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x08
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3441 if (message
& 0x08) {
3442 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3444 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x04
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3445 if (message
& 0x04) {
3446 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3449 if (message
& 0xF0) {
3450 sec_cat
= wmem_strdup_printf (pinfo
->pool
, "%s%s%s%s",
3451 (message
& 0x80) ? ",cl" : "",
3452 (message
& 0x40) ? ",cs" : "",
3453 (message
& 0x20) ? ",ex" : "",
3454 (message
& 0x10) ? ",ne" : "");
3455 proto_item_append_text (tf
, ": %s", &sec_cat
[1]);
3456 *label_string
= wmem_strconcat(pinfo
->pool
, *label_string
, sec_cat
, NULL
);
3460 case SEC_CAT_EXT_PERMISSIVE
:
3461 if ((message
>> 2) == 0x3F) {
3462 /* Fake entry because nat_pol_id defines 0x3F as reserved */
3463 proto_tree_add_uint_format (field_tree
, hf_message_sec_cat_permissive
, tvb
, offset
, 1,
3464 message
, "1111 11.. = Next byte has Country Code (0x3F)");
3465 country_code
= true;
3467 tr
= proto_tree_add_item (field_tree
, hf_message_sec_cat_permissive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3468 proto_item_append_text (tf
, ": rel-to-%s", get_nat_pol_id_short (message
>> 2));
3469 *label_string
= wmem_strdup_printf(pinfo
->pool
, "%s,rel-to-%s", *label_string
, get_nat_pol_id_short (message
>> 2));
3470 if ((message
>> 2) == 0) {
3471 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3476 case SEC_CAT_EXT_RESTRICTIVE
:
3477 proto_tree_add_item (field_tree
, hf_message_sec_cat_restrictive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3478 proto_item_append_text (tf
, " (restrictive: 0x%2.2x)", message
>> 2);
3485 proto_item_append_text (tf
, " (0x%2.2x)", message
);
3486 *ext
= 0; /* Reset extended bits */
3488 if (dmp
.version
== 1) {
3489 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x02
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3490 if (message
& 0x02) {
3491 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3493 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x01
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3494 if (message
& 0x01) {
3495 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3499 tr
= proto_tree_add_item (field_tree
, hf_message_sec_cat_extended
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3500 if ((message
& 0x01) && (message
& 0x02)) {
3501 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3502 } else if (message
& 0x01 || message
& 0x02) {
3503 proto_item_append_text (tf
, " (extended)");
3504 *ext
= message
& 0x03;
3509 proto_tree_add_item (field_tree
, hf_message_sec_cat_country_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3510 proto_item_append_text (tf
, " (rel-to country-code: %d)", tvb_get_uint8 (tvb
, offset
));
3511 proto_item_set_len (tf
, 2);
3520 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3521 * and chapter 6.3.8.1 IPM 88 message structure
3522 * and chapter 6.3.9.1 Report structure
3523 * and chapter 6.3.10.1 Notification structure
3525 static int dissect_dmp_content (tvbuff_t
*tvb
, packet_info
*pinfo
,
3526 proto_tree
*dmp_tree
, int offset
)
3528 proto_tree
*message_tree
= NULL
;
3529 proto_tree
*field_tree
= NULL
;
3530 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3531 proto_item
*hidden_item
;
3532 const char *label_string
= wmem_strdup (pinfo
->pool
, "");
3533 const char *class_name
= NULL
;
3534 uint8_t message
, dmp_sec_pol
, dmp_sec_class
, dmp_nation
= 0, exp_time
, dtg
;
3536 unsigned prev_rec_no
= 0;
3537 int rep_len
, rep_no
= 1;
3538 int loffset
, boffset
= offset
;
3540 if (dmp
.msg_type
== REPORT
) {
3541 en
= proto_tree_add_item (dmp_tree
, hf_report_content
, tvb
, offset
, 7, ENC_NA
);
3542 } else if (dmp
.msg_type
== NOTIF
) {
3543 en
= proto_tree_add_item (dmp_tree
, hf_notif_content
, tvb
, offset
, 7, ENC_NA
);
3545 en
= proto_tree_add_item (dmp_tree
, hf_message_content
, tvb
, offset
, 7, ENC_NA
);
3547 message_tree
= proto_item_add_subtree (en
, ett_content
);
3549 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3550 message
= tvb_get_uint8 (tvb
, offset
);
3551 dmp
.body_format
= (message
& 0x03);
3553 if (dmp
.msg_type
== STANAG
) {
3555 dmp
.st_type
= (message
& 0xC0) >> 6;
3556 tf
= proto_tree_add_uint_format (message_tree
, hf_message_st_type
,
3557 tvb
, offset
, 1, message
,
3558 "Message Type: %s (%d)",
3559 val_to_str_const (dmp
.st_type
,
3560 message_type_vals
, ""),
3562 field_tree
= proto_item_add_subtree (tf
, ett_message_st_type
);
3563 proto_tree_add_item (field_tree
, hf_message_st_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3565 if ((message
& 0x20) >> 5) {
3567 tf
= proto_tree_add_uint_format (message_tree
, hf_reserved_0x20
,
3568 tvb
, offset
, 1, message
,
3569 "Reserved: %d", (message
& 0x20)>>5);
3570 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3571 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x20
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3572 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3576 dmp
.prec
= (message
& 0x1C) >> 2;
3577 tf
= proto_tree_add_uint_format (message_tree
, hf_message_precedence
,
3578 tvb
, offset
, 1, message
,
3579 "Precedence: %s (%d)",
3580 val_to_str_const (dmp
.prec
, precedence
, ""),
3582 field_tree
= proto_item_add_subtree (tf
, ett_message_precedence
);
3583 proto_tree_add_item (field_tree
, hf_message_precedence
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3586 if ((message
& 0xE0) >> 5) {
3588 tf
= proto_tree_add_uint_format (message_tree
, hf_reserved_0xE0
,
3589 tvb
, offset
, 1, message
,
3590 "Reserved: %d", (message
& 0xE0)>>5);
3591 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3592 tf
= proto_tree_add_item (field_tree
, hf_reserved_0xE0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3593 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3597 dmp
.prec
= (message
& 0x1C) >> 2;
3598 tf
= proto_tree_add_uint_format (message_tree
, hf_message_importance
,
3599 tvb
, offset
, 1, message
,
3600 "Importance: %s (%d)",
3601 val_to_str_const (dmp
.prec
, importance
, ""),
3603 field_tree
= proto_item_add_subtree (tf
, ett_message_importance
);
3604 proto_tree_add_item (field_tree
, hf_message_importance
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3608 tf
= proto_tree_add_uint_format (message_tree
, hf_message_body_format
,
3609 tvb
, offset
, 1, message
,
3610 "Body Format: %s (%d)",
3611 val_to_str_const (message
& 0x03,
3612 body_format_vals
, ""),
3614 field_tree
= proto_item_add_subtree (tf
, ett_message_body_format
);
3615 proto_tree_add_item (field_tree
, hf_message_body_format
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3619 message
= tvb_get_uint8 (tvb
, offset
);
3620 /* Security Classification */
3621 dmp_sec_class
= (message
& 0xE0) >> 5;
3622 dmp_sec_pol
= (message
& 0x1C) >> 2;
3623 if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3624 dmp_nation
= tvb_get_uint8 (tvb
, offset
+ 1);
3627 loffset
= offset
; /* Offset to start of security label */
3628 if (dmp_sec_pol
== NATIONAL
&& dmp_local_nation
!= 0) {
3629 class_name
= dmp_national_sec_class (dmp_local_nation
, dmp_sec_class
);
3630 } else if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3631 class_name
= dmp_national_sec_class (dmp_nation
, dmp_sec_class
);
3633 if ((dmp_sec_pol
== NATO
|| dmp_sec_pol
== NATIONAL
) && !class_name
) {
3634 class_name
= val_to_str_const (dmp_sec_class
, sec_class
, "");
3636 if (class_name
&& class_name
[0]) {
3637 tf
= proto_tree_add_uint_format (message_tree
, hf_message_sec_class_val
,
3638 tvb
, offset
, 1, message
,
3639 "Security Classification: %s (%d)",
3640 class_name
, dmp_sec_class
);
3642 tf
= proto_tree_add_uint_format (message_tree
, hf_message_sec_class_val
,
3643 tvb
, offset
, 1, message
,
3644 "Security Classification: %d",
3647 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_class
);
3648 tf
= proto_tree_add_item (field_tree
, hf_message_sec_class_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3650 proto_item_append_text (tf
, " (%s)", class_name
);
3651 label_string
= wmem_strconcat(pinfo
->pool
, label_string
, class_name
, NULL
);
3654 /* Security Policy */
3655 tf
= proto_tree_add_uint_format (message_tree
, hf_message_sec_pol
,
3656 tvb
, offset
, 1, message
,
3657 "Security Policy: %s (%d)",
3658 val_to_str (dmp_sec_pol
, sec_pol
, "%d"),
3660 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_pol
);
3661 proto_tree_add_item (field_tree
, hf_message_sec_pol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3663 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3665 tf
= proto_tree_add_item (message_tree
, hf_message_heading_flags
, tvb
, offset
, 1, ENC_NA
);
3666 field_tree
= proto_item_add_subtree (tf
, ett_message_heading_flags
);
3667 proto_tree_add_item (field_tree
, hf_message_auth_users
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3668 proto_tree_add_item (field_tree
, hf_message_subject_disc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3669 if (message
& 0x03) {
3670 proto_item_append_text (tf
, ": %s%s%s discarded",
3671 (message
& 0x02) ? "Authorizing users" : "",
3672 (message
& 0x03) == 0x03 ? " and " : "",
3673 (message
& 0x01) ? "Subject" : "");
3675 proto_item_append_text (tf
, " (none)");
3677 } else if (dmp
.msg_type
== NOTIF
) {
3678 /* Notification Type */
3679 dmp
.notif_type
= (message
& 0x03);
3680 tf
= proto_tree_add_uint_format (message_tree
, hf_notif_type
,
3681 tvb
, offset
, 1, message
,
3682 "Notification Type: %s",
3683 val_to_str_const (dmp
.notif_type
, notif_type
,
3685 field_tree
= proto_item_add_subtree (tf
, ett_notif_type
);
3686 proto_tree_add_item (field_tree
, hf_notif_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3687 } else if (message
& 0x02) {
3689 tf
= proto_tree_add_uint_format (message_tree
, hf_reserved_0x02
,
3690 tvb
, offset
, 1, message
,
3691 "Reserved: %d", message
& 0x02);
3692 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3693 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x02
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3694 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3698 if (dmp_sec_pol
== NATIONAL
&& dmp_local_nation
!= 0) {
3699 /* Show configured national policy */
3700 tf
= proto_tree_add_uint (message_tree
, hf_message_national_policy_id
,
3701 tvb
, offset
, 0, dmp_local_nation
);
3702 proto_item_set_generated (tf
);
3703 } else if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3704 /* National Policy Identifier */
3705 proto_tree_add_item (message_tree
, hf_message_national_policy_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3707 } else if (dmp_sec_pol
== EXTENDED_MISSION
) {
3708 /* Mission Policy Identifier */
3709 message
= tvb_get_uint8 (tvb
, offset
);
3710 if (message
== 0xFF) {
3711 proto_tree_add_uint_format_value (message_tree
, hf_message_mission_policy_id
,
3712 tvb
, offset
, 1, message
,
3715 proto_tree_add_item (message_tree
, hf_message_mission_policy_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3720 /* Security Categories */
3721 if (dmp_sec_pol
== NATO
|| dmp_sec_pol
== NATIONAL
|| dmp_sec_pol
== EXTENDED_NATIONAL
) {
3723 unsigned sec_cat_count
= 0;
3725 offset
= dissect_dmp_security_category (tvb
, pinfo
, message_tree
, &label_string
, offset
, &ext
);
3727 } while (ext
!= 0 && sec_cat_count
< UINT8_MAX
);
3728 if (sec_cat_count
== UINT8_MAX
) {
3729 /* This is a arbitrary limit to avoid a long dissector loop. */
3730 expert_add_info(pinfo
, en
, &ei_too_many_sec_cat
);
3732 proto_item_append_text (en
, ", Security Label: %s", label_string
);
3733 tf
= proto_tree_add_string (message_tree
, hf_message_sec_label
, tvb
, loffset
,
3734 offset
- loffset
, label_string
);
3735 proto_item_set_generated (tf
);
3737 tf
= proto_tree_add_item (message_tree
, hf_message_sec_cat_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3738 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_cat
);
3740 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit7
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3741 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit6
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3742 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3743 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit4
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3744 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3745 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3746 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3747 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3751 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3753 exp_time
= tvb_get_uint8 (tvb
, offset
);
3754 tf
= proto_tree_add_uint_format (message_tree
, hf_message_exp_time
,
3755 tvb
, offset
, 1, exp_time
,
3757 field_tree
= proto_item_add_subtree (tf
, ett_message_exp_time
);
3758 ei
= proto_tree_add_item (field_tree
, hf_message_exp_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3759 secs
= dmp_dec_exp_time (exp_time
);
3760 if (secs
== DMP_TIME_NOT_PRESENT
) {
3761 proto_item_append_text (tf
, "Not present");
3762 proto_item_append_text (ei
, " (not present)");
3763 } else if (secs
== DMP_TIME_RESERVED
) {
3764 proto_item_append_text (tf
, "Reserved (0x%2.2x)", exp_time
);
3765 proto_item_append_text (ei
, " (Reserved)");
3767 proto_item_append_text (tf
, "%s (%s)", signed_time_secs_to_str(pinfo
->pool
, secs
),
3768 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
+ secs
, ABSOLUTE_TIME_LOCAL
, true));
3769 proto_item_append_text (ei
, " (%s from submission time)", signed_time_secs_to_str(pinfo
->pool
, secs
));
3774 if (dmp
.msg_type
== STANAG
) {
3775 dtg
= tvb_get_uint8 (tvb
, offset
);
3776 tf
= proto_tree_add_uint_format (message_tree
, hf_message_dtg
, tvb
, offset
, 1, dtg
, "DTG: ");
3777 field_tree
= proto_item_add_subtree (tf
, ett_message_dtg
);
3778 proto_tree_add_item (field_tree
, hf_message_dtg_sign
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3779 proto_tree_add_item (field_tree
, hf_message_dtg_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3780 secs
= dmp_dec_dtg (dtg
& 0x7F);
3781 if (secs
== DMP_TIME_NOT_PRESENT
) {
3782 proto_item_append_text (tf
, "Not present");
3783 } else if (secs
== DMP_TIME_RESERVED
) {
3784 proto_item_append_text (tf
, "Reserved (0x%2.2x)", dtg
& 0x7F);
3785 } else if (secs
== 0) {
3786 proto_item_append_text (tf
, "0 minutes in the %s (%s)",
3787 tfs_get_string(dtg
& 0x80, &dtg_sign
),
3788 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
, ABSOLUTE_TIME_LOCAL
, true));
3790 proto_item_append_text (tf
, "%s in the %s (%s)", signed_time_secs_to_str(pinfo
->pool
, secs
),
3791 tfs_get_string(dtg
& 0x80, &dtg_sign
), (dtg
& 0x80) ?
3792 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
+ secs
, ABSOLUTE_TIME_LOCAL
, true) :
3793 abs_time_secs_to_str (pinfo
->pool
, dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, true));
3798 if (dmp
.msg_type
== STANAG
) {
3800 offset
= dissect_dmp_sic (tvb
, pinfo
, message_tree
, offset
);
3801 } else if (dmp
.msg_type
== REPORT
|| dmp
.msg_type
== NOTIF
) {
3802 if (dmp
.version
== DMP_VERSION_1
|| dmp
.msg_id_type
== ONLY_DMP_ID
) {
3803 /* Subject Message Identifier */
3804 dmp
.subj_id
= tvb_get_ntohs (tvb
, offset
);
3805 proto_tree_add_item (message_tree
, hf_message_subj_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3806 hidden_item
= proto_tree_add_item (message_tree
, hf_dmp_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3807 proto_item_set_hidden (hidden_item
);
3809 } else if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) {
3810 if (dmp
.msg_type
== REPORT
) {
3811 /* Subject MTS Identifier */
3812 offset
= dissect_mts_identifier (tvb
, pinfo
, message_tree
, offset
, true);
3814 /* Subject IPM Identifier */
3815 offset
= dissect_ipm_identifier (tvb
, pinfo
, message_tree
, offset
, true);
3818 tf
= proto_tree_add_uint (message_tree
, hf_message_subj_id
, tvb
, offset
, 0, dmp
.subj_id
);
3819 proto_item_set_generated (tf
);
3820 hidden_item
= proto_tree_add_uint (message_tree
, hf_dmp_id
, tvb
, offset
, 0, dmp
.subj_id
);
3821 proto_item_set_generated (hidden_item
);
3822 proto_item_set_hidden (hidden_item
);
3827 if (use_seq_ack_analysis
) {
3828 register_dmp_id (pinfo
, 0);
3831 proto_item_set_len (en
, offset
- boffset
);
3833 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3835 offset
= dissect_dmp_message (tvb
, pinfo
, dmp_tree
, offset
);
3836 } else if (dmp
.msg_type
== REPORT
) {
3837 /* One or more Delivery Report or Non-Delivery Report Data */
3838 rep_len
= tvb_reported_length (tvb
);
3842 while (offset
< rep_len
) {
3843 offset
= dissect_dmp_report (tvb
, pinfo
, dmp_tree
, offset
, &prev_rec_no
, rep_no
++);
3845 } else if (dmp
.msg_type
== NOTIF
) {
3846 /* Notification Data */
3847 offset
= dissect_dmp_notification (tvb
, pinfo
, dmp_tree
, offset
);
3853 static int dissect_dmp_extensions (tvbuff_t
*tvb
, packet_info
*pinfo _U_
,
3854 proto_tree
*dmp_tree
, int offset
)
3856 proto_tree
*exts_tree
, *ext_tree
, *hdr_tree
;
3857 proto_item
*exts_item
, *en
;
3858 uint8_t ext_hdr
, ext_length
;
3859 bool more_extensions
= true;
3860 int num_ext
= 0, boffset
= offset
;
3862 exts_item
= proto_tree_add_item (dmp_tree
, hf_extensions
, tvb
, offset
, -1, ENC_NA
);
3863 exts_tree
= proto_item_add_subtree (exts_item
, ett_extensions
);
3865 while (more_extensions
) {
3866 /* Extensions Present */
3867 ext_hdr
= tvb_get_uint8 (tvb
, offset
);
3868 more_extensions
= (ext_hdr
& 0x80);
3869 ext_length
= (ext_hdr
& 0x7F) + 1;
3871 en
= proto_tree_add_none_format (exts_tree
, hf_extension
, tvb
, offset
, ext_length
+ 1,
3872 "Extension (#%d)", num_ext
+ 1);
3873 ext_tree
= proto_item_add_subtree (en
, ett_extension
);
3875 en
= proto_tree_add_none_format (ext_tree
, hf_extension_header
, tvb
, offset
, 1,
3876 "Extension Length: %u, More %s", ext_length
,
3877 (ext_hdr
& 0x80) ? "Present" : "Not present");
3878 hdr_tree
= proto_item_add_subtree (en
, ett_extension_header
);
3879 proto_tree_add_item (hdr_tree
, hf_extension_more
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3880 proto_tree_add_item (hdr_tree
, hf_extension_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3883 proto_tree_add_item (ext_tree
, hf_extension_data
, tvb
, offset
, ext_length
, ENC_NA
);
3884 offset
+= ext_length
;
3888 proto_item_append_text (exts_item
, " (%d item%s)", num_ext
, plurality (num_ext
, "", "s"));
3889 proto_item_set_len (exts_item
, offset
- boffset
);
3894 static int dissect_dmp (tvbuff_t
*tvb
, packet_info
*pinfo
,
3895 proto_tree
*tree
, void *data _U_
)
3897 proto_tree
*dmp_tree
;
3899 uint16_t checksum1
= 0, checksum2
= 1;
3900 int length
, offset
= 0;
3901 bool retrans_or_dup_ack
= false;
3903 col_set_str (pinfo
->cinfo
, COL_PROTOCOL
, "DMP");
3904 col_clear (pinfo
->cinfo
, COL_INFO
);
3906 /* Initialize global data structure */
3907 memset (&dmp
, 0, sizeof (dmp
));
3909 ti
= proto_tree_add_item (tree
, proto_dmp
, tvb
, offset
, -1, ENC_NA
);
3910 dmp_tree
= proto_item_add_subtree (ti
, ett_dmp
);
3912 offset
= dissect_dmp_envelope (tvb
, pinfo
, dmp_tree
, offset
);
3914 if (dmp
.version
> DMP_VERSION_2
) {
3915 /* Unsupported DMP Version, no point to continue */
3916 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "Unsupported Version: %d", dmp
.version
);
3920 if (dmp
.extensions
) {
3921 offset
= dissect_dmp_extensions (tvb
, pinfo
, dmp_tree
, offset
);
3924 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3925 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
))
3927 offset
= dissect_dmp_content (tvb
, pinfo
, dmp_tree
, offset
);
3928 } else if (dmp
.msg_type
== ACK
) {
3929 offset
= dissect_dmp_ack (tvb
, pinfo
, dmp_tree
, offset
);
3933 length
= tvb_captured_length (tvb
);
3934 checksum1
= crc16_x25_ccitt_tvb (tvb
, length
- 2);
3935 checksum2
= tvb_get_ntohs (tvb
, offset
);
3937 proto_tree_add_checksum(dmp_tree
, tvb
, offset
, hf_checksum
, hf_checksum_status
, &ei_checksum_bad
, pinfo
, checksum1
, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
3941 if (use_seq_ack_analysis
) {
3942 dmp_add_seq_ack_analysis (tvb
, pinfo
, dmp_tree
, offset
);
3945 if (((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3946 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
)) &&
3947 dmp
.id_val
&& dmp
.id_val
->msg_resend_count
)
3949 unsigned retrans_num
;
3950 if (dmp
.msg_type
== REPORT
) {
3951 retrans_num
= dmp
.id_val
->rep_id
;
3952 } else if (dmp
.msg_type
== NOTIF
) {
3953 retrans_num
= dmp
.id_val
->not_id
;
3955 retrans_num
= dmp
.id_val
->msg_id
;
3957 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "[Retrans %d#%d] ",
3958 retrans_num
, dmp
.id_val
->msg_resend_count
);
3959 retrans_or_dup_ack
= true;
3960 } else if (dmp
.msg_type
== ACK
&& dmp
.id_val
&& dmp
.id_val
->ack_resend_count
) {
3961 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "[Dup ACK %d#%d] ",
3962 dmp
.id_val
->ack_id
, dmp
.id_val
->ack_resend_count
);
3963 retrans_or_dup_ack
= true;
3965 if (dmp_align
&& !retrans_or_dup_ack
) {
3966 if (dmp
.msg_type
== ACK
) {
3967 /* ACK does not have "Msg Id" */
3968 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "%-45.45s", msg_type_to_str ());
3970 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "%-31.31s", msg_type_to_str ());
3973 col_append_str (pinfo
->cinfo
, COL_INFO
, msg_type_to_str ());
3975 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3976 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
))
3978 if (dmp_align
&& !retrans_or_dup_ack
) {
3979 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Msg Id: %5d", dmp
.msg_id
);
3981 col_append_fstr (pinfo
->cinfo
, COL_INFO
, ", Msg Id: %d", dmp
.msg_id
);
3984 if ((dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
) ||
3985 (dmp
.msg_type
== ACK
))
3987 if (dmp_align
&& !retrans_or_dup_ack
) {
3988 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Subj Id: %5d",
3991 col_append_fstr (pinfo
->cinfo
, COL_INFO
, ", Subj Id: %d",
3995 if (dmp
.checksum
&& (checksum1
!= checksum2
)) {
3996 col_append_str (pinfo
->cinfo
, COL_INFO
, ", Checksum incorrect");
3999 proto_item_append_text (ti
, ", Version: %d%s, %s", dmp
.version
,
4000 (dmp
.prot_id
== PROT_NAT
? " (national)" : ""),
4006 void proto_register_dmp (void)
4008 static hf_register_info hf
[] = {
4013 { "DMP Identifier", "dmp.id", FT_UINT16
, BASE_DEC
,
4014 NULL
, 0x0, NULL
, HFILL
} },
4016 /* MTS Identifier */
4018 { "MTS Identifier", "dmp.mts", FT_STRING
, BASE_NONE
,
4019 NULL
, 0x0, NULL
, HFILL
} },
4021 /* IPM Identifier */
4023 { "IPM Identifier", "dmp.ipm", FT_STRING
, BASE_NONE
,
4024 NULL
, 0x0, NULL
, HFILL
} },
4030 { "Envelope", "dmp.envelope", FT_NONE
, BASE_NONE
,
4031 NULL
, 0x0, NULL
, HFILL
} },
4034 { &hf_envelope_protocol_id
,
4035 { "Protocol Identifier", "dmp.protocol_id", FT_UINT8
,
4036 BASE_HEX
, NULL
, 0xF8, NULL
, HFILL
} },
4037 { &hf_envelope_version
,
4038 { "Protocol Version", "dmp.version", FT_UINT8
, BASE_DEC
,
4039 VALS(version_vals
), 0x07, NULL
, HFILL
} },
4040 { &hf_envelope_version_value
,
4041 { "Protocol Version", "dmp.version_value", FT_UINT8
, BASE_DEC
,
4042 VALS(version_vals
), 0x07, NULL
, HFILL
} },
4044 /* Envelope elements (byte 1) */
4045 { &hf_envelope_hop_count
,
4046 { "Hop Count", "dmp.hop_count", FT_UINT8
, BASE_DEC
,
4047 NULL
, 0xE0, NULL
, HFILL
} },
4048 { &hf_envelope_hop_count_value
,
4049 { "Hop Count", "dmp.hop_count_value", FT_UINT8
, BASE_DEC
,
4050 NULL
, 0xE0, NULL
, HFILL
} },
4051 { &hf_envelope_rec_present
,
4052 { "Recipient Present", "dmp.rec_present", FT_BOOLEAN
, 8,
4053 TFS (&tfs_present_absent
), 0x20, NULL
, HFILL
} },
4054 { &hf_envelope_addr_enc
,
4055 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4056 TFS (&addr_enc
), 0x10, NULL
, HFILL
} },
4057 { &hf_envelope_checksum
,
4058 { "Checksum", "dmp.checksum_used", FT_BOOLEAN
, 8,
4059 TFS (&tfs_used_notused
), 0x08, "Checksum Used", HFILL
} },
4060 { &hf_envelope_type
,
4061 { "Content Type", "dmp.content_type", FT_UINT8
, BASE_DEC
,
4062 VALS(type_vals
), 0x07, NULL
, HFILL
} },
4064 /* Envelope elements (byte 2) */
4065 { &hf_envelope_extensions
,
4066 { "Extensions", "dmp.extensions_used", FT_BOOLEAN
, 8,
4067 TFS (&tfs_present_absent
), 0x80, "Extensions Used", HFILL
} },
4068 { &hf_envelope_msg_id_type
,
4069 { "Message Identifier Type", "dmp.msg_id_type", FT_UINT8
, BASE_DEC
,
4070 VALS(msg_id_type_vals
), 0x60, NULL
, HFILL
} },
4071 { &hf_envelope_msg_id_length
,
4072 { "Message Identifier Length", "dmp.msg_id_short", FT_UINT8
, BASE_DEC
,
4073 VALS(msg_id_length_vals
), 0x10, NULL
, HFILL
} },
4074 { &hf_envelope_mts_id_length
,
4075 { "MTS Identifier Length", "dmp.mts_id_length", FT_UINT8
, BASE_DEC
,
4076 NULL
, 0x1F, NULL
, HFILL
} },
4077 { &hf_envelope_ipm_id_modifier
,
4078 { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8
, BASE_DEC
,
4079 VALS(ipm_id_modifier
), 0xC0, NULL
, HFILL
} },
4080 { &hf_envelope_ipm_id_length
,
4081 { "IPM Identifier Length", "dmp.ipm_id_length", FT_UINT8
, BASE_DEC
,
4082 NULL
, 0x3F, NULL
, HFILL
} },
4084 { &hf_thales_ipm_id_modifier
,
4085 { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8
, BASE_DEC
,
4086 VALS(thales_ipm_id_modifier
), 0xC0, "Thales XOmail IPM Identifier Modifier", HFILL
} },
4088 /* Message identifier */
4089 { &hf_envelope_msg_id
,
4090 { "Message Identifier", "dmp.msg_id", FT_UINT16
, BASE_DEC
,
4091 NULL
, 0x0, NULL
, HFILL
} },
4092 { &hf_envelope_msg_id_12bit
,
4093 { "Message Identifier", "dmp.msg_id", FT_UINT16
, BASE_DEC
,
4094 NULL
, 0x0FFF, NULL
, HFILL
} },
4096 /* MTS Identifier */
4097 { &hf_envelope_mts_id
,
4098 { "MTS Identifier", "dmp.mts_id", FT_STRING
, BASE_NONE
,
4099 NULL
, 0x0, NULL
, HFILL
} },
4101 /* IPM Identifier */
4102 { &hf_envelope_ipm_id
,
4103 { "IPM Identifier", "dmp.ipm_id", FT_STRING
, BASE_NONE
,
4104 NULL
, 0x0, NULL
, HFILL
} },
4108 { "Extensions", "dmp.extensions", FT_NONE
, BASE_NONE
,
4109 NULL
, 0x0, NULL
, HFILL
} },
4111 { "Extension", "dmp.extension", FT_NONE
, BASE_NONE
,
4112 NULL
, 0x0, NULL
, HFILL
} },
4113 { &hf_extension_header
,
4114 { "Extension Header", "dmp.extension_header", FT_NONE
, BASE_NONE
,
4115 NULL
, 0x0, NULL
, HFILL
} },
4116 { &hf_extension_more
,
4117 { "More Extensions", "dmp.extension_more", FT_BOOLEAN
, 8,
4118 TFS (&tfs_present_absent
), 0x80, NULL
, HFILL
} },
4119 { &hf_extension_length
,
4120 { "Extension Length (minus one)", "dmp.extension_length", FT_UINT8
, BASE_DEC
,
4121 NULL
, 0x7F, "Extension Length minus one", HFILL
} },
4122 { &hf_extension_data
,
4123 { "Extension Data", "dmp.extension_data", FT_BYTES
, BASE_NONE
,
4124 NULL
, 0x0, NULL
, HFILL
} },
4126 /* Submission time */
4127 { &hf_envelope_subm_time
,
4128 { "Submission Time", "dmp.subm_time", FT_UINT16
, BASE_HEX
,
4129 NULL
, 0x0, NULL
, HFILL
} },
4130 { &hf_envelope_time_diff_present
,
4131 { "Time Diff", "dmp.time_diff_present", FT_BOOLEAN
, 16,
4132 TFS (&tfs_present_absent
), 0x8000, "Time Diff Present", HFILL
} },
4133 { &hf_envelope_subm_time_value
,
4134 { "Submission Time Value", "dmp.subm_time_value", FT_UINT16
,
4135 BASE_HEX
, NULL
, 0x7FFF, NULL
, HFILL
} },
4136 { &hf_envelope_time_diff
,
4137 { "Time Difference", "dmp.time_diff", FT_UINT8
, BASE_HEX
,
4138 NULL
, 0x0, NULL
, HFILL
} },
4139 { &hf_envelope_time_diff_value
,
4140 { "Time Difference Value", "dmp.time_diff_value", FT_UINT8
,
4141 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
4143 /* Envelope flags */
4144 { &hf_envelope_flags
,
4145 { "Flags", "dmp.envelope_flags", FT_UINT8
, BASE_DEC
,
4146 NULL
, 0x0, "Envelope Flags", HFILL
} },
4147 { &hf_envelope_content_id_discarded
,
4148 { "Content Identifier discarded", "dmp.cont_id_discarded",
4149 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
4151 { &hf_envelope_recip_reassign_prohib
,
4152 { "Recipient reassign prohibited","dmp.recip_reassign_prohib",
4153 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
4155 { &hf_envelope_dl_expansion_prohib
,
4156 { "DL expansion prohibited", "dmp.dl_expansion_prohib",
4157 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20, NULL
,
4160 /* Recipient Count */
4161 { &hf_envelope_recipients
,
4162 { "Recipient Count", "dmp.rec_count", FT_UINT8
, BASE_DEC
,
4163 NULL
, 0x1F, NULL
, HFILL
} },
4164 { &hf_envelope_ext_recipients
,
4165 { "Extended Recipient Count", "dmp.ext_rec_count", FT_UINT16
,
4166 BASE_DEC
, NULL
, 0x7FFF, NULL
, HFILL
} },
4171 { &hf_addr_recipient
,
4172 { "Recipient Number", "dmp.recipient", FT_NONE
, BASE_NONE
,
4173 NULL
, 0x0, NULL
, HFILL
} },
4174 { &hf_addr_originator
,
4175 { "Originator", "dmp.originator", FT_NONE
, BASE_NONE
,
4176 NULL
, 0x0, NULL
, HFILL
} },
4177 { &hf_addr_reporting_name
,
4178 { "Reporting Name Number", "dmp.reporting_name", FT_NONE
,
4179 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4180 { &hf_addr_dl_expanded
,
4181 { "DL Expanded", "dmp.dl_expanded", FT_BOOLEAN
, BASE_NONE
,
4182 NULL
, 0x0, "Message has been DL expanded", HFILL
} },
4184 { "Intended Recipient", "dmp.int_rec", FT_BOOLEAN
, BASE_NONE
,
4185 NULL
, 0x0, "Message has an intended recipient", HFILL
} },
4190 { &hf_addr_dir_addr_ext
,
4191 { "Address Extended", "dmp.addr_ext", FT_BOOLEAN
, 8,
4192 NULL
, 0x80, NULL
, HFILL
} },
4193 { &hf_addr_dir_rec_no
,
4194 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8
,
4195 BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
} },
4196 { &hf_addr_dir_rec_no_generated
,
4197 { "Recipient Number", "dmp.rec_no", FT_UINT32
,
4198 BASE_DEC
, NULL
, 0x0, "Recipient Number Offset", HFILL
} },
4199 { &hf_addr_dir_rec_no1
,
4200 { "Recipient Number (bits 3-0)", "dmp.rec_no_offset1", FT_UINT8
,
4201 BASE_DEC
, NULL
, 0xF0, "Recipient Number (bits 3-0) Offset", HFILL
} },
4202 { &hf_addr_dir_rec_no2
,
4203 { "Recipient Number (bits 9-4)", "dmp.rec_no_offset2", FT_UINT8
,
4204 BASE_DEC
, NULL
, 0x3F, "Recipient Number (bits 9-4) Offset", HFILL
} },
4205 { &hf_addr_dir_rec_no3
,
4206 { "Recipient Number (bits 14-10)", "dmp.rec_no_offset3", FT_UINT8
,
4207 BASE_DEC
, NULL
, 0x1F, "Recipient Number (bits 14-10) Offset",HFILL
} },
4208 { &hf_addr_dir_rep_req1
,
4209 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4210 VALS (report_vals_ext
), 0x0C, NULL
, HFILL
} },
4211 { &hf_addr_dir_rep_req2
,
4212 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4213 VALS (report_vals_ext
), 0xC0, NULL
, HFILL
} },
4214 { &hf_addr_dir_rep_req3
,
4215 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4216 VALS (report_vals
), 0xC0, NULL
, HFILL
} },
4217 { &hf_addr_dir_not_req1
,
4218 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4219 VALS (notif_vals_ext
), 0x03, NULL
, HFILL
} },
4220 { &hf_addr_dir_not_req2
,
4221 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4222 VALS (notif_vals_ext
), 0xC0, NULL
, HFILL
} },
4223 { &hf_addr_dir_not_req3
,
4224 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4225 VALS (notif_vals
), 0xC0, NULL
, HFILL
} },
4226 { &hf_addr_dir_action
,
4227 { "Action", "dmp.action", FT_BOOLEAN
, 8,
4228 TFS (&tfs_yes_no
), 0x80, NULL
, HFILL
} },
4229 { &hf_addr_dir_address
,
4230 { "Direct Address", "dmp.direct_addr", FT_UINT8
,
4231 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4232 { &hf_addr_dir_address_generated
,
4233 { "Direct Address", "dmp.direct_addr", FT_UINT32
,
4234 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4235 { &hf_addr_dir_address1
,
4236 { "Direct Address (bits 6-0)", "dmp.direct_addr1", FT_UINT8
,
4237 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4238 { &hf_addr_dir_address2
,
4239 { "Direct Address (bits 12-7)", "dmp.direct_addr2", FT_UINT8
,
4240 BASE_DEC
, NULL
, 0x3F, NULL
, HFILL
} },
4241 { &hf_addr_dir_address3
,
4242 { "Direct Address (bits 18-13)", "dmp.direct_addr3", FT_UINT8
,
4243 BASE_DEC
, NULL
, 0x3F, NULL
, HFILL
} },
4248 { &hf_addr_ext_form
,
4249 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4250 VALS (addr_form
), 0xE0, NULL
, HFILL
} },
4251 { &hf_addr_ext_form_orig_v1
,
4252 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4253 VALS (addr_form_orig_v1
), 0xE0, NULL
, HFILL
} },
4254 { &hf_addr_ext_form_orig
,
4255 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4256 VALS (addr_form_orig
), 0xE0, NULL
, HFILL
} },
4257 { &hf_addr_ext_action
,
4258 { "Action", "dmp.action", FT_BOOLEAN
, 8,
4259 TFS (&tfs_yes_no
), 0x10, NULL
, HFILL
} },
4260 { &hf_addr_ext_rep_req
,
4261 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4262 VALS (report_vals
), 0x0C, NULL
, HFILL
} },
4263 { &hf_addr_ext_not_req
,
4264 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4265 VALS (notif_vals
), 0x03, NULL
, HFILL
} },
4266 { &hf_addr_ext_rec_ext
,
4267 { "Recipient Number Extended", "dmp.rec_no_ext", FT_BOOLEAN
, 8,
4268 NULL
, 0x80, NULL
, HFILL
} },
4269 { &hf_addr_ext_rec_no
,
4270 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8
,
4271 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4272 { &hf_addr_ext_rec_no_generated
,
4273 { "Recipient Number", "dmp.rec_no", FT_UINT32
,
4274 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4275 { &hf_addr_ext_rec_no1
,
4276 { "Recipient Number (bits 6-0)", "dmp.rec_no_offset1", FT_UINT8
,
4277 BASE_DEC
, NULL
, 0x7F, "Recipient Number (bits 6-0) Offset", HFILL
} },
4278 { &hf_addr_ext_rec_no2
,
4279 { "Recipient Number (bits 14-7)", "dmp.rec_no_offset2", FT_UINT8
,
4280 BASE_DEC
, NULL
, 0x0, "Recipient Number (bits 14-7) Offset", HFILL
} },
4281 { &hf_addr_ext_address
,
4282 { "Extended Address", "dmp.addr_form_ext", FT_NONE
, BASE_NONE
,
4283 NULL
, 0x0, NULL
, HFILL
} },
4284 { &hf_addr_ext_type
,
4285 { "Address Type", "dmp.addr_type", FT_UINT8
, BASE_DEC
,
4286 VALS (ext_addr_type
), 0xE0, NULL
, HFILL
} },
4287 { &hf_addr_ext_type_ext
,
4288 { "Address Type Extended", "dmp.addr_type_ext", FT_UINT8
,
4289 BASE_DEC
, VALS (ext_addr_type_ext
), 0xE0, NULL
,
4291 { &hf_addr_ext_length
,
4292 { "Address Length", "dmp.addr_length", FT_UINT8
,
4293 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4294 { &hf_addr_ext_length_generated
,
4295 { "Address Length", "dmp.addr_length", FT_UINT32
,
4296 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4297 { &hf_addr_ext_length1
,
4298 { "Address Length (bits 4-0)", "dmp.addr_length1", FT_UINT8
,
4299 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4300 { &hf_addr_ext_length2
,
4301 { "Address Length (bits 9-5)", "dmp.addr_length2", FT_UINT8
,
4302 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4303 { &hf_addr_ext_asn1_ber
,
4304 { "ASN.1 BER-encoded OR-name", "dmp.or_name", FT_NONE
,
4305 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4306 { &hf_addr_ext_asn1_per
,
4307 { "ASN.1 PER-encoded OR-name", "dmp.asn1_per", FT_BYTES
,
4308 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4309 { &hf_addr_ext_unknown
,
4310 { "Unknown encoded address", "dmp.addr_unknown", FT_BYTES
,
4311 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4316 { &hf_message_content
,
4317 { "Message Content", "dmp.message", FT_NONE
, BASE_NONE
,
4318 NULL
, 0x0, NULL
, HFILL
} },
4319 { &hf_report_content
,
4320 { "Report Content", "dmp.report", FT_NONE
, BASE_NONE
,
4321 NULL
, 0x0, NULL
, HFILL
} },
4322 { &hf_notif_content
,
4323 { "Notification Content", "dmp.notification", FT_NONE
, BASE_NONE
,
4324 NULL
, 0x0, NULL
, HFILL
} },
4326 { &hf_message_st_type
,
4327 { "Message type", "dmp.msg_type", FT_UINT8
, BASE_DEC
,
4328 VALS (message_type_vals
), 0xC0, NULL
, HFILL
} },
4329 { &hf_message_precedence
,
4330 { "Precedence", "dmp.precedence", FT_UINT8
, BASE_DEC
,
4331 VALS (precedence
), 0x1C, NULL
, HFILL
} },
4332 { &hf_message_importance
,
4333 { "Importance", "dmp.importance", FT_UINT8
, BASE_DEC
,
4334 VALS (importance
), 0x1C, NULL
, HFILL
} },
4335 { &hf_message_body_format
,
4336 { "Body format", "dmp.body_format", FT_UINT8
, BASE_DEC
,
4337 VALS (body_format_vals
), 0x03, NULL
, HFILL
} },
4339 /* Security Values */
4340 { &hf_message_sec_label
,
4341 { "Security Label", "dmp.sec_label", FT_STRING
, BASE_NONE
,
4342 NULL
, 0x0, NULL
, HFILL
} },
4343 { &hf_message_sec_class_val
,
4344 { "Security Classification", "dmp.sec_class", FT_UINT8
,
4345 BASE_DEC
, NULL
, 0xE0, NULL
, HFILL
} },
4346 { &hf_message_sec_pol
,
4347 { "Security Policy", "dmp.sec_pol", FT_UINT8
, BASE_DEC
,
4348 VALS (sec_pol
), 0x1C, NULL
, HFILL
} },
4349 { &hf_message_heading_flags
,
4350 { "Heading Flags", "dmp.heading_flags", FT_NONE
, BASE_NONE
,
4351 NULL
, 0x0, NULL
, HFILL
} },
4352 { &hf_message_auth_users
,
4353 { "Authorizing users discarded", "dmp.auth_discarded",
4354 FT_BOOLEAN
, 8, TFS (&tfs_yes_no
), 0x02,
4356 { &hf_message_subject_disc
,
4357 { "Subject discarded", "dmp.subject_discarded", FT_BOOLEAN
, 8,
4358 TFS (&tfs_yes_no
), 0x01, NULL
, HFILL
} },
4360 /* National Policy Identifier */
4361 { &hf_message_national_policy_id
,
4362 { "National Policy Identifier", "dmp.nat_pol_id", FT_UINT8
,
4363 BASE_DEC
, VALS(nat_pol_id
), 0x0, NULL
,
4366 /* Mission Policy Identifier */
4367 { &hf_message_mission_policy_id
,
4368 { "Mission Policy Identifier", "dmp.mission_pol_id", FT_UINT8
,
4369 BASE_DEC
, NULL
, 0x0, NULL
,
4372 /* Security Categories */
4373 { &hf_message_sec_cat_nat
,
4374 { "Security Categories", "dmp.sec_cat", FT_UINT8
, BASE_HEX
,
4375 NULL
, 0x0, NULL
, HFILL
} },
4376 { &hf_message_sec_cat_val
,
4377 { "Security Categories", "dmp.sec_cat", FT_UINT8
, BASE_HEX
,
4378 NULL
, 0x0, NULL
, HFILL
} },
4379 { &hf_message_sec_cat_cl
,
4380 { "Clear", "dmp.sec_cat.cl", FT_BOOLEAN
, 8,
4381 TFS (&tfs_set_notset
), 0x80, NULL
, HFILL
} },
4382 { &hf_message_sec_cat_cs
,
4383 { "Crypto Security", "dmp.sec_cat.cs", FT_BOOLEAN
, 8,
4384 TFS (&tfs_set_notset
), 0x40, NULL
, HFILL
} },
4385 { &hf_message_sec_cat_ex
,
4386 { "Exclusive", "dmp.sec_cat.ex", FT_BOOLEAN
, 8,
4387 TFS (&tfs_set_notset
), 0x20, NULL
, HFILL
} },
4388 { &hf_message_sec_cat_ne
,
4389 { "National Eyes Only", "dmp.sec_cat.ne", FT_BOOLEAN
, 8,
4390 TFS (&tfs_set_notset
), 0x10, NULL
, HFILL
} },
4391 { &hf_message_sec_cat_permissive
,
4392 { "Releasable to", "dmp.sec_cat.permissive", FT_UINT8
, BASE_HEX
,
4393 VALS (nat_pol_id
), 0xFC, NULL
, HFILL
} },
4394 { &hf_message_sec_cat_country_code
,
4395 { "Country Code", "dmp.sec_cat.country", FT_UINT8
, BASE_DEC
,
4396 NULL
, 0x00, NULL
, HFILL
} },
4397 { &hf_message_sec_cat_restrictive
,
4398 { "Restrictive", "dmp.sec_cat.restrictive", FT_UINT8
, BASE_HEX
,
4399 NULL
, 0xFC, NULL
, HFILL
} },
4400 { &hf_message_sec_cat_extended
,
4401 { "Extended", "dmp.sec_cat.extended", FT_UINT8
, BASE_HEX
,
4402 VALS (ext_sec_cat
), 0x03, "Extended Security Category", HFILL
} },
4403 { &hf_message_sec_cat_bit0
,
4404 { "Bit 0", "dmp.sec_cat.bit0", FT_BOOLEAN
, 8,
4405 TFS (&tfs_set_notset
), 0x01, NULL
, HFILL
} },
4406 { &hf_message_sec_cat_bit1
,
4407 { "Bit 1", "dmp.sec_cat.bit1", FT_BOOLEAN
, 8,
4408 TFS (&tfs_set_notset
), 0x02, NULL
, HFILL
} },
4409 { &hf_message_sec_cat_bit2
,
4410 { "Bit 2", "dmp.sec_cat.bit2", FT_BOOLEAN
, 8,
4411 TFS (&tfs_set_notset
), 0x04, NULL
, HFILL
} },
4412 { &hf_message_sec_cat_bit3
,
4413 { "Bit 3", "dmp.sec_cat.bit3", FT_BOOLEAN
, 8,
4414 TFS (&tfs_set_notset
), 0x08, NULL
, HFILL
} },
4415 { &hf_message_sec_cat_bit4
,
4416 { "Bit 4", "dmp.sec_cat.bit4", FT_BOOLEAN
, 8,
4417 TFS (&tfs_set_notset
), 0x10, NULL
, HFILL
} },
4418 { &hf_message_sec_cat_bit5
,
4419 { "Bit 5", "dmp.sec_cat.bit5", FT_BOOLEAN
, 8,
4420 TFS (&tfs_set_notset
), 0x20, NULL
, HFILL
} },
4421 { &hf_message_sec_cat_bit6
,
4422 { "Bit 6", "dmp.sec_cat.bit6", FT_BOOLEAN
, 8,
4423 TFS (&tfs_set_notset
), 0x40, NULL
, HFILL
} },
4424 { &hf_message_sec_cat_bit7
,
4425 { "Bit 7", "dmp.sec_cat.bit7", FT_BOOLEAN
, 8,
4426 TFS (&tfs_set_notset
), 0x80, NULL
, HFILL
} },
4429 { &hf_message_exp_time
,
4430 { "Expiry Time", "dmp.expiry_time", FT_UINT8
, BASE_HEX
,
4431 NULL
, 0x0, NULL
, HFILL
} },
4432 { &hf_message_exp_time_val
,
4433 { "Expiry Time Value", "dmp.expiry_time_val", FT_UINT8
, BASE_HEX
,
4434 NULL
, 0x0, NULL
, HFILL
} },
4438 { "DTG", "dmp.dtg", FT_UINT8
, BASE_HEX
,
4439 NULL
, 0x0, NULL
, HFILL
} },
4440 { &hf_message_dtg_sign
,
4441 { "DTG in the", "dmp.dtg.sign", FT_BOOLEAN
, 8, TFS (&dtg_sign
),
4442 0x80, "Sign", HFILL
} },
4443 { &hf_message_dtg_val
,
4444 { "DTG Value", "dmp.dtg.val", FT_UINT8
, BASE_HEX
, NULL
,
4445 0x7F, NULL
, HFILL
} },
4449 { "SIC", "dmp.sic", FT_STRING
, BASE_NONE
,
4450 NULL
, 0x0, NULL
, HFILL
} },
4451 { &hf_message_sic_key
,
4452 { "SICs", "dmp.sic_key", FT_NONE
, BASE_NONE
,
4453 NULL
, 0x0, "SIC Content", HFILL
} },
4454 { &hf_message_sic_key_values
,
4455 { "Content Byte", "dmp.sic_key.values", FT_UINT8
, BASE_HEX
,
4456 NULL
, 0x0, "SIC Content Byte", HFILL
} },
4457 { &hf_message_sic_key_type
,
4458 { "Type", "dmp.sic_key.type", FT_UINT8
, BASE_HEX
,
4459 VALS (sic_key_type
), 0xF0, "SIC Content Type", HFILL
} },
4460 { &hf_message_sic_key_chars
,
4461 { "Valid Characters", "dmp.sic_key.chars", FT_BOOLEAN
, 8,
4462 TFS (&sic_key_chars
), 0x08, "SIC Valid Characters", HFILL
} },
4463 { &hf_message_sic_key_num
,
4464 { "Number of SICs", "dmp.sic_key.num", FT_UINT8
, BASE_HEX
,
4465 VALS (sic_key_num
), 0x07, NULL
, HFILL
} },
4466 { &hf_message_sic_bitmap
,
4467 { "Length Bitmap (0 = 3 bytes, 1 = 4-8 bytes)", "dmp.sic_bitmap",
4468 FT_UINT8
, BASE_HEX
, NULL
, 0xFF, "SIC Length Bitmap", HFILL
} },
4469 { &hf_message_sic_bits
,
4470 { "Bit 7-4", "dmp.sic_bits", FT_UINT8
, BASE_HEX
,
4471 VALS(sic_bit_vals
), 0xF0, "SIC Bit 7-4, Characters [A-Z0-9] only",
4473 { &hf_message_sic_bits_any
,
4474 { "Bit 7-4", "dmp.sic_bits_any", FT_UINT8
, BASE_HEX
,
4475 VALS(sic_bit_any_vals
), 0xF0, "SIC Bit 7-4, Any valid characters",
4478 /* Subject Message Id */
4479 { &hf_message_subj_id
,
4480 { "Subject Message Identifier", "dmp.subj_id", FT_UINT16
,
4481 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4483 /* Subject MTS Identifier */
4484 { &hf_message_subj_mts_id
,
4485 { "Subject MTS Identifier", "dmp.subj_mts_id", FT_STRING
, BASE_NONE
,
4486 NULL
, 0x0, NULL
, HFILL
} },
4488 /* Subject IPM Identifier */
4489 { &hf_message_subj_ipm_id
,
4490 { "Subject IPM Identifier", "dmp.subj_ipm_id", FT_STRING
, BASE_NONE
,
4491 NULL
, 0x0, NULL
, HFILL
} },
4497 { "Message Body", "dmp.body", FT_NONE
, BASE_NONE
, NULL
,
4498 0x0, NULL
, HFILL
} },
4502 { "EIT", "dmp.body.eit", FT_UINT8
, BASE_DEC
,
4503 VALS(eit_vals
), 0xE0, "Encoded Information Type", HFILL
} },
4504 { &hf_message_compr
,
4505 { "Compression", "dmp.body.compression", FT_UINT8
, BASE_DEC
,
4506 VALS(compression_vals
), 0x18, NULL
, HFILL
} },
4509 { &hf_message_subject
,
4510 { "Subject", "dmp.subject", FT_STRINGZ
, BASE_NONE
,
4511 NULL
, 0x0, NULL
, HFILL
} },
4514 { &hf_message_body_data
,
4515 { "User data", "dmp.body.data", FT_BYTES
, BASE_NONE
,
4516 NULL
, 0x0, NULL
, HFILL
} },
4517 { &hf_message_body_compressed
,
4518 { "Compressed User data", "dmp.body.compressed", FT_NONE
, BASE_NONE
,
4519 NULL
, 0x0, NULL
, HFILL
} },
4520 { &hf_message_body_plain
,
4521 { "Message Body", "dmp.body.plain", FT_STRING
, BASE_NONE
,
4522 NULL
, 0x0, NULL
, HFILL
} },
4523 { &hf_message_body_structured
,
4524 { "Structured Body", "dmp.body.structured", FT_BYTES
, BASE_NONE
,
4525 NULL
, 0x0, NULL
, HFILL
} },
4530 { &hf_delivery_report
,
4531 { "Delivery Report", "dmp.dr", FT_NONE
, BASE_NONE
, NULL
,
4532 0x0, NULL
, HFILL
} },
4533 { &hf_non_delivery_report
,
4534 { "Non-Delivery Report", "dmp.ndr", FT_NONE
, BASE_NONE
, NULL
,
4535 0x0, NULL
, HFILL
} },
4538 { "Report Type", "dmp.report_type", FT_BOOLEAN
, 8,
4539 TFS (&report_type
), 0x80, NULL
, HFILL
} },
4540 { &hf_report_info_present_dr
,
4541 { "Info Present", "dmp.info_present", FT_BOOLEAN
, 8,
4542 TFS (&tfs_present_absent
), 0x40, NULL
, HFILL
} },
4543 { &hf_report_addr_enc_dr
,
4544 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4545 TFS (&addr_enc
), 0x20, NULL
, HFILL
} },
4546 { &hf_report_del_time
,
4547 { "Delivery Time", "dmp.delivery_time", FT_UINT8
, BASE_HEX
,
4548 NULL
, 0x0, NULL
, HFILL
} },
4549 { &hf_report_del_time_val
,
4550 { "Delivery Time Value", "dmp.delivery_time_val", FT_UINT8
,
4551 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
4552 { &hf_report_addr_enc_ndr
,
4553 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4554 TFS (&addr_enc
), 0x40, NULL
, HFILL
} },
4555 { &hf_report_reason
,
4556 { "Reason (P1)", "dmp.report_reason", FT_UINT8
, BASE_DEC
,
4557 VALS (p1_NonDeliveryReasonCode_vals
), 0x3F,
4559 { &hf_report_info_present_ndr
,
4560 { "Info Present", "dmp.info_present", FT_BOOLEAN
, 8,
4561 TFS (&tfs_present_absent
), 0x80, NULL
, HFILL
} },
4563 { "Diagnostic (P1)", "dmp.report_diagnostic", FT_UINT8
, BASE_DEC
,
4564 VALS (p1_NonDeliveryDiagnosticCode_vals
), 0x7F,
4566 { &hf_report_suppl_info_len
,
4567 { "Supplementary Information", "dmp.suppl_info_len", FT_UINT8
,
4568 BASE_DEC
, NULL
, 0x0, "Supplementary Information Length", HFILL
} },
4569 { &hf_report_suppl_info
,
4570 { "Supplementary Information", "dmp.suppl_info", FT_STRINGZ
,
4571 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4576 { &hf_receipt_notif
,
4577 { "Receipt Notification (RN)", "dmp.rn", FT_NONE
, BASE_NONE
,
4578 NULL
, 0x0, NULL
, HFILL
} },
4579 { &hf_non_receipt_notif
,
4580 { "Non-Receipt Notification (NRN)", "dmp.nrn", FT_NONE
, BASE_NONE
,
4581 NULL
, 0x0, NULL
, HFILL
} },
4583 { "Other Notification (ON)", "dmp.on", FT_NONE
, BASE_NONE
,
4584 NULL
, 0x0, NULL
, HFILL
} },
4587 { "Notification Type", "dmp.notif_type", FT_UINT8
, BASE_DEC
,
4588 VALS (notif_type
), 0x03, NULL
, HFILL
} },
4589 { &hf_notif_rec_time
,
4590 { "Receipt Time", "dmp.receipt_time", FT_UINT8
, BASE_HEX
,
4591 NULL
, 0x0, NULL
, HFILL
} },
4592 { &hf_notif_rec_time_val
,
4593 { "Receipt Time Value", "dmp.receipt_time_val", FT_UINT8
,
4594 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
4595 { &hf_notif_suppl_info_len
,
4596 { "Supplementary Information", "dmp.suppl_info_len",
4597 FT_UINT8
, BASE_DEC
, NULL
, 0x0, "Supplementary Information Length",
4599 { &hf_notif_suppl_info
,
4600 { "Supplementary Information", "dmp.suppl_info",
4601 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0, NULL
,
4603 { &hf_notif_non_rec_reason
,
4604 { "Non-Receipt Reason", "dmp.notif_non_rec_reason",
4605 FT_UINT8
, BASE_DEC
, VALS (p22_NonReceiptReasonField_vals
), 0x0,
4607 { &hf_notif_discard_reason
,
4608 { "Discard Reason", "dmp.notif_discard_reason", FT_UINT8
,
4609 BASE_DEC
, VALS (p22_DiscardReasonField_vals
), 0x0,
4611 { &hf_notif_on_type
,
4612 { "ON Type", "dmp.notif_on_type", FT_UINT8
, BASE_DEC
,
4613 VALS (on_type
), 0x0, NULL
, HFILL
} },
4615 { "ACP127 Recipient", "dmp.acp127recip_len", FT_UINT8
,
4616 BASE_DEC
, NULL
, 0x0, "ACP 127 Recipient Length", HFILL
} },
4617 { &hf_notif_acp127recip
,
4618 { "ACP127 Recipient", "dmp.acp127recip", FT_STRINGZ
,
4619 BASE_NONE
, NULL
, 0x0, "ACP 127 Recipient", HFILL
} },
4625 { "Acknowledgement", "dmp.ack", FT_NONE
, BASE_NONE
,
4626 NULL
, 0x0, NULL
, HFILL
} },
4628 { "Ack Reason", "dmp.ack_reason", FT_UINT8
, BASE_DEC
,
4629 VALS (ack_reason
), 0x0, NULL
, HFILL
} },
4630 { &hf_ack_diagnostic
,
4631 { "Ack Diagnostic", "dmp.ack_diagnostic", FT_UINT8
, BASE_DEC
,
4632 NULL
, 0x0, NULL
, HFILL
} },
4634 { "Recipient List", "dmp.ack_rec_list", FT_NONE
, BASE_NONE
,
4635 NULL
, 0x0, NULL
, HFILL
} },
4641 { "Checksum", "dmp.checksum", FT_UINT16
, BASE_HEX
,
4642 NULL
, 0x0, NULL
, HFILL
} },
4643 { &hf_checksum_status
,
4644 { "Checksum Status", "dmp.checksum.status", FT_UINT8
, BASE_NONE
,
4645 VALS(proto_checksum_vals
), 0x0, NULL
, HFILL
} },
4648 ** Ack matching / Resend
4650 { &hf_analysis_ack_time
,
4651 { "Acknowledgement Time", "dmp.analysis.ack_time", FT_RELATIVE_TIME
, BASE_NONE
,
4652 NULL
, 0x0, "The time between the Message and the Acknowledge", HFILL
} },
4653 { &hf_analysis_rep_time
,
4654 { "Report Reply Time", "dmp.analysis.report_time", FT_RELATIVE_TIME
, BASE_NONE
,
4655 NULL
, 0x0, "The time between the Message and the Report", HFILL
} },
4656 { &hf_analysis_not_time
,
4657 { "Notification Reply Time", "dmp.analysis.notif_time", FT_RELATIVE_TIME
, BASE_NONE
,
4658 NULL
, 0x0, "The time between the Message and the Notification", HFILL
} },
4659 { &hf_analysis_total_time
,
4660 { "Total Time", "dmp.analysis.total_time", FT_RELATIVE_TIME
, BASE_NONE
,
4661 NULL
, 0x0, "The time between the first Message and the Acknowledge", HFILL
} },
4662 { &hf_analysis_retrans_time
,
4663 { "Retransmission Time", "dmp.analysis.retrans_time", FT_RELATIVE_TIME
, BASE_NONE
,
4664 NULL
, 0x0, "The time between the last Message and this Message", HFILL
} },
4665 { &hf_analysis_total_retrans_time
,
4666 { "Total Retransmission Time", "dmp.analysis.total_retrans_time", FT_RELATIVE_TIME
, BASE_NONE
,
4667 NULL
, 0x0, "The time between the first Message and this Message", HFILL
} },
4668 { &hf_analysis_msg_num
,
4669 { "Message in", "dmp.analysis.msg_in", FT_FRAMENUM
, BASE_NONE
,
4670 NULL
, 0x0, "This packet has a Message in this frame", HFILL
} },
4671 { &hf_analysis_acks_msg_num
,
4672 { "This is an Ack to the Message in", "dmp.analysis.acks_msg_in", FT_FRAMENUM
, BASE_NONE
,
4673 FRAMENUM_TYPE(FT_FRAMENUM_ACK
), 0x0, "This packet ACKs a Message in this frame", HFILL
} },
4674 { &hf_analysis_ack_num
,
4675 { "Acknowledgement in", "dmp.analysis.ack_in", FT_FRAMENUM
, BASE_NONE
,
4676 NULL
, 0x0, "This packet has an Acknowledgement in this frame", HFILL
} },
4677 { &hf_analysis_acks_rep_num
,
4678 { "This is an Ack to the Report in", "dmp.analysis.acks_report_in", FT_FRAMENUM
, BASE_NONE
,
4679 FRAMENUM_TYPE(FT_FRAMENUM_ACK
), 0x0, "This packet ACKs a Report in this frame", HFILL
} },
4681 { &hf_analysis_rep_num
,
4682 { "Report in", "dmp.analysis.report_in", FT_FRAMENUM
, BASE_NONE
,
4683 NULL
, 0x0, "This packet has a Report in this frame", HFILL
} },
4684 { &hf_analysis_not_num
,
4685 { "Notification in", "dmp.analysis.notif_in", FT_FRAMENUM
, BASE_NONE
,
4686 NULL
, 0x0, "This packet has a Notification in this frame", HFILL
} },
4688 { &hf_analysis_acks_not_num
,
4689 { "This is an Ack to the Notification in", "dmp.analysis.acks_notif_in", FT_FRAMENUM
, BASE_NONE
,
4690 FRAMENUM_TYPE(FT_FRAMENUM_ACK
), 0x0, "This packet ACKs a Notification in this frame", HFILL
} },
4691 { &hf_analysis_ack_missing
,
4692 { "Acknowledgement missing", "dmp.analysis.ack_missing", FT_NONE
, BASE_NONE
,
4693 NULL
, 0x0, "The acknowledgement for this packet is missing", HFILL
} },
4694 { &hf_analysis_retrans_no
,
4695 { "Retransmission #", "dmp.analysis.retrans_no", FT_UINT32
, BASE_DEC
,
4696 NULL
, 0x0, "Retransmission count", HFILL
} },
4697 { &hf_analysis_ack_dup_no
,
4698 { "Duplicate ACK #", "dmp.analysis.dup_ack_no", FT_UINT32
, BASE_DEC
,
4699 NULL
, 0x0, "Duplicate Acknowledgement count", HFILL
} },
4700 { &hf_analysis_msg_resend_from
,
4701 { "Retransmission of Message sent in", "dmp.analysis.msg_first_sent_in",
4702 FT_FRAMENUM
, BASE_NONE
,
4703 NULL
, 0x0, "This Message was first sent in this frame", HFILL
} },
4704 { &hf_analysis_rep_resend_from
,
4705 { "Retransmission of Report sent in", "dmp.analysis.report_first_sent_in",
4706 FT_FRAMENUM
, BASE_NONE
,
4707 NULL
, 0x0, "This Report was first sent in this frame", HFILL
} },
4708 { &hf_analysis_not_resend_from
,
4709 { "Retransmission of Notification sent in", "dmp.analysis.notif_first_sent_in",
4710 FT_FRAMENUM
, BASE_NONE
,
4711 NULL
, 0x0, "This Notification was first sent in this frame", HFILL
} },
4712 { &hf_analysis_ack_resend_from
,
4713 { "Retransmission of Acknowledgement sent in", "dmp.analysis.ack_first_sent_in",
4714 FT_FRAMENUM
, BASE_NONE
,
4715 NULL
, 0x0, "This Acknowledgement was first sent in this frame", HFILL
} },
4720 { &hf_reserved_0x01
,
4721 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4722 NULL
, 0x01, NULL
, HFILL
} },
4723 { &hf_reserved_0x02
,
4724 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4725 NULL
, 0x02, NULL
, HFILL
} },
4726 { &hf_reserved_0x04
,
4727 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4728 NULL
, 0x04, NULL
, HFILL
} },
4729 { &hf_reserved_0x07
,
4730 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4731 NULL
, 0x07, NULL
, HFILL
} },
4732 { &hf_reserved_0x08
,
4733 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4734 NULL
, 0x08, NULL
, HFILL
} },
4735 { &hf_reserved_0x0F
,
4736 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4737 NULL
, 0x0F, NULL
, HFILL
} },
4738 { &hf_reserved_0x1F
,
4739 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4740 NULL
, 0x1F, NULL
, HFILL
} },
4741 { &hf_reserved_0x20
,
4742 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4743 NULL
, 0x20, NULL
, HFILL
} },
4744 { &hf_reserved_0x40
,
4745 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4746 NULL
, 0x40, NULL
, HFILL
} },
4747 { &hf_reserved_0xC0
,
4748 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4749 NULL
, 0xC0, NULL
, HFILL
} },
4750 { &hf_reserved_0xE0
,
4751 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4752 NULL
, 0xE0, NULL
, HFILL
} },
4753 { &hf_reserved_0x8000
,
4754 { "Reserved", "dmp.reserved", FT_UINT16
, BASE_DEC
,
4755 NULL
, 0x8000, NULL
, HFILL
} },
4758 static int *ett
[] = {
4761 &ett_envelope_version
,
4762 &ett_envelope_hop_count
,
4763 &ett_envelope_rec_present
,
4764 &ett_envelope_addr_enc
,
4765 &ett_envelope_checksum
,
4766 &ett_envelope_extensions
,
4767 &ett_envelope_msg_id_type
,
4768 &ett_envelope_msg_id
,
4769 &ett_envelope_mts_id_length
,
4770 &ett_envelope_ipm_id_length
,
4771 &ett_envelope_cont_type
,
4772 &ett_envelope_subm_time
,
4773 &ett_envelope_time_diff
,
4774 &ett_envelope_flags
,
4775 &ett_envelope_recipients
,
4776 &ett_envelope_ext_recipients
,
4777 &ett_envelope_addresses
,
4779 &ett_address_direct
,
4780 &ett_address_rec_no
,
4781 &ett_address_extended
,
4782 &ett_address_ext_form
,
4783 &ett_address_ext_rec_no
,
4784 &ett_address_ext_action
,
4785 &ett_address_ext_rep_req
,
4786 &ett_address_ext_not_req
,
4787 &ett_address_ext_type
,
4788 &ett_address_ext_length
,
4791 &ett_extension_header
,
4794 &ett_message_st_type
,
4795 &ett_message_reserved
,
4796 &ett_message_precedence
,
4797 &ett_message_importance
,
4798 &ett_message_body_format
,
4799 &ett_message_sec_class
,
4800 &ett_message_sec_pol
,
4801 &ett_message_sec_cat
,
4802 &ett_message_heading_flags
,
4803 &ett_message_exp_time
,
4806 &ett_message_sic_key
,
4807 &ett_message_sic_bitmap
,
4808 &ett_message_sic_bits
,
4811 &ett_message_body_reserved
,
4815 &ett_report_info_present_dr
,
4816 &ett_report_info_present_ndr
,
4817 &ett_report_addr_enc_dr
,
4818 &ett_report_addr_enc_ndr
,
4819 &ett_report_reserved
,
4820 &ett_report_del_time
,
4822 &ett_report_suppl_info
,
4826 &ett_notif_rec_time
,
4827 &ett_notif_suppl_info
,
4828 &ett_notif_acp127recip
,
4834 static ei_register_info ei
[] = {
4835 { &ei_reserved_value
,
4836 { "dmp.reserved.expert", PI_UNDECODED
, PI_WARN
,
4837 "Reserved value", EXPFILL
} },
4838 { &ei_message_sic_illegal
,
4839 { "dmp.sic.illegal", PI_UNDECODED
, PI_NOTE
,
4840 "Illegal SIC", EXPFILL
} },
4841 { &ei_analysis_ack_unexpected
,
4842 { "dmp.analysis.ack_unexpected", PI_SEQUENCE
, PI_NOTE
,
4843 "Unexpected ACK", EXPFILL
} },
4844 { &ei_analysis_ack_missing
,
4845 { "dmp.analysis.ack_missing.expert", PI_SEQUENCE
, PI_NOTE
,
4846 "Acknowledgement missing", EXPFILL
} },
4847 { &ei_analysis_msg_missing
,
4848 { "dmp.analysis.msg_missing", PI_SEQUENCE
, PI_NOTE
,
4849 "Message missing", EXPFILL
} },
4850 { &ei_analysis_retrans_no
,
4851 { "dmp.analysis.retrans_no.expert", PI_SEQUENCE
, PI_NOTE
,
4852 "Retransmission #", EXPFILL
} },
4853 { &ei_analysis_ack_dup_no
,
4854 { "dmp.analysis.dup_ack_no.expert", PI_SEQUENCE
, PI_NOTE
,
4855 "Dup ACK #", EXPFILL
} },
4856 { &ei_addr_dir_rec_no_generated
,
4857 { "dmp.rec_no.expert", PI_MALFORMED
, PI_WARN
,
4858 "Recipient number too big", EXPFILL
} },
4859 { &ei_addr_ext_rec_no_generated
,
4860 { "dmp.rec_no.expert", PI_MALFORMED
, PI_WARN
,
4861 "Recipient number too big", EXPFILL
} },
4863 { "dmp.ack_reason.expert", PI_RESPONSE_CODE
, PI_NOTE
,
4864 "ACK reason", EXPFILL
} },
4865 { &ei_envelope_version_value
,
4866 { "dmp.version_value.unsupported", PI_UNDECODED
, PI_ERROR
,
4867 "Unsupported DMP Version", EXPFILL
} },
4868 { &ei_envelope_msg_id
,
4869 { "dmp.msg_id.short_id", PI_PROTOCOL
, PI_NOTE
,
4870 "Id < 4096 - should use ShortId", EXPFILL
} },
4871 { &ei_7bit_string_unused_bits
,
4872 { "dmp.7bit_string.unused_bits", PI_PROTOCOL
, PI_WARN
,
4873 "Unused bits in last byte shall be null", EXPFILL
} },
4874 { &ei_message_compr
,
4875 { "dmp.body.compression.unknown", PI_UNDECODED
, PI_WARN
,
4876 "Unknown compression algorithm", EXPFILL
} },
4877 { &ei_message_body_uncompress
,
4878 { "dmp.body.uncompress.fail", PI_UNDECODED
, PI_WARN
,
4879 "Error: Unable to uncompress content", EXPFILL
} },
4881 { "dmp.checksum_bad.expert", PI_CHECKSUM
, PI_WARN
,
4882 "Bad checksum", EXPFILL
} },
4883 { &ei_too_many_sec_cat
,
4884 { "dmp.too_many_security_categories", PI_PROTOCOL
, PI_ERROR
,
4885 "Too many security categories", EXPFILL
} },
4888 static uat_field_t attributes_flds
[] = {
4889 UAT_FLD_VS(dmp_security_class
,nation
, "Nation", nat_pol_id
, 0),
4890 UAT_FLD_DEC(dmp_security_class
,sec_class
, "Classification", "Security Classification"),
4891 UAT_FLD_CSTRING(dmp_security_class
,name
, "Name", "Classification Name"),
4895 uat_t
*attributes_uat
= uat_new("DMP Security Classifications",
4896 sizeof(dmp_security_class_t
),
4897 "dmp_security_classifications",
4899 &dmp_security_classes
,
4900 &num_dmp_security_classes
,
4901 UAT_AFFECTS_DISSECTION
, /* affects dissection of packets, but not set of named fields */
4902 "ChDMPSecurityClassifications",
4910 module_t
*dmp_module
;
4911 expert_module_t
* expert_dmp
;
4913 proto_dmp
= proto_register_protocol (PNAME
, PSNAME
, PFNAME
);
4915 dmp_handle
= register_dissector(PFNAME
, dissect_dmp
, proto_dmp
);
4917 proto_register_field_array (proto_dmp
, hf
, array_length (hf
));
4918 proto_register_subtree_array (ett
, array_length (ett
));
4919 expert_dmp
= expert_register_protocol(proto_dmp
);
4920 expert_register_field_array(expert_dmp
, ei
, array_length(ei
));
4922 dmp_id_hash_table
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dmp_id_hash
, dmp_id_hash_equal
);
4923 dmp_long_id_hash_table
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash
, g_str_equal
);
4925 /* Build national values */
4926 build_national_strings ();
4928 /* Register our configuration options */
4929 dmp_module
= prefs_register_protocol (proto_dmp
, NULL
);
4931 prefs_register_obsolete_preference (dmp_module
, "udp_port");
4932 prefs_register_obsolete_preference (dmp_module
, "udp_port_second");
4934 prefs_register_enum_preference (dmp_module
, "national_decode",
4935 "National decoding",
4936 "Select the type of decoding for nationally-defined values",
4937 &dmp_nat_decode
, national_decoding
,
4939 prefs_register_enum_preference (dmp_module
, "local_nation",
4940 "Nation of local server",
4941 "Select the nation of sending server. This is used when presenting"
4942 " security classification values in messages with security"
4943 " policy set to National (nation of local server)",
4944 &dmp_local_nation
, dmp_national_values
,
4946 prefs_register_uat_preference (dmp_module
, "classes_table",
4947 "National Security Classifications",
4948 "Translation table for national security classifications. This is used"
4949 " when presenting security classification values in messages with"
4950 " security policy set to National or Extended National",
4952 prefs_register_bool_preference (dmp_module
, "seq_ack_analysis",
4954 "Calculate sequence/acknowledgement analysis",
4955 &use_seq_ack_analysis
);
4956 prefs_register_bool_preference (dmp_module
, "align_ids",
4957 "Align identifiers in info list",
4958 "Align identifiers in info list"
4959 " (does not align when retransmission or"
4960 " duplicate acknowledgement indication)",
4962 prefs_register_obsolete_preference(dmp_module
, "subject_as_id");
4963 prefs_register_obsolete_preference(dmp_module
, "struct_print");
4964 prefs_register_obsolete_preference(dmp_module
, "struct_offset");
4965 prefs_register_obsolete_preference(dmp_module
, "struct_length");
4968 void proto_reg_handoff_dmp (void)
4970 dissector_add_uint ("s5066sis.ctl.appid", S5066_CLIENT_S4406_ANNEX_E_TMI_4_DMP
, dmp_handle
);
4971 dissector_add_uint_range_with_preference("udp.port", DEFAULT_DMP_PORT_RANGE
, dmp_handle
);
4980 * indent-tabs-mode: nil
4983 * ex: set shiftwidth=2 tabstop=8 expandtab:
4984 * :indentSize=2:tabSize=8:noTabs=true: