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
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 * Ref: http://jcs.dtic.mil/j6/cceb/acps/acp123/
35 * - Dissect extended Restrictive security categories
36 * - Add Transmission/Retransmission statistics
44 #include <epan/packet.h>
45 #include <epan/address.h>
46 #include <epan/addr_resolv.h>
47 #include <epan/to_str.h>
48 #include <epan/prefs.h>
49 #include <epan/wmem/wmem.h>
50 #include <epan/expert.h>
51 #include <epan/crc16-tvb.h>
52 #include <epan/asn1.h>
53 #include <epan/strutil.h>
56 #include "packet-p1.h"
57 #include "packet-p22.h"
59 #define PNAME "Direct Message Profile"
63 /* Default UDP Port Number */
64 #define DEFAULT_DMP_PORT_RANGE "5031"
66 /* Protocol Identifier */
70 /* Versions supported */
71 #define DMP_VERSION_1 1
72 #define DMP_VERSION_2 2
74 /* Message Type (dmp.msg_type) */
81 /* Message Identifier Type (dmp.msg_id_type) */
82 #define ONLY_DMP_ID 0x0
83 #define X400_MSG_ID 0x1
84 #define NAT_MSG_ID 0x2
86 /* Report Type (dmp.report_type) */
90 /* Notification Type (dmp.notif_type) */
95 /* Address Encoding (dmp.addr_enc) */
96 #define DIRECT_ADDR 0x0
97 #define EXTENDED_ADDR 0x1
99 /* Address type (internal values) */
103 #define ORIG_P2_ADDRESS 4
105 /* Extended Address Form (dmp_addr_form) */
106 #define P1_DIRECT 0x0
107 #define P2_DIRECT 0x1
108 #define P1_EXTENDED 0x2
109 #define P2_EXTENDED 0x3
110 #define P1_P2_DIRECT 0x4
111 #define P1_DIRECT_P2_EXTENDED 0x5
112 #define P1_EXTENDED_P2_DIRECT 0x6
113 #define P1_P2_EXTENDED 0x7
115 /* Extended Address Type */
119 /* Security Policy (dmp_sec_pol) */
122 #define EXTENDED_NATIONAL 0x6
123 #define EXTENDED_MISSION 0x7
125 #define SEC_CAT_EXT_NONE 0x0
126 #define SEC_CAT_EXT_PERMISSIVE 0x1
127 #define SEC_CAT_EXT_RESTRICTIVE 0x2
129 /* Body Format (dmp.body_format) */
130 #define FREE_TEXT 0x0
131 #define FREE_TEXT_SUBJECT 0x1
132 #define STRUCTURED 0x2
134 /* Encoded Information Types */
135 #define EIT_BILATERAL 0x3
137 /* Compression Algorithm */
138 #define ALGORITHM_NONE 0x0
139 #define ALGORITHM_ZLIB 0x1
141 /* Type of structured id to print */
142 #define STRUCT_ID_NONE 0
143 #define STRUCT_ID_UINT8 1
144 #define STRUCT_ID_UINT16 2
145 #define STRUCT_ID_UINT32 3
146 #define STRUCT_ID_UINT64 4
147 #define STRUCT_ID_STRING 5
148 #define STRUCT_ID_ZSTRING 6
150 #define NAT_DECODE_NONE 0
151 #define NAT_DECODE_DMP 1
152 #define NAT_DECODE_THALES 2
154 #define IPM_MODIFIER_X400 0
156 /* Internal values for not present and reserved time values */
157 #define DMP_TIME_NOT_PRESENT -1
158 #define DMP_TIME_RESERVED -2
160 #define ILLEGAL_FORMAT "<Illegal format>"
162 /* Maximum lengths */
163 #define MAX_SIC_LEN 30
165 void proto_reg_handoff_dmp (void);
167 static int proto_dmp
= -1;
169 static int hf_dmp_id
= -1;
170 static int hf_mts_id
= -1;
171 static int hf_ipm_id
= -1;
173 static int hf_envelope
= -1;
174 static int hf_envelope_protocol_id
= -1;
175 static int hf_envelope_version
= -1;
176 static int hf_envelope_version_value
= -1;
177 static int hf_envelope_hop_count
= -1;
178 static int hf_envelope_hop_count_value
= -1;
179 static int hf_envelope_rec_present
= -1;
180 static int hf_envelope_addr_enc
= -1;
181 static int hf_envelope_checksum
= -1;
182 static int hf_envelope_extensions
= -1;
183 static int hf_envelope_msg_id_type
= -1;
184 static int hf_envelope_msg_id_length
= -1;
185 static int hf_envelope_mts_id_length
= -1;
186 static int hf_envelope_ipm_id_modifier
= -1;
187 static int hf_envelope_ipm_id_length
= -1;
188 static int hf_envelope_mts_id
= -1;
189 static int hf_envelope_ipm_id
= -1;
190 static int hf_envelope_type
= -1;
191 static int hf_envelope_msg_id
= -1;
192 static int hf_envelope_msg_id_12bit
= -1;
193 static int hf_envelope_subm_time
= -1;
194 static int hf_envelope_subm_time_value
= -1;
195 static int hf_envelope_time_diff_present
= -1;
196 static int hf_envelope_time_diff
= -1;
197 static int hf_envelope_time_diff_value
= -1;
198 static int hf_envelope_flags
= -1;
199 static int hf_envelope_content_id_discarded
= -1;
200 static int hf_envelope_recip_reassign_prohib
= -1;
201 static int hf_envelope_dl_expansion_prohib
= -1;
202 static int hf_envelope_recipients
= -1;
203 static int hf_envelope_ext_recipients
= -1;
205 static int hf_thales_ipm_id_modifier
= -1;
207 static int hf_extensions
= -1;
208 static int hf_extension
= -1;
209 static int hf_extension_header
= -1;
210 static int hf_extension_more
= -1;
211 static int hf_extension_length
= -1;
212 static int hf_extension_data
= -1;
214 static int hf_message_content
= -1;
215 static int hf_report_content
= -1;
216 static int hf_notif_content
= -1;
218 static int hf_addr_recipient
= -1;
219 static int hf_addr_originator
= -1;
220 static int hf_addr_reporting_name
= -1;
221 static int hf_addr_dl_expanded
= -1;
222 static int hf_addr_int_rec
= -1;
223 static int hf_addr_dir_addr_ext
= -1;
224 static int hf_addr_dir_rec_no
= -1;
225 static int hf_addr_dir_rec_no1
= -1;
226 static int hf_addr_dir_rec_no2
= -1;
227 static int hf_addr_dir_rec_no3
= -1;
228 static int hf_addr_dir_rec_no_generated
= -1;
229 static int hf_addr_dir_rep_req1
= -1;
230 static int hf_addr_dir_rep_req2
= -1;
231 static int hf_addr_dir_rep_req3
= -1;
232 static int hf_addr_dir_not_req1
= -1;
233 static int hf_addr_dir_not_req2
= -1;
234 static int hf_addr_dir_not_req3
= -1;
235 static int hf_addr_dir_action
= -1;
236 static int hf_addr_dir_address
= -1;
237 static int hf_addr_dir_address1
= -1;
238 static int hf_addr_dir_address2
= -1;
239 static int hf_addr_dir_address3
= -1;
240 static int hf_addr_dir_address_generated
= -1;
242 static int hf_addr_ext_form
= -1;
243 static int hf_addr_ext_form_orig_v1
= -1;
244 static int hf_addr_ext_form_orig
= -1;
245 static int hf_addr_ext_action
= -1;
246 static int hf_addr_ext_rep_req
= -1;
247 static int hf_addr_ext_not_req
= -1;
248 static int hf_addr_ext_rec_ext
= -1;
249 static int hf_addr_ext_rec_no
= -1;
250 static int hf_addr_ext_rec_no1
= -1;
251 static int hf_addr_ext_rec_no2
= -1;
252 static int hf_addr_ext_rec_no_generated
= -1;
253 static int hf_addr_ext_address
= -1;
254 static int hf_addr_ext_type
= -1;
255 static int hf_addr_ext_type_ext
= -1;
256 static int hf_addr_ext_length
= -1;
257 static int hf_addr_ext_length1
= -1;
258 static int hf_addr_ext_length2
= -1;
259 static int hf_addr_ext_length_generated
= -1;
260 static int hf_addr_ext_asn1_ber
= -1;
261 static int hf_addr_ext_asn1_per
= -1;
262 static int hf_addr_ext_unknown
= -1;
264 static int hf_message_body
= -1;
265 static int hf_message_st_type
= -1;
266 static int hf_message_precedence
= -1;
267 static int hf_message_importance
= -1;
268 static int hf_message_body_format
= -1;
269 static int hf_message_sec_class_val
= -1;
270 static int hf_message_sec_pol
= -1;
271 static int hf_message_heading_flags
= -1;
272 static int hf_message_auth_users
= -1;
273 static int hf_message_subject_disc
= -1;
274 static int hf_message_national_policy_id
= -1;
275 static int hf_message_mission_policy_id
= -1;
276 static int hf_message_sec_label
= -1;
277 static int hf_message_sec_cat_nat
= -1;
278 static int hf_message_sec_cat_val
= -1;
279 static int hf_message_sec_cat_cl
= -1;
280 static int hf_message_sec_cat_cs
= -1;
281 static int hf_message_sec_cat_ex
= -1;
282 static int hf_message_sec_cat_ne
= -1;
283 static int hf_message_sec_cat_permissive
= -1;
284 static int hf_message_sec_cat_country_code
= -1;
285 static int hf_message_sec_cat_restrictive
= -1;
286 static int hf_message_sec_cat_extended
= -1;
287 static int hf_message_sec_cat_bit0
= -1;
288 static int hf_message_sec_cat_bit1
= -1;
289 static int hf_message_sec_cat_bit2
= -1;
290 static int hf_message_sec_cat_bit3
= -1;
291 static int hf_message_sec_cat_bit4
= -1;
292 static int hf_message_sec_cat_bit5
= -1;
293 static int hf_message_sec_cat_bit6
= -1;
294 static int hf_message_sec_cat_bit7
= -1;
295 static int hf_message_exp_time
= -1;
296 static int hf_message_exp_time_val
= -1;
297 static int hf_message_dtg
= -1;
298 static int hf_message_dtg_sign
= -1;
299 static int hf_message_dtg_val
= -1;
300 static int hf_message_sic
= -1;
301 static int hf_message_sic_key
= -1;
302 static int hf_message_sic_key_values
= -1;
303 static int hf_message_sic_key_type
= -1;
304 static int hf_message_sic_key_chars
= -1;
305 static int hf_message_sic_key_num
= -1;
306 static int hf_message_sic_bitmap
= -1;
307 static int hf_message_sic_bits
= -1;
308 static int hf_message_sic_bits_any
= -1;
309 static int hf_message_subj_id
= -1;
310 static int hf_message_subj_mts_id
= -1;
311 static int hf_message_subj_ipm_id
= -1;
313 static int hf_message_subject
= -1;
314 static int hf_message_eit
= -1;
315 static int hf_message_compr
= -1;
316 static int hf_message_body_data
= -1;
317 static int hf_message_body_plain
= -1;
318 static int hf_message_bodyid_uint8
= -1;
319 static int hf_message_bodyid_uint16
= -1;
320 static int hf_message_bodyid_uint32
= -1;
321 static int hf_message_bodyid_uint64
= -1;
322 static int hf_message_bodyid_string
= -1;
323 static int hf_message_bodyid_zstring
= -1;
324 static int hf_message_body_structured
= -1;
325 static int hf_message_body_uncompr
= -1;
326 static int hf_message_body_uncompressed
= -1;
328 static int hf_delivery_report
= -1;
329 static int hf_non_delivery_report
= -1;
330 static int hf_report_type
= -1;
331 static int hf_report_info_present_dr
= -1;
332 static int hf_report_addr_enc_dr
= -1;
333 static int hf_report_del_time
= -1;
334 static int hf_report_del_time_val
= -1;
335 static int hf_report_addr_enc_ndr
= -1;
336 static int hf_report_reason
= -1;
337 static int hf_report_info_present_ndr
= -1;
338 static int hf_report_diagn
= -1;
339 static int hf_report_suppl_info_len
= -1;
340 static int hf_report_suppl_info
= -1;
342 static int hf_receipt_notif
= -1;
343 static int hf_non_receipt_notif
= -1;
344 static int hf_other_notif
= -1;
345 static int hf_notif_type
= -1;
346 static int hf_notif_rec_time
= -1;
347 static int hf_notif_rec_time_val
= -1;
348 static int hf_notif_suppl_info_len
= -1;
349 static int hf_notif_suppl_info
= -1;
350 static int hf_notif_non_rec_reason
= -1;
351 static int hf_notif_discard_reason
= -1;
352 static int hf_notif_on_type
= -1;
353 static int hf_notif_acp127
= -1;
354 static int hf_notif_acp127recip
= -1;
356 static int hf_ack
= -1;
357 static int hf_ack_reason
= -1;
358 static int hf_ack_diagnostic
= -1;
359 static int hf_ack_recips
= -1;
361 static int hf_checksum
= -1;
362 static int hf_checksum_good
= -1;
363 static int hf_checksum_bad
= -1;
365 static int hf_analysis_ack_time
= -1;
366 static int hf_analysis_total_time
= -1;
367 static int hf_analysis_retrans_time
= -1;
368 static int hf_analysis_total_retrans_time
= -1;
369 static int hf_analysis_msg_num
= -1;
370 static int hf_analysis_retrans_no
= -1;
371 static int hf_analysis_ack_num
= -1;
372 static int hf_analysis_ack_missing
= -1;
373 static int hf_analysis_ack_dup_no
= -1;
374 static int hf_analysis_rep_num
= -1;
375 static int hf_analysis_rep_time
= -1;
376 static int hf_analysis_not_num
= -1;
377 static int hf_analysis_not_time
= -1;
378 static int hf_analysis_msg_resend_from
= -1;
379 static int hf_analysis_rep_resend_from
= -1;
380 static int hf_analysis_not_resend_from
= -1;
381 static int hf_analysis_ack_resend_from
= -1;
383 static int hf_reserved_0x01
= -1;
384 static int hf_reserved_0x02
= -1;
385 static int hf_reserved_0x04
= -1;
386 static int hf_reserved_0x07
= -1;
387 static int hf_reserved_0x08
= -1;
388 static int hf_reserved_0x0F
= -1;
389 static int hf_reserved_0x1F
= -1;
390 static int hf_reserved_0x20
= -1;
391 static int hf_reserved_0x40
= -1;
392 static int hf_reserved_0xC0
= -1;
393 static int hf_reserved_0xE0
= -1;
394 static int hf_reserved_0x8000
= -1;
396 static gint ett_dmp
= -1;
397 static gint ett_envelope
= -1;
398 static gint ett_envelope_version
= -1;
399 static gint ett_envelope_hop_count
= -1;
400 static gint ett_envelope_rec_present
= -1;
401 static gint ett_envelope_addr_enc
= -1;
402 static gint ett_envelope_checksum
= -1;
403 static gint ett_envelope_extensions
= -1;
404 static gint ett_envelope_msg_id_type
= -1;
405 static gint ett_envelope_msg_id
= -1;
406 static gint ett_envelope_mts_id_length
= -1;
407 static gint ett_envelope_ipm_id_length
= -1;
408 static gint ett_envelope_cont_type
= -1;
409 static gint ett_envelope_subm_time
= -1;
410 static gint ett_envelope_time_diff
= -1;
411 static gint ett_envelope_flags
= -1;
412 static gint ett_envelope_recipients
= -1;
413 static gint ett_envelope_ext_recipients
= -1;
414 static gint ett_envelope_addresses
= -1;
416 static gint ett_address
= -1;
417 static gint ett_address_direct
= -1;
418 static gint ett_address_rec_no
= -1;
419 static gint ett_address_extended
= -1;
420 static gint ett_address_ext_form
= -1;
421 static gint ett_address_ext_rec_no
= -1;
422 static gint ett_address_ext_action
= -1;
423 static gint ett_address_ext_rep_req
= -1;
424 static gint ett_address_ext_not_req
= -1;
425 static gint ett_address_ext_type
= -1;
426 static gint ett_address_ext_length
= -1;
428 static gint ett_extensions
= -1;
429 static gint ett_extension
= -1;
430 static gint ett_extension_header
= -1;
432 static gint ett_content
= -1;
434 static gint ett_message
= -1;
435 static gint ett_message_st_type
= -1;
436 static gint ett_message_reserved
= -1;
437 static gint ett_message_precedence
= -1;
438 static gint ett_message_importance
= -1;
439 static gint ett_message_body_format
= -1;
440 static gint ett_message_sec_class
= -1;
441 static gint ett_message_sec_pol
= -1;
442 static gint ett_message_sec_cat
= -1;
443 static gint ett_message_heading_flags
= -1;
444 static gint ett_message_exp_time
= -1;
445 static gint ett_message_dtg
= -1;
446 static gint ett_message_sic
= -1;
447 static gint ett_message_sic_key
= -1;
448 static gint ett_message_sic_bitmap
= -1;
449 static gint ett_message_sic_bits
= -1;
450 static gint ett_message_eit
= -1;
451 static gint ett_message_compr
= -1;
452 static gint ett_message_body_reserved
= -1;
453 static gint ett_message_body
= -1;
454 static gint ett_message_body_uncompr
= -1;
456 static gint ett_report
= -1;
457 static gint ett_report_type
= -1;
458 static gint ett_report_info_present_dr
= -1;
459 static gint ett_report_info_present_ndr
= -1;
460 static gint ett_report_addr_enc_dr
= -1;
461 static gint ett_report_addr_enc_ndr
= -1;
462 static gint ett_report_reserved
= -1;
463 static gint ett_report_del_time
= -1;
464 static gint ett_report_reason
= -1;
465 static gint ett_report_suppl_info
= -1;
466 static gint ett_report_diagn
= -1;
468 static gint ett_notif
= -1;
469 static gint ett_notif_type
= -1;
470 static gint ett_notif_rec_time
= -1;
471 static gint ett_notif_suppl_info
= -1;
472 static gint ett_notif_acp127recip
= -1;
474 static gint ett_ack
= -1;
475 static gint ett_ack_recips
= -1;
477 static gint ett_checksum
= -1;
479 static gint ett_analysis
= -1;
481 static expert_field ei_reserved_value
= EI_INIT
;
482 static expert_field ei_message_sic_illegal
= EI_INIT
;
483 static expert_field ei_envelope_version_value
= EI_INIT
;
484 static expert_field ei_message_compr
= EI_INIT
;
485 static expert_field ei_ack_reason
= EI_INIT
;
486 static expert_field ei_addr_dir_rec_no_generated
= EI_INIT
;
487 static expert_field ei_checksum_bad
= EI_INIT
;
488 static expert_field ei_message_body_uncompressed
= EI_INIT
;
489 static expert_field ei_addr_ext_rec_no_generated
= EI_INIT
;
490 static expert_field ei_envelope_msg_id
= EI_INIT
;
491 static expert_field ei_analysis_ack_missing
= EI_INIT
;
492 static expert_field ei_analysis_ack_dup_no
= EI_INIT
;
493 static expert_field ei_analysis_ack_unexpected
= EI_INIT
;
494 static expert_field ei_analysis_msg_missing
= EI_INIT
;
495 static expert_field ei_analysis_retrans_no
= EI_INIT
;
497 static dissector_handle_t dmp_handle
;
499 typedef struct _dmp_id_key
{
505 typedef struct _dmp_id_val
{
506 gint msg_type
; /* Message type */
507 guint prev_msg_id
; /* Previous message package num */
508 guint msg_id
; /* Message package num */
509 guint ack_id
; /* Acknowledgement package num */
510 guint rep_id
; /* Report package num */
511 guint not_id
; /* Notification package num */
512 nstime_t msg_time
; /* Message receive time */
513 nstime_t first_msg_time
; /* First message receive time */
514 nstime_t prev_msg_time
; /* Previous message receive time */
515 nstime_t rep_not_msg_time
; /* Report or Notification time */
516 guint32 msg_resend_count
; /* Message resend counter */
517 guint32 ack_resend_count
; /* Acknowledgement resend counter */
520 static GHashTable
*dmp_id_hash_table
= NULL
;
521 static GHashTable
*dmp_long_id_hash_table
= NULL
;
523 /* Global values used in several functions */
524 static struct dmp_data
{
537 guint8 mts_id_length
;
538 proto_item
*mts_id_item
;
546 gboolean ack_rec_present
;
550 /* User definable values */
551 static range_t
*global_dmp_port_range
;
552 static gint dmp_nat_decode
= NAT_DECODE_DMP
;
553 static gint dmp_local_nation
= 0;
554 static gboolean use_seq_ack_analysis
= TRUE
;
555 static gboolean dmp_align
= FALSE
;
556 static gboolean dmp_subject_as_id
= FALSE
;
557 static gint dmp_struct_format
= STRUCT_ID_NONE
;
558 static guint dmp_struct_offset
= 0;
559 static guint dmp_struct_length
= 1;
561 typedef struct _dmp_security_class_t
{
565 } dmp_security_class_t
;
567 static dmp_security_class_t
*dmp_security_classes
;
568 static guint num_dmp_security_classes
;
570 static const true_false_string addr_enc
= {
571 "Use Extended Encoding", "Use Direct Encoding"
574 static const true_false_string dtg_sign
= {
578 static const true_false_string report_type
= {
579 "Non-Delivery Report", "Delivery Report"
582 static const value_string version_vals
[] = {
593 static const value_string type_vals
[] = {
595 { 0x1, "Message (E-Mail)" },
597 { 0x3, "Notification" },
598 { 0x4, "Acknowledgement" },
599 { 0x5, "Unknown Content" },
600 { 0x6, "Unknown Content" },
601 { 0x7, "Unknown Content" },
604 static const value_string msg_id_type_vals
[] = {
605 { 0x0, "DMP Identifiers only" },
606 { 0x1, "X.400 Message Identifiers" },
607 { 0x2, "Nationally-defined" },
611 static const value_string msg_id_length_vals
[] = {
612 { 0x0, "Full (16 bits)" },
613 { 0x1, "Short (12 bits)" },
616 static const value_string report_vals
[] = {
617 { 0x0, "No Report" },
618 { 0x1, "Non-Delivery Report" },
619 { 0x2, "Delivery Report" },
623 static const value_string report_vals_ext
[] = {
624 { 0x0, "No Report" },
625 { 0x1, "Non-Delivery Report" },
626 { 0x2, "Delivery Report" },
627 { 0x3, "Recipient Number Extended" },
630 /* Note the space in front of these values */
631 static const value_string report_vals_short
[] = {
636 static const value_string notif_vals
[] = {
637 { 0x0, "No Notification" },
638 { 0x1, "Non-Receipt Notification" },
639 { 0x2, "Receipt Notification" },
643 static const value_string notif_vals_ext
[] = {
644 { 0x0, "No Notification" },
645 { 0x1, "Non-Receipt Notification" },
646 { 0x2, "Receipt Notification" },
647 { 0x3, "Direct Address Extended" },
650 /* Note the space in front of these values */
651 static const value_string notif_vals_short
[] = {
656 static const value_string notif_type
[] = {
657 { 0x0, "Receipt Notification (RN)" },
658 { 0x1, "Non-Receipt Notification (NRN)" },
659 { 0x2, "Other Notification (ON)" },
660 { 0x3, "Unknown Notification" },
663 /* Note the space behind these values */
664 static const value_string addr_type_str
[] = {
666 { P1_ADDRESS
, "P1 " },
667 { P2_ADDRESS
, "P22/P772 " },
668 { ORIG_P2_ADDRESS
, "P22 " },
671 static const value_string addr_form
[] = {
672 { 0x0, "P1 Direct" },
673 { 0x1, "P22/P772 Direct" },
674 { 0x2, "P1 Extended" },
675 { 0x3, "P22/P772 Extended" },
676 { 0x4, "P1 and P22/P772 Direct" },
677 { 0x5, "P1 Direct and P22/P772 Extended" },
678 { 0x6, "P1 Extended and P22/P772 Direct" },
679 { 0x7, "P1 and P22/P772 Extended" },
682 static const value_string addr_form_orig_v1
[] = {
693 static const value_string addr_form_orig
[] = {
698 { 0x4, "Originator and P2 Direct" },
699 { 0x5, "Originator Direct and P2 Extended" },
700 { 0x6, "Originator Extended and P2 Direct" },
701 { 0x7, "Originator and P2 Extended" },
704 static const value_string ext_addr_type
[] = {
705 { 0x0, "ASN.1 BER-encoded OR-name" },
706 { 0x1, "ASN.1 PER-encoded OR-name" },
712 { 0x7, "Address Length Extended" },
715 static const value_string ext_addr_type_ext
[] = {
716 { 0x0, "ASN.1 BER-encoded OR-name" },
717 { 0x1, "ASN.1 PER-encoded OR-name" },
726 static const value_string ext_addr_type_short
[] = {
727 { 0x0, "OR-name (BER)" },
728 { 0x1, "OR-name (PER)" },
737 static const value_string message_type_vals
[] = {
738 { 0x0, "Operation" },
744 static const value_string precedence
[] = {
748 { 0x3, "Immediate" },
751 { 0x6, "Priority, Info Precedence: Routine" },
752 { 0x7, "Immediate, Info Precedence: Routine" },
755 static const value_string importance
[] = {
766 static const value_string sec_class
[] = {
768 { 0x1, "Unclassified" },
769 /* { 0x2, "Reserved" }, */
770 { 0x3, "Restricted" },
771 /* { 0x4, "Reserved" }, */
772 { 0x5, "Confidential" },
774 { 0x7, "Top secret" },
777 static const value_string sec_pol
[] = {
778 { 0x0, "Network defined" },
779 { 0x1, "Network defined" },
780 { 0x2, "Network defined" },
781 { 0x3, "Network defined" },
783 { 0x5, "National (nation of local server)" },
784 { 0x6, "Extended, National" },
785 { 0x7, "Extended, Mission Defined" },
788 #define MAX_NATIONAL_VALUES 56
789 /* Will be built in build_national_strings() */
790 static value_string nat_pol_id
[MAX_NATIONAL_VALUES
+1];
792 /* For name we use the ISO 3166-1 Alfa-3 value for the country,
793 * for description we use the Country Name and
794 * for value we use the DMP value for National Policy Identifier.
796 static const enum_val_t dmp_national_values
[MAX_NATIONAL_VALUES
+1] = {
797 { "???", "None", 0x00 },
798 { "alb", "Albania", 0x1B },
799 { "arm", "Armenia", 0x20 },
800 { "aut", "Austria", 0x21 },
801 { "aze", "Azerbaijan", 0x22 },
802 { "blr", "Belarus", 0x23 },
803 { "bel", "Belgium", 0x01 },
804 { "bih", "Bosnia and Hercegowina", 0x24 },
805 { "bgr", "Bulgaria", 0x02 },
806 { "can", "Canada", 0x03 },
807 { "hrv", "Croatia", 0x1C },
808 { "cze", "Czech Republic", 0x04 },
809 { "dnk", "Denmark", 0x05 },
810 { "est", "Estonia", 0x06 },
811 { "eapc", "Euro-Atlantic Partnership Council (EAPC)", 0x3A },
812 { "eu", "European Union (EU)", 0x3B },
813 { "fin", "Finland", 0x25 },
814 { "mkd", "Former Yugoslav Republic of Macedonia", 0x26 },
815 { "fra", "France", 0x07 },
816 { "geo", "Georgia", 0x27 },
817 { "deu", "Germany", 0x08 },
818 { "grc", "Greece", 0x09 },
819 { "hun", "Hungary", 0x0A },
820 { "isl", "Iceland", 0x0B },
821 { "isaf", "International Security Assistance Force (ISAF)", 0x3C },
822 { "irl", "Ireland", 0x28 },
823 { "ita", "Italy", 0x0C },
824 { "kaz", "Kazakhstan", 0x29 },
825 { "kgz", "Kyrgyztan", 0x2A },
826 { "lva", "Latvia", 0x0D },
827 { "ltu", "Lithuania", 0x0E },
828 { "lux", "Luxembourg", 0x0F },
829 { "mlt", "Malta", 0x2B },
830 { "mda", "Moldova", 0x2C },
831 { "mne", "Montenegro", 0x2D },
832 { "nld", "Netherlands", 0x10 },
833 { "nor", "Norway", 0x11 },
834 { "pfp", "Partnership for Peace (PfP)", 0x3D },
835 { "pol", "Poland", 0x12 },
836 { "ptr", "Portugal", 0x13 },
837 { "rou", "Romania", 0x14 },
838 { "rus", "Russian Federation", 0x2E },
839 { "srb", "Serbia", 0x2F },
840 { "svk", "Slovakia", 0x15 },
841 { "svn", "Slovenia", 0x16 },
842 { "esp", "Spain", 0x17 },
843 { "swe", "Sweden", 0x30 },
844 { "che", "Switzerland", 0x31 },
845 { "tjk", "Tajikistan", 0x32 },
846 { "tur", "Turkey", 0x18 },
847 { "tkm", "Turkmenistan", 0x33 },
848 { "gbr", "United Kingdom", 0x19 },
849 { "usa", "United States", 0x1A },
850 { "ukr", "Ukraine", 0x34 },
851 { "uzb", "Uzbekistan", 0x35 },
852 { "weu", "Western European Union (WEU)", 0x3E },
856 static const value_string ext_sec_cat
[] = {
857 { 0x0, "Not present" },
858 { 0x1, "Permissive category follows" },
859 { 0x2, "Restrictive category follows" },
863 static const value_string sic_key_type
[] = {
864 { 0xc, "2 or more 3-character SICs" },
865 { 0xd, "1 or more 3-to-8 character SICs" },
868 static const true_false_string sic_key_chars
= {
869 "Any", "[A-Z0-9] only"
872 static const value_string sic_key_num
[] = {
884 static const value_string sic_bit_vals
[] = {
885 { 0, "length:6, bytes:4" },
886 { 1, "length:6, bytes:4" },
887 { 2, "length:6, bytes:4" },
888 { 3, "length:6, bytes:4" },
889 { 4, "length:6, bytes:4" },
890 { 5, "length:6, bytes:4" },
891 { 6, "length:6, bytes:4" },
892 { 7, "length:6, bytes:4" },
893 { 8, "length:6, bytes:4" },
895 { 10, "length:5, bytes:4" },
896 { 11, "length:8, bytes:6" },
897 { 12, "length:4, bytes:3" },
898 { 13, "length:4, bytes:3" },
899 { 14, "length:7, bytes:5" },
900 { 15, "length:7, bytes:5" },
903 static const value_string sic_bit_any_vals
[] = {
904 { 0, "length:5, bytes:4" },
905 { 1, "length:5, bytes:4" },
906 { 2, "length:5, bytes:4" },
907 { 3, "length:5, bytes:4" },
908 { 4, "length:5, bytes:4" },
909 { 5, "length:5, bytes:4" },
910 { 6, "length:5, bytes:4" },
911 { 7, "length:5, bytes:4" },
912 { 8, "length:5, bytes:4" },
913 { 9, "length:8, bytes:7" },
914 { 10, "length:4, bytes:4" },
915 { 11, "length:7, bytes:6" },
916 { 12, "length:6, bytes:5" },
917 { 13, "length:6, bytes:5" },
918 { 14, "length:6, bytes:5" },
919 { 15, "length:6, bytes:5" },
922 static const value_string body_format_vals
[] = {
923 { 0x0, "Free text" },
924 { 0x1, "Free text including subject" },
925 { 0x2, "Structured" },
929 static const value_string eit_vals
[] = {
932 { 0x2, "General text" },
933 { 0x3, "Bilaterally defined (binary data)" },
940 static const value_string compression_vals
[] = {
941 { 0x0, "No compression" },
942 { 0x1, "ZLib compressed" },
947 static const value_string ack_reason
[] = {
948 { 0x00, "Successful, positive acknowledgement" },
949 { 0x01, "Unspecified error" },
950 { 0x02, "Checksum incorrect" },
953 static const value_string non_del_reason
[] = {
954 { 0x3D, "Unknown reason" },
955 { 0x3E, "Reason code greater than 0x3c (60)" },
956 { 0x3F, "Reserved" },
959 static const value_string non_del_diagn
[] = {
960 { 0x7C, "Diagnostic not specified" },
961 { 0x7D, "Unknown diagnostic" },
962 { 0x7E, "Diagnostic code greater than 0x7b (123)" },
963 { 0x7F, "Reserved" },
966 static const value_string discard_reason
[] = {
967 { 0xFE, "Discard Reason absent" },
968 { 0xFF, "Reserved" },
971 static const value_string on_type
[] = {
972 { 0x00, "acp127-nn" },
973 { 0x01, "acp127-pn" },
974 { 0x02, "acp127-tn" },
977 static const value_string ack_msg_type
[] = {
978 { STANAG
, " (message)" },
979 { IPM
, " (e-mail)" },
980 { REPORT
, " (report)" },
981 { NOTIF
, " (notif)" },
985 static const enum_val_t struct_id_options
[] = {
986 { "none", "None", STRUCT_ID_NONE
},
987 { "1byte", "1 Byte value", STRUCT_ID_UINT8
},
988 { "2byte", "2 Byte value", STRUCT_ID_UINT16
},
989 { "4byte", "4 Byte value", STRUCT_ID_UINT32
},
990 { "8byte", "8 Byte value", STRUCT_ID_UINT64
},
991 { "fstring", "Fixed text string", STRUCT_ID_STRING
},
992 { "zstring", "Zero terminated text string", STRUCT_ID_ZSTRING
},
996 static const enum_val_t national_decoding
[] = {
997 { "none", "None (raw data)", NAT_DECODE_NONE
},
998 { "dmp", "As for regular", NAT_DECODE_DMP
},
999 { "thales", "Thales XOmail", NAT_DECODE_THALES
},
1003 static const value_string ipm_id_modifier
[] = {
1004 { 0x0, "X.400 IPM Identifier" },
1005 { 0x1, "Nationally-defined" },
1006 { 0x2, "Nationally-defined" },
1007 { 0x3, "Nationally-defined" },
1011 static const value_string thales_ipm_id_modifier
[] = {
1012 { 0x0, "X.400 IPM Identifier" },
1013 { 0x1, "3 or 5 digits" },
1014 { 0x2, "4 digits" },
1015 { 0x3, "5 digits" },
1019 UAT_VS_DEF(dmp_security_class
, nation
, dmp_security_class_t
, guint
, 0, "None")
1020 UAT_DEC_CB_DEF(dmp_security_class
, sec_class
, dmp_security_class_t
)
1021 UAT_CSTRING_CB_DEF(dmp_security_class
, name
, dmp_security_class_t
)
1024 dmp_class_copy_cb(void *dest
, const void *orig
, size_t len _U_
)
1026 dmp_security_class_t
*u
= (dmp_security_class_t
*)dest
;
1027 const dmp_security_class_t
*o
= (const dmp_security_class_t
*)orig
;
1029 u
->nation
= o
->nation
;
1030 u
->sec_class
= o
->sec_class
;
1031 u
->name
= g_strdup(o
->name
);
1037 dmp_class_free_cb(void *r
)
1039 dmp_security_class_t
*u
= (dmp_security_class_t
*)r
;
1044 static gchar
*dmp_national_sec_class (guint nation
, guint dmp_sec_class
)
1048 for (i
= 0; i
< num_dmp_security_classes
; i
++) {
1049 dmp_security_class_t
*u
= &(dmp_security_classes
[i
]);
1051 if (u
->nation
== nation
&& u
->sec_class
== dmp_sec_class
) {
1059 static void build_national_strings (void)
1064 ** We use values from dmp_national_values to build value_string for nat_pol_id.
1066 while (dmp_national_values
[i
].name
&& i
< MAX_NATIONAL_VALUES
) {
1067 nat_pol_id
[i
].value
= dmp_national_values
[i
].value
;
1068 nat_pol_id
[i
].strptr
= dmp_national_values
[i
].description
;
1071 nat_pol_id
[i
].value
= 0;
1072 nat_pol_id
[i
].strptr
= NULL
;
1075 static const gchar
*get_nat_pol_id_short (gint nation
)
1078 while (dmp_national_values
[i
].name
) {
1079 if (dmp_national_values
[i
].value
== nation
) {
1080 return dmp_national_values
[i
].name
;
1088 static const gchar
*msg_type_to_str (void)
1090 const gchar
*msg_type
;
1091 gboolean have_msg
= FALSE
;
1093 switch (dmp
.msg_type
) {
1096 /* Include message type and precedence */
1097 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "%s (%s) [%s]",
1098 val_to_str_const (dmp
.msg_type
, type_vals
, "Unknown"),
1099 val_to_str_const (dmp
.st_type
, message_type_vals
, "Unknown"),
1100 (dmp
.prec
== 0x6 || dmp
.prec
== 0x7) ?
1101 val_to_str_const (dmp
.prec
-4, precedence
, "Unknown") :
1102 val_to_str_const (dmp
.prec
, precedence
, "Unknown"));
1106 /* Include importance */
1107 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "%s [%s]",
1108 val_to_str_const (dmp
.msg_type
, type_vals
, "Unknown"),
1109 val_to_str_const (dmp
.prec
, importance
, "Unknown"));
1113 /* Include report types included */
1114 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "Report (%s%s%s)",
1115 dmp
.dr
? "DR" : "", (dmp
.dr
&& dmp
.ndr
) ? " and " : "",
1116 dmp
.ndr
? "NDR" : "");
1120 msg_type
= val_to_str_const (dmp
.notif_type
, notif_type
, "Unknown");
1124 /* If we have msg_time we have a matching packet */
1125 have_msg
= (dmp
.id_val
&&
1126 (dmp
.id_val
->msg_time
.secs
>0 || dmp
.id_val
->msg_time
.nsecs
>0));
1127 msg_type
= wmem_strdup_printf (wmem_packet_scope(), "Acknowledgement%s%s",
1128 have_msg
? val_to_str (dmp
.id_val
->msg_type
, ack_msg_type
,
1129 " (unknown:%d)") : "",
1130 dmp
.ack_reason
? " [negative]" : "");
1134 msg_type
= "Unknown";
1141 static const gchar
*non_del_reason_str (guint32 value
)
1144 /* Standard values according to P1 */
1145 return val_to_str_const (value
, p1_NonDeliveryReasonCode_vals
, "Unknown");
1147 return val_to_str_const (value
, non_del_reason
, "Unknown");
1151 static const gchar
*non_del_diagn_str (guint32 value
)
1154 /* Standard values according to P1 */
1155 return val_to_str_const (value
, p1_NonDeliveryDiagnosticCode_vals
, "Unknown");
1157 return val_to_str_const (value
, non_del_diagn
, "Unknown");
1161 static const gchar
*nrn_reason_str (guint32 value
)
1163 /* Standard values according to P22 */
1164 return val_to_str_const (value
, p22_NonReceiptReasonField_vals
, "Reserved");
1167 static const gchar
*discard_reason_str (guint32 value
)
1170 /* Standard values according to P22 */
1171 return val_to_str_const (value
, p22_DiscardReasonField_vals
, "Reserved");
1173 return val_to_str_const (value
, discard_reason
, "Unknown");
1177 /* Ref chapter 6.2.8.10 TimeDifference */
1178 static gint32
dmp_dec_time_diff (guint8 dmp_time_diff
)
1180 gint32 time_diff
= 0;
1182 if (dmp_time_diff
<= 0x01) {
1183 /* Reserved - low value */
1184 time_diff
= DMP_TIME_RESERVED
;
1185 } else if (dmp_time_diff
<= 0x1D) {
1186 /* Number of 2-second units (2-58 seconds) */
1187 time_diff
= dmp_time_diff
* 2;
1188 } else if (dmp_time_diff
<= 0x91) {
1189 /* Number of 15-second units (1 min - 29 min 45 sec) */
1190 time_diff
= (dmp_time_diff
- 0x1D + 3) * 15;
1191 } else if (dmp_time_diff
<= 0xDF) {
1192 /* Number of 5-minute units (30 min - 6 hours 55 min) */
1193 time_diff
= (dmp_time_diff
- 0x91 + 5) * 5*60;
1194 } else if (dmp_time_diff
<= 0xF7) {
1195 /* Number of 30-minute units (7 hours - 18 hours 30 min) */
1196 time_diff
= (dmp_time_diff
- 0xDF + 7) * 30*60;
1198 /* Reserved - high value */
1199 time_diff
= DMP_TIME_RESERVED
;
1206 * Ref chapter 6.3.7.2.10 ExpiryTime
1207 * and chapter 6.3.9.2.2 DeliveryTime
1209 static gint32
dmp_dec_exp_del_time (guint8 timev
, gboolean expiry_time
)
1211 gint32 time_value
= 0;
1213 if (expiry_time
&& (timev
== 0x00)) {
1214 /* No expiry time */
1215 time_value
= DMP_TIME_NOT_PRESENT
;
1216 } else if (timev
<= 0x1D) {
1217 /* Number of 2-second units (2-58 seconds) */
1218 time_value
= timev
* 2;
1219 } else if (timev
<= 0x91) {
1220 /* Number of 15-second units (1 min - 29 min 45 sec) */
1221 time_value
= (timev
- 0x1D + 3) * 15;
1222 } else if (timev
<= 0xBB) {
1223 /* Number of 5-minute units (30 min - 3 hours 55 min) */
1224 time_value
= (timev
- 0x91 + 5) * 5*60;
1225 } else if (timev
<= 0xE3) {
1226 /* Number of 30-minute units (4 hours - 23 hours 30 min) */
1227 time_value
= (timev
- 0xBB + 7) * 30*60;
1228 } else if (timev
< 0xFF) {
1229 /* Number of 2-hour units (24 - 78 hours) */
1230 time_value
= (timev
- 0xE3 + 11) * 2*3600;
1233 time_value
= DMP_TIME_RESERVED
;
1239 static gint32
dmp_dec_exp_time (guint8 expiry_time
)
1241 return dmp_dec_exp_del_time (expiry_time
, TRUE
);
1244 static gint32
dmp_dec_del_time (guint8 delivery_time
)
1246 return dmp_dec_exp_del_time (delivery_time
, FALSE
);
1249 /* Ref chapter 6.3.7.2.11 DTG */
1250 static gint32
dmp_dec_dtg (guint32 dtg
)
1256 value
= DMP_TIME_NOT_PRESENT
;
1257 } else if (dtg
<= 0x3C) {
1258 /* Number of minutes (0-59 min) */
1259 value
= (dtg
- 1) * 60;
1260 } else if (dtg
<= 0x64) {
1261 /* Number of 15-minute units (1 hour - 10 hours 45 min) */
1262 value
= (dtg
- 0x3C + 3) * 15 * 60;
1263 } else if (dtg
< 0x7F) {
1264 /* Number of hours (11-36 hours) */
1265 value
= (dtg
- 0x64 + 10) * 3600;
1268 value
= DMP_TIME_RESERVED
;
1275 * Ref chapter 7.10.11.1 Submission time
1277 * start_time (current time)
1278 * delta1 = E (encoded submission time)
1279 * delta2 = C (encoded current time)
1280 * 0x01C2 = Pn + 15min (maximum point for S1)
1281 * 0x7E38 = Pn+1 - 15min (minimum point for S3)
1282 * 0x7FF8 = Pn+1 (length of P (period))
1284 static gint32
dmp_dec_subm_time (guint16 delta1
, gint32 start_time
)
1286 gint32 subm_time
= start_time
;
1289 delta2
= (guint16
) ((subm_time
/ 2) % 0x7FF8);
1291 if ((delta1
< 0x01C2) && (delta2
>= delta1
+ 0x7E38)) {
1292 subm_time
+= 2 * (0x7FF8 - delta2
+ delta1
);
1293 } else if ((delta1
>= 0x01C2) && (delta2
< delta1
- 0x01C2)) {
1294 subm_time
-= 2 * (0x7FF8 - delta1
+ delta2
);
1296 subm_time
-= 2 * (delta2
- delta1
);
1302 /* Ref chapter 6.3.7.2.12 SIC */
1303 static gboolean
dmp_dec_xbyte_sic (guint64 bin
, gchar
*sic
,
1304 guint8 no_char
, gboolean any
)
1306 gboolean failure
= FALSE
;
1311 if (no_char
>= MAX_SIC_LEN
) {
1312 /* Illegal length */
1313 g_snprintf (sic
, MAX_SIC_LEN
, "Illegal length: %d", no_char
);
1323 for (i
= 0; i
< no_char
; i
++) {
1324 p
= (guint64
) pow (multiplier
, no_char
- 1 - i
);
1327 sic
[i
] = (gchar
) tmp
;
1330 } else if (sic
[i
] <= 35) {
1331 sic
[i
] += ('A' - 10);
1335 } else if (sic
[i
] <= 61) {
1336 sic
[i
] += ('a' - 36);
1337 } else if (sic
[i
] == 62) {
1339 } else if (sic
[i
] == 63) {
1341 } else if (sic
[i
] == 64) {
1343 } else if (sic
[i
] == 65) {
1345 } else if (sic
[i
] == 66) {
1347 } else if (sic
[i
] == 67) {
1349 } else if (sic
[i
] == 68) {
1351 } else if (sic
[i
] == 69) {
1353 } else if (sic
[i
] == 70) {
1355 } else if (sic
[i
] == 71) {
1357 } else if (sic
[i
] == 72) {
1359 } else if (sic
[i
] == 73) {
1371 static guint
dmp_id_hash (gconstpointer k
)
1373 dmp_id_key
*dmpx
=(dmp_id_key
*)k
;
1377 static gint
dmp_id_hash_equal (gconstpointer k1
, gconstpointer k2
)
1379 dmp_id_key
*dmp1
=(dmp_id_key
*)k1
;
1380 dmp_id_key
*dmp2
=(dmp_id_key
*)k2
;
1381 if (dmp1
->id
!= dmp2
->id
)
1384 return (ADDRESSES_EQUAL (&dmp1
->src
, &dmp2
->src
) &&
1385 ADDRESSES_EQUAL (&dmp1
->dst
, &dmp2
->dst
));
1388 static void register_dmp_id (packet_info
*pinfo
, guint8 reason
)
1390 dmp_id_val
*dmp_data
= NULL
, *pkg_data
= NULL
;
1391 dmp_id_key
*dmp_key
= NULL
;
1395 if (pinfo
->flags
.in_error_pkt
) {
1396 /* No analysis of error packets */
1400 nstime_set_zero(&msg_time
);
1402 dmp_key
= wmem_new (wmem_file_scope(), dmp_id_key
);
1404 if (!pinfo
->fd
->flags
.visited
&&
1405 (dmp
.msg_type
== REPORT
|| dmp
.msg_type
== NOTIF
))
1407 /* Try to match corresponding message */
1408 dmp_key
->id
= (guint
) dmp
.subj_id
;
1409 SE_COPY_ADDRESS(&dmp_key
->src
, &(pinfo
->dst
));
1410 SE_COPY_ADDRESS(&dmp_key
->dst
, &(pinfo
->src
));
1412 dmp_data
= (dmp_id_val
*) g_hash_table_lookup (dmp_id_hash_table
, dmp_key
);
1416 if (dmp_data
->prev_msg_id
> 0) {
1417 msg_id
= dmp_data
->prev_msg_id
;
1419 msg_id
= dmp_data
->msg_id
;
1421 msg_time
= dmp_data
->msg_time
;
1425 if (dmp
.msg_type
== ACK
) {
1426 dmp_key
->id
= (guint
) dmp
.subj_id
;
1427 SE_COPY_ADDRESS(&dmp_key
->src
, &(pinfo
->dst
));
1428 SE_COPY_ADDRESS(&dmp_key
->dst
, &(pinfo
->src
));
1430 dmp_key
->id
= (guint
) dmp
.msg_id
;
1431 SE_COPY_ADDRESS(&dmp_key
->src
, &(pinfo
->src
));
1432 SE_COPY_ADDRESS(&dmp_key
->dst
, &(pinfo
->dst
));
1435 dmp_data
= (dmp_id_val
*) g_hash_table_lookup (dmp_id_hash_table
, dmp_key
);
1437 if (!pinfo
->fd
->flags
.visited
) {
1439 if (dmp
.msg_type
== ACK
) {
1440 /* Only save this data if positive ack */
1442 if (dmp_data
->ack_id
== 0) {
1443 /* Only save reference to first ACK */
1444 dmp_data
->ack_id
= pinfo
->fd
->num
;
1446 /* Only count when resending */
1447 dmp_data
->ack_resend_count
++;
1451 /* Message resent */
1452 dmp_data
->msg_resend_count
++;
1453 dmp_data
->prev_msg_id
= pinfo
->fd
->num
;
1454 dmp_data
->prev_msg_time
= dmp_data
->msg_time
;
1455 dmp_data
->msg_time
= pinfo
->fd
->abs_ts
;
1459 dmp_data
= wmem_new0 (wmem_file_scope(), dmp_id_val
);
1460 dmp_data
->msg_type
= dmp
.msg_type
;
1462 if (dmp
.msg_type
== ACK
) {
1463 /* No matching message for this ack */
1464 dmp_data
->ack_id
= pinfo
->fd
->num
;
1466 dmp_data
->first_msg_time
= pinfo
->fd
->abs_ts
;
1467 dmp_data
->msg_time
= pinfo
->fd
->abs_ts
;
1469 if (dmp
.msg_type
== REPORT
) {
1470 dmp_data
->rep_id
= pinfo
->fd
->num
;
1471 dmp_data
->msg_id
= msg_id
;
1472 dmp_data
->rep_not_msg_time
= msg_time
;
1473 } else if (dmp
.msg_type
== NOTIF
) {
1474 dmp_data
->not_id
= pinfo
->fd
->num
;
1475 dmp_data
->msg_id
= msg_id
;
1476 dmp_data
->rep_not_msg_time
= msg_time
;
1478 dmp_data
->msg_id
= pinfo
->fd
->num
;
1481 g_hash_table_insert (dmp_id_hash_table
, dmp_key
, dmp_data
);
1485 pkg_data
= wmem_new (wmem_file_scope(), dmp_id_val
);
1486 *pkg_data
= *dmp_data
;
1487 p_add_proto_data (pinfo
->fd
, proto_dmp
, 0, pkg_data
);
1489 /* Fetch last values from data saved in packet */
1490 pkg_data
= (dmp_id_val
*)p_get_proto_data (pinfo
->fd
, proto_dmp
, 0);
1492 if (dmp_data
&& pkg_data
&& dmp
.msg_type
!= ACK
&& pkg_data
->ack_id
== 0) {
1493 pkg_data
->ack_id
= dmp_data
->ack_id
;
1497 DISSECTOR_ASSERT (pkg_data
);
1498 dmp
.id_val
= pkg_data
;
1501 static void dmp_add_seq_ack_analysis (tvbuff_t
*tvb
, packet_info
*pinfo
,
1502 proto_tree
*dmp_tree
, gint offset
)
1504 proto_tree
*analysis_tree
= NULL
;
1505 proto_item
*en
= NULL
, *eh
= NULL
;
1508 if (dmp
.msg_type
> ACK
|| (dmp
.msg_type
< ACK
&& !dmp
.checksum
) ||
1509 dmp
.id_val
== NULL
|| pinfo
->flags
.in_error_pkt
)
1511 /* No need for seq/ack analysis */
1515 en
= proto_tree_add_text (dmp_tree
, tvb
, 0, 0, "SEQ/ACK analysis");
1516 PROTO_ITEM_SET_GENERATED (en
);
1517 analysis_tree
= proto_item_add_subtree (en
, ett_analysis
);
1519 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
1520 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
)) {
1521 if (dmp
.id_val
->ack_id
) {
1522 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_num
, tvb
,
1523 0, 0, dmp
.id_val
->ack_id
);
1524 PROTO_ITEM_SET_GENERATED (en
);
1525 if (!dmp
.checksum
) {
1526 proto_item_append_text (en
, " (unexpected)");
1527 expert_add_info(pinfo
, en
, &ei_analysis_ack_unexpected
);
1529 } else if (dmp
.checksum
&& !dmp
.id_val
->msg_resend_count
) {
1530 en
= proto_tree_add_item (analysis_tree
, hf_analysis_ack_missing
, tvb
, offset
, 0, ENC_NA
);
1531 if (pinfo
->fd
->flags
.visited
) {
1532 /* We do not know this on first visit and we do not want to
1533 add a entry in the "Expert Severity Info" for this note */
1534 expert_add_info(pinfo
, en
, &ei_analysis_ack_missing
);
1535 PROTO_ITEM_SET_GENERATED (en
);
1539 if (dmp
.msg_type
== REPORT
) {
1540 if (dmp
.id_val
->msg_id
) {
1541 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_num
,
1542 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1543 PROTO_ITEM_SET_GENERATED (en
);
1545 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->rep_not_msg_time
);
1546 en
= proto_tree_add_time (analysis_tree
, hf_analysis_rep_time
,
1548 PROTO_ITEM_SET_GENERATED (en
);
1550 proto_tree_add_expert(analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1552 } else if (dmp
.msg_type
== NOTIF
) {
1553 if (dmp
.id_val
->msg_id
) {
1554 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_num
,
1555 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1556 PROTO_ITEM_SET_GENERATED (en
);
1558 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->rep_not_msg_time
);
1559 en
= proto_tree_add_time (analysis_tree
, hf_analysis_not_time
,
1561 PROTO_ITEM_SET_GENERATED (en
);
1563 proto_tree_add_expert(analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1567 if (dmp
.id_val
->msg_resend_count
) {
1568 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_retrans_no
,
1569 tvb
, 0, 0, dmp
.id_val
->msg_resend_count
);
1570 PROTO_ITEM_SET_GENERATED (en
);
1572 expert_add_info_format(pinfo
, en
, &ei_analysis_retrans_no
, "Retransmission #%d", dmp
.id_val
->msg_resend_count
);
1574 if (dmp
.msg_type
== REPORT
) {
1575 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_rep_resend_from
,
1576 tvb
, 0, 0, dmp
.id_val
->rep_id
);
1577 } else if (dmp
.msg_type
== NOTIF
) {
1578 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_not_resend_from
,
1579 tvb
, 0, 0, dmp
.id_val
->not_id
);
1581 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_resend_from
,
1582 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1584 PROTO_ITEM_SET_GENERATED (en
);
1586 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->prev_msg_time
);
1587 en
= proto_tree_add_time (analysis_tree
, hf_analysis_retrans_time
,
1589 PROTO_ITEM_SET_GENERATED (en
);
1591 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->first_msg_time
);
1592 eh
= proto_tree_add_time (analysis_tree
, hf_analysis_total_retrans_time
,
1594 PROTO_ITEM_SET_GENERATED (eh
);
1596 if (dmp
.id_val
->first_msg_time
.secs
== dmp
.id_val
->prev_msg_time
.secs
&&
1597 dmp
.id_val
->first_msg_time
.nsecs
== dmp
.id_val
->prev_msg_time
.nsecs
) {
1598 /* Time values does not differ, hide the total time */
1599 PROTO_ITEM_SET_HIDDEN (eh
);
1602 } else if (dmp
.msg_type
== ACK
) {
1603 if (dmp
.id_val
->msg_type
!= ACK
) {
1604 if (dmp
.id_val
->msg_type
== REPORT
) {
1605 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_rep_num
,
1606 tvb
, 0, 0, dmp
.id_val
->rep_id
);
1607 } else if (dmp
.id_val
->msg_type
== NOTIF
) {
1608 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_not_num
,
1609 tvb
, 0, 0, dmp
.id_val
->not_id
);
1611 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_msg_num
,
1612 tvb
, 0, 0, dmp
.id_val
->msg_id
);
1614 PROTO_ITEM_SET_GENERATED (en
);
1616 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->msg_time
);
1617 en
= proto_tree_add_time (analysis_tree
, hf_analysis_ack_time
,
1619 PROTO_ITEM_SET_GENERATED (en
);
1621 nstime_delta (&ns
, &pinfo
->fd
->abs_ts
, &dmp
.id_val
->first_msg_time
);
1622 eh
= proto_tree_add_time (analysis_tree
, hf_analysis_total_time
,
1624 PROTO_ITEM_SET_GENERATED (eh
);
1626 if (dmp
.id_val
->first_msg_time
.secs
== dmp
.id_val
->msg_time
.secs
&&
1627 dmp
.id_val
->first_msg_time
.nsecs
== dmp
.id_val
->msg_time
.nsecs
) {
1628 /* Time values does not differ, hide the total time */
1629 PROTO_ITEM_SET_HIDDEN (eh
);
1631 /* Different times, add a reference to the message we have ack'ed */
1632 proto_item_append_text (en
, " (from frame %d)",
1633 dmp
.id_val
->prev_msg_id
);
1636 proto_tree_add_expert(analysis_tree
, pinfo
, &ei_analysis_msg_missing
, tvb
, 0, 0);
1639 if (dmp
.id_val
->ack_resend_count
) {
1640 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_dup_no
,
1641 tvb
, 0, 0, dmp
.id_val
->ack_resend_count
);
1642 PROTO_ITEM_SET_GENERATED (en
);
1644 expert_add_info_format(pinfo
, en
, &ei_analysis_ack_dup_no
, "Dup ACK #%d", dmp
.id_val
->ack_resend_count
);
1646 en
= proto_tree_add_uint (analysis_tree
, hf_analysis_ack_resend_from
,
1647 tvb
, 0, 0, dmp
.id_val
->ack_id
);
1648 PROTO_ITEM_SET_GENERATED (en
);
1653 static gchar
*dissect_7bit_string (tvbuff_t
*tvb
, gint offset
, gint length
)
1655 guchar
*encoded
= tvb_get_string (wmem_packet_scope(), tvb
, offset
, length
);
1656 guchar
*decoded
= (guchar
*)wmem_alloc0 (wmem_packet_scope(), (size_t)(length
* 1.2) + 1);
1657 guchar rest
= 0, bits
= 1;
1660 for (i
= 0; i
< length
; i
++) {
1661 decoded
[len
++] = encoded
[i
] >> bits
| rest
;
1662 rest
= (encoded
[i
] << (7 - bits
) & 0x7F);
1664 decoded
[len
++] = rest
;
1672 return (gchar
*) decoded
;
1675 static const gchar
*dissect_thales_mts_id (tvbuff_t
*tvb
, gint offset
, gint length
)
1677 /* Thales XOmail uses this format: "MTA-NAME/000000000000" */
1678 if (length
>= 7 && length
<= 22) {
1679 return wmem_strdup_printf (wmem_packet_scope(), "%s/%08X%04X",
1680 dissect_7bit_string (tvb
, offset
, length
- 6),
1681 tvb_get_ntohl (tvb
, offset
+ length
- 6),
1682 tvb_get_ntohs (tvb
, offset
+ length
- 2));
1685 return ILLEGAL_FORMAT
;
1688 static const gchar
*dissect_thales_ipm_id (tvbuff_t
*tvb
, gint offset
, gint length
, gint modifier
)
1690 /* Thales XOmail uses this format: "<prefix>0000 YYMMDDhhmmssZ" */
1691 if (length
>= 6 && length
<= 20 && modifier
>= 0 && modifier
<= 2) {
1692 guint number
= tvb_get_ntohs (tvb
, offset
+ length
- 6);
1693 guint8 number_len
= modifier
+ 2;
1694 time_t timev
= tvb_get_ntohl(tvb
, offset
+ length
- 4);
1695 struct tm
*tmp
= gmtime(&timev
);
1697 if (modifier
== 1 && number
>= 1024) {
1698 /* The number is in the range 65536-99999 */
1700 number
+= (65536 - 1024);
1703 return wmem_strdup_printf (wmem_packet_scope(), "%s%0*d %02d%02d%02d%02d%02d%02dZ",
1704 (length
== 6) ? "" : dissect_7bit_string (tvb
, offset
, length
- 6),
1706 tmp
->tm_year
% 100, tmp
->tm_mon
+ 1, tmp
->tm_mday
,
1707 tmp
->tm_hour
, tmp
->tm_min
, tmp
->tm_sec
);
1710 return ILLEGAL_FORMAT
;
1713 /* Ref chapter 6.3.7.2.12 SIC */
1714 static gint
dissect_dmp_sic (tvbuff_t
*tvb
, packet_info
*pinfo
,
1715 proto_tree
*message_tree
, gint offset
)
1717 proto_tree
*sic_tree
= NULL
, *bitmap_tree
= NULL
, *key_tree
= NULL
;
1718 proto_item
*sf
= NULL
, *bf
= NULL
, *kf
= NULL
;
1720 guint8 key
, bitmap
, no
, i
, length
= 0;
1721 gboolean any
, no_sic
= FALSE
, failure
= FALSE
;
1722 gint bytes
= 0, boffset
= offset
;
1725 key
= tvb_get_guint8 (tvb
, offset
);
1726 sic
= (gchar
*)wmem_alloc (wmem_packet_scope(), MAX_SIC_LEN
);
1729 /* 2 bytes, single 3-character SIC, characters [A-Z0-9] only */
1731 value
= tvb_get_ntohs (tvb
, offset
);
1732 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, FALSE
);
1733 sf
= proto_tree_add_string_format_value(message_tree
, hf_message_sic
, tvb
,
1735 "%s [A-Z0-9 only]%s", sic
,
1736 failure
? " (invalid)": "");
1738 expert_add_info(pinfo
, sf
, &ei_message_sic_illegal
);
1742 } else if (key
<= 0xBD) {
1743 /* 3 bytes, single 3-character SIC, any valid character */
1745 value
= tvb_get_ntohl (tvb
, offset
);
1746 value
= (value
>> 8) & 0x48FFFF;
1747 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, TRUE
);
1748 sf
= proto_tree_add_string_format_value(message_tree
, hf_message_sic
, tvb
,
1750 "%s [any character]%s", sic
,
1751 failure
? " (invalid)": "");
1753 expert_add_info(pinfo
, sf
, &ei_message_sic_illegal
);
1757 } else if (key
<= 0xBF) {
1758 /* Reserved (not used) */
1759 g_snprintf (sic
, MAX_SIC_LEN
, "Reserved");
1762 } else if (key
<= 0xCF) {
1763 /* 2 or more 3-character SICs */
1765 sf
= proto_tree_add_item (message_tree
, hf_message_sic_key
, tvb
, offset
, 1, ENC_NA
);
1766 sic_tree
= proto_item_add_subtree (sf
, ett_message_sic
);
1768 kf
= proto_tree_add_item (sic_tree
, hf_message_sic_key_values
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1769 key_tree
= proto_item_add_subtree (kf
, ett_message_sic_key
);
1771 proto_tree_add_item (key_tree
, hf_message_sic_key_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1772 proto_tree_add_item (key_tree
, hf_message_sic_key_chars
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1773 proto_tree_add_item (key_tree
, hf_message_sic_key_num
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1777 no
= (key
& 0x07) + 1;
1778 for (i
= 0; i
< no
; i
++) {
1780 value
= tvb_get_ntohl (tvb
, offset
);
1781 value
= (value
>> 8) & 0x48FFFF;
1784 value
= tvb_get_ntohs (tvb
, offset
);
1787 failure
= dmp_dec_xbyte_sic (value
, sic
, 3, any
);
1788 bf
= proto_tree_add_string_format (sic_tree
, hf_message_sic
, tvb
,
1790 "SIC %d: %s%s", i
+ 1, sic
,
1791 failure
? " (invalid)": "");
1793 expert_add_info(pinfo
, bf
, &ei_message_sic_illegal
);
1797 proto_item_append_text (sf
, ": %d (3 %s character)", no
,
1798 any
? "any" : "[A-Z0-9]");
1800 } else if (key
<= 0xDF) {
1801 /* 1 or more 3 to 8 character SICs */
1803 sf
= proto_tree_add_item (message_tree
, hf_message_sic_key
, tvb
, offset
, 1, ENC_NA
);
1804 sic_tree
= proto_item_add_subtree (sf
, ett_message_sic
);
1806 kf
= proto_tree_add_item (sic_tree
, hf_message_sic_key_values
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1807 key_tree
= proto_item_add_subtree (kf
, ett_message_sic_key
);
1809 proto_tree_add_item (key_tree
, hf_message_sic_key_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1810 proto_tree_add_item (key_tree
, hf_message_sic_key_chars
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1811 proto_tree_add_item (key_tree
, hf_message_sic_key_num
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1814 bitmap
= tvb_get_guint8 (tvb
, offset
);
1815 bf
= proto_tree_add_uint_format (sic_tree
, hf_message_sic_bitmap
, tvb
,
1817 "Length Bitmap: 0x%2.2x", bitmap
);
1818 bitmap_tree
= proto_item_add_subtree (bf
, ett_message_sic_bitmap
);
1819 proto_tree_add_item (bitmap_tree
, hf_message_sic_bitmap
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1822 no
= (key
& 0x07) + 1;
1825 for (i
= 0; i
< no
; i
++) {
1826 if (bitmap
& (1 << (7 - i
))) {
1827 /* 4 - 8 character */
1828 key
= tvb_get_guint8 (tvb
, offset
);
1830 /* Any valid characters */
1831 if ((key
& 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1834 value
= tvb_get_ntohl (tvb
, offset
) & 0x0FFFFFFF;
1835 } else if ((key
& 0xC0) == 0xC0) { /* bit 7-4: 11xx */
1838 value
= ((guint64
)key
& 0x3F)<<32|tvb_get_ntohl (tvb
, offset
+ 1);
1839 } else if ((key
& 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1842 value
= ((guint64
)(tvb_get_ntohs (tvb
, offset
) & 0x0FFF)) << 32 |
1843 tvb_get_ntohl (tvb
, offset
+ 2);
1844 } else if ((key
& 0xF0) == 0x90) { /* bit 7-4: 1001 */
1847 value
= ((guint64
)((tvb_get_ntohl (tvb
, offset
)>>8) & 0x0FFF))<<32 |
1848 tvb_get_ntohl (tvb
, offset
+ 3);
1849 } else { /* bit 7-4: 0xxx or 1000 */
1852 value
= tvb_get_ntohl (tvb
, offset
);
1855 /* Characterts [A-Z0-9] only */
1856 if ((key
& 0xE0) == 0xC0) { /* bit 7-4: 110x */
1859 value
= (tvb_get_ntohl (tvb
, offset
) >> 8) & 0x1FFFFF;
1860 } else if ((key
& 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1863 value
= tvb_get_ntohl (tvb
, offset
) & 0x0FFFFFFF;
1864 } else if ((key
& 0xE0) == 0xE0) { /* bit 7-4: 111x */
1867 value
= ((guint64
)key
& 0x1F)<<32 | tvb_get_ntohl (tvb
, offset
+1);
1868 } else if ((key
& 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1871 value
= ((guint64
)tvb_get_ntohs (tvb
, offset
) & 0x0FFF) << 32 |
1872 tvb_get_ntohl (tvb
, offset
+ 2);
1873 } else { /* bit 7-4: 0xxx or 1000 */
1876 value
= tvb_get_ntohl (tvb
, offset
);
1882 value
= (tvb_get_ntohl (tvb
, offset
) >> 8) & 0x48FFFF;
1886 value
= tvb_get_ntohs (tvb
, offset
);
1891 failure
= dmp_dec_xbyte_sic (value
, sic
, length
, any
);
1892 bf
= proto_tree_add_string_format (sic_tree
, hf_message_sic
, tvb
,
1894 "SIC %d: %s (%d bytes: %" G_GINT64_MODIFIER
"x)%s",
1895 i
+ 1, sic
, bytes
, value
,
1896 failure
? " (invalid)": "");
1897 if (bitmap
& (1 << (7 - i
))) {
1898 /* Only if 4 - 8 character */
1899 bitmap_tree
= proto_item_add_subtree (bf
, ett_message_sic_bits
);
1901 proto_tree_add_item (bitmap_tree
, hf_message_sic_bits_any
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1903 proto_tree_add_item (bitmap_tree
, hf_message_sic_bits
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1907 expert_add_info(pinfo
, bf
, &ei_message_sic_illegal
);
1911 proto_item_append_text (sf
, ": %d (3-to-8 %s character)", no
,
1912 any
? "any" : "[A-Z0-9]");
1914 } else if (key
== 0xFE) {
1916 g_snprintf (sic
, MAX_SIC_LEN
, "Not present");
1920 /* Resered (not used) */
1921 g_snprintf (sic
, MAX_SIC_LEN
, "Reserved");
1926 /* Not added any SIC, dump text value */
1927 sf
= proto_tree_add_string (message_tree
, hf_message_sic
, tvb
, offset
, 1, sic
);
1931 proto_item_set_len (sf
, offset
- boffset
);
1936 /* Ref chapter 5.2.7.1 Direct Originator Encoding */
1937 static gint
dissect_dmp_direct_addr (tvbuff_t
*tvb
, packet_info
*pinfo
,
1938 proto_tree
*field_tree
, proto_item
*tf
,
1939 gint offset
, gint rec_no
,
1940 gint rec_ofs
, gint addr_type
)
1942 proto_tree
*addr_tree
= NULL
;
1943 proto_item
*en
= NULL
;
1947 value
= tvb_get_guint8 (tvb
, offset
);
1948 dir_addr
= (value
& 0x7F);
1950 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address1
, tvb
,
1952 "%sDirect Address (bits 6-0): %d",
1953 val_to_str_const (addr_type
, addr_type_str
, ""),
1955 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1956 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1957 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1961 value
= tvb_get_guint8 (tvb
, offset
);
1962 dir_addr
|= ((value
& 0x3F) << 7);
1963 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address2
, tvb
,
1965 "%sDirect Address (bits 12-7): %d",
1966 val_to_str_const (addr_type
, addr_type_str
, ""),
1968 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1969 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1970 en
= proto_tree_add_item (addr_tree
, hf_reserved_0x40
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1972 expert_add_info(pinfo
, en
, &ei_reserved_value
);
1974 proto_tree_add_item (addr_tree
, hf_addr_dir_address2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1979 value
= tvb_get_guint8 (tvb
, offset
);
1980 dir_addr
|= ((value
& 0x3F) << 13);
1981 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address3
, tvb
,
1983 "%sDirect Address (bits 18-13): %d",
1984 val_to_str_const (addr_type
,addr_type_str
,""),
1986 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
1987 en
= proto_tree_add_item (addr_tree
, hf_reserved_0xC0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1989 expert_add_info(pinfo
, en
, &ei_reserved_value
);
1991 proto_tree_add_item (addr_tree
, hf_addr_dir_address3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1995 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address_generated
,
1996 tvb
, offset
, 0, dir_addr
,
1997 "%sDirect Address: %d",
1998 val_to_str_const (addr_type
, addr_type_str
, ""),
2000 PROTO_ITEM_SET_GENERATED (en
);
2002 en
= proto_tree_add_uint_format (field_tree
, hf_addr_dir_address
, tvb
,
2004 "%sDirect Address: %d",
2005 val_to_str_const (addr_type
, addr_type_str
, ""),
2007 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2008 proto_tree_add_item (addr_tree
, hf_addr_dir_addr_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2009 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2014 proto_item_append_text (tf
, " %d", rec_no
);
2015 if (rec_ofs
!= -1) {
2016 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
2019 proto_item_append_text (tf
, ", %sDirect Address: %d",
2020 val_to_str_const (addr_type
, addr_type_str
, ""), dir_addr
);
2025 /* Ref 5.3.14 Extended Address */
2026 static gint
dissect_dmp_ext_addr (tvbuff_t
*tvb
, packet_info
*pinfo
,
2027 proto_tree
*field_tree
, proto_item
*tf
,
2028 gint offset
, gint rec_no
, gint rec_ofs
,
2031 proto_tree
*addr_tree
= NULL
, *ext_tree
= NULL
;
2032 proto_item
*en
= NULL
, *ef
= NULL
;
2035 gint boffset
= offset
;
2036 gboolean addr_length_extended
= FALSE
;
2037 asn1_ctx_t asn1_ctx
;
2039 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, TRUE
, pinfo
);
2041 value
= tvb_get_guint8 (tvb
, offset
);
2042 type
= (value
& 0xE0) >> 5;
2043 length
= (value
& 0x1F);
2044 ef
= proto_tree_add_none_format (field_tree
, hf_addr_ext_address
, tvb
,
2045 offset
, -1, "%sExtended Address",
2046 val_to_str_const (addr_type
, addr_type_str
, ""));
2047 ext_tree
= proto_item_add_subtree (ef
, ett_address_extended
);
2049 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_type
, tvb
,
2050 offset
, 1, value
, "Address Type: %s",
2051 val_to_str_const (type
, ext_addr_type
,
2053 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_type
);
2054 proto_tree_add_item (addr_tree
, hf_addr_ext_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2057 addr_length_extended
= TRUE
;
2058 en
= proto_tree_add_uint(ext_tree
, hf_addr_ext_length1
, tvb
,
2060 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2061 proto_tree_add_item (addr_tree
, hf_addr_ext_length1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2065 value
= tvb_get_guint8 (tvb
, offset
);
2066 type
= ((value
& 0xE0) >> 5);
2067 length
|= ((value
& 0x1F) << 5);
2069 en
= proto_tree_add_uint_format (ext_tree
, hf_addr_ext_type_ext
, tvb
,
2070 offset
, 1, value
, "Address Type Ext: %s",
2071 val_to_str_const (type
, ext_addr_type_ext
,
2073 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_type
);
2074 proto_tree_add_item (addr_tree
, hf_addr_ext_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2076 en
= proto_tree_add_uint(ext_tree
, hf_addr_ext_length2
, tvb
,
2078 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2079 proto_tree_add_item (addr_tree
, hf_addr_ext_length2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2082 en
= proto_tree_add_uint(ext_tree
, hf_addr_ext_length
, tvb
,
2084 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_length
);
2085 proto_tree_add_item (addr_tree
, hf_addr_ext_length1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2089 if (type
== ASN1_BER
) {
2090 tvbuff_t
*next_tvb
= tvb_new_subset(tvb
, offset
, length
, length
);
2092 dissect_p1_ORName (FALSE
, next_tvb
, 0, &asn1_ctx
, ext_tree
,
2093 hf_addr_ext_asn1_ber
);
2094 } else if (type
== ASN1_PER
) {
2095 proto_tree_add_item (ext_tree
, hf_addr_ext_asn1_per
, tvb
, offset
, length
, ENC_NA
);
2097 proto_tree_add_item (ext_tree
, hf_addr_ext_unknown
, tvb
, offset
, length
, ENC_NA
);
2101 if (addr_length_extended
) {
2102 en
= proto_tree_add_uint(ext_tree
, hf_addr_ext_length_generated
,
2103 tvb
, offset
, 0, length
);
2104 PROTO_ITEM_SET_GENERATED (en
);
2107 proto_item_append_text (ef
, ", Type: %s, Length: %d",
2108 val_to_str_const (type
, ext_addr_type
, "Reserved"),
2112 proto_item_append_text (tf
, " %d", rec_no
);
2113 if (rec_ofs
!= -1) {
2114 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
2117 proto_item_append_text (tf
, ", %sExtended Address Type: %s",
2118 val_to_str_const (addr_type
, addr_type_str
, ""),
2119 val_to_str_const (type
, ext_addr_type_short
, "Reserved"));
2121 proto_item_set_len (ef
, offset
- boffset
);
2126 /* Ref chapter 5.2.8.1 Extended Originator Encoding */
2127 static gint
dissect_dmp_originator (tvbuff_t
*tvb
, packet_info
*pinfo
,
2128 proto_tree
*envelope_tree
, gint offset
)
2130 proto_tree
*field_tree
= NULL
, *rec_tree
= NULL
;
2131 proto_item
*en
= NULL
, *tf
= NULL
;
2132 guint8 value
, dmp_addr_form
;
2133 gint boffset
= offset
;
2134 gboolean p2_addr
= FALSE
;
2136 tf
= proto_tree_add_item (envelope_tree
, hf_addr_originator
, tvb
, offset
, -1, ENC_NA
);
2137 field_tree
= proto_item_add_subtree (tf
, ett_address
);
2139 if (dmp
.addr_enc
== DIRECT_ADDR
) {
2140 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
,
2141 offset
, -1, -1, ORIGINATOR
);
2143 value
= tvb_get_guint8 (tvb
, offset
);
2144 dmp_addr_form
= (value
& 0xE0) >> 5;
2146 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2147 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form_orig_v1
, tvb
,
2150 val_to_str_const (dmp_addr_form
,
2151 addr_form_orig_v1
, "Reserved"));
2152 rec_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2153 proto_tree_add_item (rec_tree
, hf_addr_ext_form_orig_v1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2155 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form_orig
, tvb
,
2158 val_to_str_const (dmp_addr_form
,
2159 addr_form_orig
, "Reserved"));
2160 rec_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2161 proto_tree_add_item (rec_tree
, hf_addr_ext_form_orig
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2164 en
= proto_tree_add_item (rec_tree
, hf_reserved_0x1F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2166 expert_add_info(pinfo
, en
, &ei_reserved_value
);
2170 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2171 switch (dmp_addr_form
) {
2174 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2180 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2185 proto_item_append_text (tf
, " (invalid address form)");
2190 switch (dmp_addr_form
) {
2194 case P1_DIRECT_P2_EXTENDED
:
2195 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2201 case P1_EXTENDED_P2_DIRECT
:
2202 case P1_P2_EXTENDED
:
2203 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2208 proto_item_append_text (tf
, " (invalid address form)");
2213 switch (dmp_addr_form
) {
2216 case P1_EXTENDED_P2_DIRECT
:
2217 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
,
2223 case P1_DIRECT_P2_EXTENDED
:
2224 case P1_P2_EXTENDED
:
2225 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
, -1,
2226 -1, ORIG_P2_ADDRESS
);
2234 if (dmp
.msg_type
== NOTIF
) {
2235 en
= proto_tree_add_boolean (field_tree
, hf_addr_int_rec
, tvb
,
2238 en
= proto_tree_add_boolean (field_tree
, hf_addr_dl_expanded
, tvb
,
2241 PROTO_ITEM_SET_GENERATED (en
);
2244 proto_item_set_len (tf
, offset
- boffset
);
2249 static void dmp_add_recipient_info (proto_item
*tf
, guint8 rep_req
,
2250 guint8 not_req
, gboolean action
)
2252 if (rep_req
|| not_req
) {
2253 proto_item_append_text (tf
, ", Request:");
2256 proto_item_append_text (tf
, "%s",
2257 val_to_str_const (rep_req
, report_vals_short
, ""));
2260 dmp
.notif_req
= TRUE
;
2261 proto_item_append_text (tf
, "%s",
2262 val_to_str_const (not_req
, notif_vals_short
, ""));
2265 if (dmp
.msg_type
== STANAG
) {
2266 proto_item_append_text (tf
, " (Action)");
2267 } else if (dmp
.msg_type
== IPM
) {
2268 proto_item_append_text (tf
, " (To)");
2271 if (dmp
.msg_type
== STANAG
) {
2272 proto_item_append_text (tf
, " (Info)");
2273 } else if (dmp
.msg_type
== IPM
) {
2274 proto_item_append_text (tf
, " (Cc)");
2279 /* Ref chapter 5.2.7 Direct Recipient Encoding */
2280 static gint
dissect_dmp_direct_encoding (tvbuff_t
*tvb
, packet_info
*pinfo
,
2281 proto_tree
*field_tree
, proto_item
*tf
,
2282 gint offset
, guint
*prev_rec_no
)
2285 proto_tree
*addr_tree
= NULL
, *rec_tree
= NULL
;
2286 proto_item
*en
= NULL
;
2287 guint8 rep_req
= 0, not_req
= 0, value
;
2288 gint rec_no
, rec_ofs
= -1, dir_addr
;
2289 gboolean action
= FALSE
, dir_addr_extended
= FALSE
;
2291 value
= tvb_get_guint8 (tvb
, offset
);
2292 rec_no
= (value
& 0xF0) >> 4;
2293 rep_req
= (value
& 0x0C) >> 2;
2294 not_req
= (value
& 0x03);
2296 if (rep_req
== 0x03) {
2297 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_dir_rec_no1
,
2298 tvb
, offset
, 1, value
,
2299 "%d (offset from previous)",
2300 (value
& 0xF0) >> 4);
2302 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_dir_rec_no
,
2303 tvb
, offset
, 1, value
,
2304 "%d (offset from previous)",
2305 (value
& 0xF0) >> 4);
2307 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2308 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2309 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2310 proto_tree_add_item (rec_tree
, hf_addr_dir_not_req1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2313 value
= tvb_get_guint8 (tvb
, offset
);
2314 dir_addr
= (value
& 0x7F);
2315 action
= (value
& 0x80);
2316 if (not_req
== 0x03) {
2317 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_address1
,
2318 tvb
, offset
, 1, value
);
2320 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_address
,
2321 tvb
, offset
, 1, value
);
2323 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2324 proto_tree_add_item (addr_tree
, hf_addr_dir_action
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2325 proto_tree_add_item (addr_tree
, hf_addr_dir_address1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2328 if (rep_req
== 0x03) {
2329 /* Extended Recipient Number 1 */
2330 value
= tvb_get_guint8 (tvb
, offset
);
2331 rec_no
|= ((value
& 0x3F) << 4);
2333 rep_req
= (value
& 0xC0) >> 6;
2335 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_dir_rec_no2
,
2336 tvb
, offset
, 1, value
,
2337 "%d (offset from previous)",
2339 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2340 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2341 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2344 if (rep_req
== 0x03) {
2345 /* Extended Recipient Number 2 */
2346 value
= tvb_get_guint8 (tvb
, offset
);
2347 rec_no
|= ((value
& 0x1F) << 10);
2349 rep_req
= (value
& 0xC0) >> 6;
2351 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_dir_rec_no3
,
2352 tvb
, offset
, 1, value
,
2353 "%d (offset from previous)",
2355 rec_tree
= proto_item_add_subtree (en
, ett_address_rec_no
);
2356 proto_tree_add_item (rec_tree
, hf_addr_dir_rep_req3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2357 en
= proto_tree_add_item (rec_tree
, hf_reserved_0x20
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2359 expert_add_info(pinfo
, en
, &ei_reserved_value
);
2361 proto_tree_add_item (rec_tree
, hf_addr_dir_rec_no3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2366 if (not_req
== 0x03) {
2367 /* Extended Direct Address 1 */
2368 dir_addr_extended
= TRUE
;
2369 value
= tvb_get_guint8 (tvb
, offset
);
2370 dir_addr
|= ((value
& 0x3F) << 7);
2371 not_req
= (value
& 0xC0) >> 6;
2373 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_address2
, tvb
,
2375 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2376 proto_tree_add_item (addr_tree
, hf_addr_dir_not_req2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2377 proto_tree_add_item (addr_tree
, hf_addr_dir_address2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2380 if (not_req
== 0x03) {
2381 /* Extended Direct Address 2 */
2382 value
= tvb_get_guint8 (tvb
, offset
);
2383 dir_addr
|= ((value
& 0x3F) << 13);
2384 not_req
= (value
& 0xC0) >> 6;
2386 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_address3
, tvb
,
2388 addr_tree
= proto_item_add_subtree (en
, ett_address_direct
);
2389 proto_tree_add_item (addr_tree
, hf_addr_dir_not_req3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2390 proto_tree_add_item (addr_tree
, hf_addr_dir_address3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2395 rec_no
+= *prev_rec_no
;
2396 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2399 *prev_rec_no
= rec_no
;
2401 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_rec_no_generated
,
2402 tvb
, offset
, 0, rec_no
);
2403 if (rec_no
> 32767) {
2404 proto_item_append_text (en
, " (maximum 32767)");
2405 expert_add_info(pinfo
, en
, &ei_addr_dir_rec_no_generated
);
2407 PROTO_ITEM_SET_GENERATED (en
);
2409 if (dir_addr_extended
) {
2410 en
= proto_tree_add_uint(field_tree
, hf_addr_dir_address_generated
,
2411 tvb
, offset
, 0, dir_addr
);
2412 PROTO_ITEM_SET_GENERATED (en
);
2415 proto_item_append_text (tf
, " %d", rec_no
);
2416 if (rec_ofs
!= -1) {
2417 proto_item_append_text (tf
, " (offset from previous: %d)", rec_ofs
);
2420 proto_item_append_text (tf
, ", Direct Address: %d", dir_addr
);
2421 dmp_add_recipient_info (tf
, rep_req
, not_req
, action
);
2426 /* Ref 5.2.8.2 Extended Recipient Encoding */
2427 static gint
dissect_dmp_ext_encoding (tvbuff_t
*tvb
, packet_info
*pinfo
,
2428 proto_tree
*field_tree
,
2429 proto_item
*tf
, gint offset
,
2432 proto_tree
*addr_tree
= NULL
;
2433 proto_item
*en
= NULL
;
2434 guint8 rep_req
= 0, not_req
= 0;
2435 guint8 value
, dmp_addr_form
;
2436 gboolean action
= FALSE
;
2437 gint rec_no
, rec_ofs
= -1;
2439 value
= tvb_get_guint8 (tvb
, offset
);
2440 dmp_addr_form
= (value
& 0xE0) >> 5;
2441 action
= (value
& 0x10);
2442 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_form
, tvb
,
2445 val_to_str_const (dmp_addr_form
,
2446 addr_form
, "Reserved"));
2447 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_form
);
2448 proto_tree_add_item (addr_tree
, hf_addr_ext_form
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2450 en
= proto_tree_add_boolean_format (field_tree
, hf_addr_ext_action
, tvb
,
2451 offset
, 1, value
, "Action: %s",
2452 action
? "Yes" : "No");
2453 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_action
);
2454 proto_tree_add_item (addr_tree
, hf_addr_ext_action
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2456 rep_req
= (value
& 0x0C) >> 2;
2457 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_rep_req
, tvb
,
2459 "Report Request: %s",
2460 val_to_str_const ((value
& 0x0C) >> 2,
2461 report_vals
, "Reserved"));
2462 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rep_req
);
2463 proto_tree_add_item (addr_tree
, hf_addr_ext_rep_req
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2465 not_req
= (value
& 0x03);
2466 en
= proto_tree_add_uint_format (field_tree
, hf_addr_ext_not_req
, tvb
,
2468 "Notification Request: %s",
2469 val_to_str_const (value
& 0x03,
2470 notif_vals
, "Reserved"));
2471 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_not_req
);
2472 proto_tree_add_item (addr_tree
, hf_addr_ext_not_req
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2475 value
= tvb_get_guint8 (tvb
, offset
);
2476 rec_no
= (value
& 0x7F);
2478 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_ext_rec_no1
, tvb
,
2480 "%d (offset from previous)",
2482 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2483 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2484 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2488 value
= tvb_get_guint8 (tvb
, offset
);
2489 rec_no
|= (value
<< 7);
2491 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_ext_rec_no2
, tvb
,
2493 "%d (offset from previous)", value
);
2494 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2495 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2499 en
= proto_tree_add_uint_format_value(field_tree
, hf_addr_ext_rec_no
, tvb
,
2501 "%d (offset from previous)",
2503 addr_tree
= proto_item_add_subtree (en
, ett_address_ext_rec_no
);
2504 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_ext
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2505 proto_tree_add_item (addr_tree
, hf_addr_ext_rec_no1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2510 rec_no
+= *prev_rec_no
;
2511 if (dmp
.version
== DMP_VERSION_1
&& !(dmp
.prot_id
== PROT_NAT
&& dmp_nat_decode
== NAT_DECODE_THALES
)) {
2514 *prev_rec_no
= rec_no
;
2516 en
= proto_tree_add_uint(field_tree
, hf_addr_ext_rec_no_generated
,
2517 tvb
, offset
, 0, rec_no
);
2518 if (rec_no
> 32767) {
2519 proto_item_append_text (en
, " (maximum 32767)");
2520 expert_add_info(pinfo
, en
, &ei_addr_ext_rec_no_generated
);
2522 PROTO_ITEM_SET_GENERATED (en
);
2524 switch (dmp_addr_form
) {
2528 case P1_DIRECT_P2_EXTENDED
:
2529 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2530 rec_no
, rec_ofs
, P1_ADDRESS
);
2534 case P1_EXTENDED_P2_DIRECT
:
2535 case P1_P2_EXTENDED
:
2536 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2537 rec_no
, rec_ofs
, P1_ADDRESS
);
2542 switch (dmp_addr_form
) {
2546 case P1_EXTENDED_P2_DIRECT
:
2547 offset
= dissect_dmp_direct_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2548 rec_no
, rec_ofs
, P2_ADDRESS
);
2552 case P1_DIRECT_P2_EXTENDED
:
2553 case P1_P2_EXTENDED
:
2554 offset
= dissect_dmp_ext_addr (tvb
, pinfo
, field_tree
, tf
, offset
,
2555 rec_no
, rec_ofs
, P2_ADDRESS
);
2560 dmp_add_recipient_info (tf
, rep_req
, not_req
, action
);
2565 /* Ref chapter 5.2 Address encoding */
2566 static gint
dissect_dmp_address (tvbuff_t
*tvb
, packet_info
*pinfo
,
2567 proto_tree
*envelope_tree
,
2568 gint offset
, guint
*prev_rec_no
,
2569 gboolean reporting_name
)
2571 proto_tree
*field_tree
= NULL
;
2572 proto_item
*tf
= NULL
;
2573 gint boffset
= offset
;
2575 if (reporting_name
) {
2576 tf
= proto_tree_add_item (envelope_tree
, hf_addr_reporting_name
, tvb
, offset
, -1, ENC_NA
);
2578 tf
= proto_tree_add_none_format (envelope_tree
, hf_addr_recipient
, tvb
,
2579 offset
, -1, "Recipient Number");
2581 field_tree
= proto_item_add_subtree (tf
, ett_address
);
2583 if (dmp
.addr_enc
== DIRECT_ADDR
) {
2584 offset
= dissect_dmp_direct_encoding (tvb
, pinfo
, field_tree
, tf
,
2585 offset
, prev_rec_no
);
2587 offset
= dissect_dmp_ext_encoding (tvb
, pinfo
, field_tree
, tf
, offset
,
2591 proto_item_set_len (tf
, offset
- boffset
);
2596 /* Ref chapter 6.2.9 Acknowledgement */
2597 static gint
dissect_dmp_ack (tvbuff_t
*tvb
, packet_info
*pinfo
,
2598 proto_tree
*dmp_tree
, gint offset
)
2600 proto_tree
*ack_tree
= NULL
, *recip_tree
= NULL
;
2601 proto_item
*en
= NULL
, *rt
= NULL
;
2602 proto_item
*hidden_item
;
2603 guint prev_rec_no
= 0;
2604 gint rec_len
, rec_no
= 0;
2605 gint boffset
= offset
;
2607 en
= proto_tree_add_item (dmp_tree
, hf_ack
, tvb
, offset
, 4, ENC_NA
);
2608 ack_tree
= proto_item_add_subtree (en
, ett_ack
);
2610 dmp
.ack_reason
= tvb_get_guint8 (tvb
, offset
);
2611 proto_item_append_text (en
, ", Reason: %s",
2612 val_to_str_const (dmp
.ack_reason
, ack_reason
, "Reserved"));
2614 rt
= proto_tree_add_item (ack_tree
, hf_ack_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2615 if (dmp
.ack_reason
!= 0) {
2616 expert_add_info_format(pinfo
, rt
, &ei_ack_reason
, "ACK reason: %s", val_to_str_const (dmp
.ack_reason
, ack_reason
, "Reserved"));
2620 proto_tree_add_item (ack_tree
, hf_ack_diagnostic
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2623 /* Subject Message Identifier */
2624 dmp
.subj_id
= tvb_get_ntohs (tvb
, offset
);
2625 proto_tree_add_item (ack_tree
, hf_message_subj_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2626 hidden_item
= proto_tree_add_item (ack_tree
, hf_dmp_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2627 PROTO_ITEM_SET_HIDDEN (hidden_item
);
2630 if (use_seq_ack_analysis
) {
2631 register_dmp_id (pinfo
, dmp
.ack_reason
);
2634 if (dmp
.ack_rec_present
) {
2635 /* Recipient List */
2636 rec_len
= tvb_length (tvb
);
2640 if (offset
< rec_len
) {
2641 rt
= proto_tree_add_item (ack_tree
, hf_ack_recips
, tvb
, offset
, -1, ENC_NA
);
2642 recip_tree
= proto_item_add_subtree (rt
, ett_ack_recips
);
2643 while (offset
< rec_len
) {
2644 offset
= dissect_dmp_address (tvb
, pinfo
, recip_tree
, offset
,
2645 &prev_rec_no
, FALSE
);
2648 proto_item_append_text (rt
, ", No Recipients: %d", rec_no
);
2649 proto_item_set_len (rt
, offset
- boffset
- 4);
2650 proto_item_set_len (en
, offset
- boffset
);
2657 static gint
dissect_mts_identifier (tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
2658 gint offset
, gboolean subject
)
2660 proto_item
*hidden_item
;
2661 const gchar
*mts_id
;
2663 if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp_nat_decode
== NAT_DECODE_DMP
) {
2664 mts_id
= dissect_7bit_string (tvb
, offset
, dmp
.mts_id_length
);
2665 } else if (dmp_nat_decode
== NAT_DECODE_THALES
) {
2666 mts_id
= dissect_thales_mts_id (tvb
, offset
, dmp
.mts_id_length
);
2668 mts_id
= tvb_bytes_to_str (tvb
, offset
, dmp
.mts_id_length
);
2670 proto_item_append_text (dmp
.mts_id_item
, " (%zu bytes decompressed)", strlen (mts_id
));
2671 mts_id
= format_text (mts_id
, strlen (mts_id
));
2673 proto_tree_add_string (tree
, hf_message_subj_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2674 hidden_item
= proto_tree_add_string (tree
, hf_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2675 /* Read from hash, for analysis */
2676 dmp
.subj_id
= GPOINTER_TO_UINT (g_hash_table_lookup (dmp_long_id_hash_table
, mts_id
));
2678 proto_tree_add_string (tree
, hf_envelope_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2679 hidden_item
= proto_tree_add_string (tree
, hf_mts_id
, tvb
, offset
, dmp
.mts_id_length
, mts_id
);
2680 /* Insert into hash, for analysis */
2681 g_hash_table_insert (dmp_long_id_hash_table
, g_strdup (mts_id
), GUINT_TO_POINTER ((guint
)dmp
.msg_id
));
2683 PROTO_ITEM_SET_HIDDEN (hidden_item
);
2684 offset
+= dmp
.mts_id_length
;
2689 static gint
dissect_ipm_identifier (tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
,
2690 gint offset
, gboolean subject
)
2692 proto_tree
*field_tree
;
2693 proto_item
*tf
, *hidden_item
;
2694 const gchar
*ipm_id
;
2695 gint length
, modifier
, ipm_id_length
;
2697 length
= tvb_get_guint8 (tvb
, offset
);
2698 modifier
= (length
& 0xC0) >> 6;
2699 ipm_id_length
= length
& 0x3F;
2701 tf
= proto_tree_add_uint(tree
, hf_envelope_ipm_id_length
,
2702 tvb
, offset
, 1, ipm_id_length
);
2703 field_tree
= proto_item_add_subtree (tf
, ett_envelope_ipm_id_length
);
2704 if ((dmp
.msg_id_type
== NAT_MSG_ID
|| modifier
!= IPM_MODIFIER_X400
) && dmp_nat_decode
== NAT_DECODE_THALES
) {
2705 proto_tree_add_item (field_tree
, hf_thales_ipm_id_modifier
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2707 proto_tree_add_item (field_tree
, hf_envelope_ipm_id_modifier
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2709 proto_tree_add_item (field_tree
, hf_envelope_ipm_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2712 if (modifier
== IPM_MODIFIER_X400
|| dmp_nat_decode
== NAT_DECODE_DMP
) {
2713 ipm_id
= dissect_7bit_string (tvb
, offset
, ipm_id_length
);
2714 } else if (dmp_nat_decode
== NAT_DECODE_THALES
) {
2715 ipm_id
= dissect_thales_ipm_id (tvb
, offset
, ipm_id_length
, modifier
);
2717 ipm_id
= tvb_bytes_to_str (tvb
, offset
, ipm_id_length
);
2719 proto_item_append_text (tf
, " (%zu bytes decompressed)", strlen (ipm_id
));
2720 ipm_id
= format_text (ipm_id
, strlen (ipm_id
));
2722 proto_tree_add_string (tree
, hf_message_subj_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2723 hidden_item
= proto_tree_add_string (tree
, hf_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2724 /* Read from hash, for analysis */
2725 dmp
.subj_id
= GPOINTER_TO_UINT (g_hash_table_lookup (dmp_long_id_hash_table
, ipm_id
));
2727 proto_tree_add_string (tree
, hf_envelope_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2728 hidden_item
= proto_tree_add_string (tree
, hf_ipm_id
, tvb
, offset
, ipm_id_length
, ipm_id
);
2729 /* Insert into hash, for analysis */
2730 g_hash_table_insert (dmp_long_id_hash_table
, g_strdup (ipm_id
), GUINT_TO_POINTER ((guint
)dmp
.msg_id
));
2732 PROTO_ITEM_SET_HIDDEN (hidden_item
);
2733 offset
+= ipm_id_length
;
2738 /* Ref chapter 6.2.7 Envelope structure */
2739 static gint
dissect_dmp_envelope (tvbuff_t
*tvb
, packet_info
*pinfo
,
2740 proto_tree
*dmp_tree
, gint offset
)
2742 proto_tree
*envelope_tree
= NULL
;
2743 proto_tree
*field_tree
= NULL
;
2744 proto_item
*en
= NULL
, *tf
= NULL
, *vf
= NULL
;
2745 proto_item
*hidden_item
;
2746 guint8 envelope
, time_diff
;
2747 guint16 subm_time
, no_rec
, value16
;
2749 gchar
*env_flags
= NULL
;
2750 guint prev_rec_no
= 0;
2751 gint boffset
= offset
, i
;
2752 gboolean using_short_id
= FALSE
;
2754 en
= proto_tree_add_item (dmp_tree
, hf_envelope
, tvb
, offset
, 10, ENC_NA
);
2755 envelope_tree
= proto_item_add_subtree (en
, ett_envelope
);
2757 envelope
= tvb_get_guint8 (tvb
, offset
);
2758 dmp
.prot_id
= (envelope
& 0xF8) >> 3;
2759 dmp
.version
= (envelope
& 0x07) + 1;
2761 /* Protocol Version */
2762 tf
= proto_tree_add_uint(envelope_tree
, hf_envelope_version
,
2763 tvb
, offset
, 1, dmp
.version
);
2765 field_tree
= proto_item_add_subtree (tf
, ett_envelope_version
);
2766 vf
= proto_tree_add_item (field_tree
, hf_envelope_protocol_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2767 if (dmp
.prot_id
== PROT_NAT
) {
2768 proto_item_append_text (vf
, " (national version of DMP)");
2769 proto_item_append_text (tf
, " (national)");
2770 } else if (dmp
.prot_id
== PROT_DMP
) {
2771 proto_item_append_text (vf
, " (correct)");
2773 proto_item_append_text (vf
, " (incorrect, should be 0x1d)");
2775 vf
= proto_tree_add_item (field_tree
, hf_envelope_version_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2778 if (dmp
.version
> DMP_VERSION_2
) {
2779 /* Unsupported DMP Version */
2780 proto_item_append_text (vf
, " (unsupported)");
2781 proto_item_append_text (tf
, " (unsupported)");
2782 expert_add_info_format(pinfo
, vf
, &ei_envelope_version_value
, "Unsupported DMP Version: %d", dmp
.version
);
2786 envelope
= tvb_get_guint8 (tvb
, offset
);
2787 dmp
.addr_enc
= ((envelope
& 0x10) >> 4);
2788 dmp
.checksum
= ((envelope
& 0x08) >> 3);
2789 dmp
.msg_type
= (envelope
& 0x07);
2791 if (dmp
.msg_type
!= ACK
) {
2793 tf
= proto_tree_add_uint(envelope_tree
, hf_envelope_hop_count
,
2794 tvb
, offset
, 1, envelope
);
2795 field_tree
= proto_item_add_subtree (tf
, ett_envelope_hop_count
);
2796 proto_tree_add_item (field_tree
, hf_envelope_hop_count_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2798 if (dmp
.version
>= DMP_VERSION_2
) {
2799 /* Extensions Present */
2800 dmp
.extensions
= (envelope
& 0x80);
2801 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_extensions
,
2802 tvb
, offset
, 1, envelope
,
2804 (envelope
& 0x80) ? "Present" : "Absent");
2805 field_tree
= proto_item_add_subtree (tf
, ett_envelope_extensions
);
2806 proto_tree_add_item (field_tree
, hf_envelope_extensions
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2809 /* Recipient Present */
2810 dmp
.ack_rec_present
= (envelope
& 0x20);
2811 tf
= proto_tree_add_boolean_format (envelope_tree
,hf_envelope_rec_present
,
2812 tvb
, offset
, 1, envelope
,
2813 "Recipient Present: %s",
2814 (envelope
& 0x20) ? "Present" : "Absent");
2815 field_tree
= proto_item_add_subtree (tf
, ett_envelope_rec_present
);
2816 proto_tree_add_item (field_tree
, hf_envelope_rec_present
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2819 /* Address Encoding */
2820 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_addr_enc
,
2821 tvb
, offset
, 1, envelope
,
2822 "Address Encoding: %s",
2824 addr_enc
.true_string
:
2825 addr_enc
.false_string
);
2826 field_tree
= proto_item_add_subtree (tf
, ett_envelope_addr_enc
);
2827 proto_tree_add_item (field_tree
, hf_envelope_addr_enc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2829 /* Checksum Present */
2830 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_checksum
,
2831 tvb
, offset
, 1, envelope
,
2833 (envelope
& 0x08) ? "Used" : "Not used");
2834 field_tree
= proto_item_add_subtree (tf
, ett_envelope_checksum
);
2835 proto_tree_add_item (field_tree
, hf_envelope_checksum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2838 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_type
,
2839 tvb
, offset
, 1, envelope
,
2840 "Content Type: %s (%d)",
2841 val_to_str_const (envelope
& 0x07,
2842 type_vals
, "Unknown"),
2844 field_tree
= proto_item_add_subtree (tf
, ett_envelope_cont_type
);
2845 proto_tree_add_item (field_tree
, hf_envelope_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2847 proto_item_append_text (en
, ", Checksum %s", (envelope
>> 3) & 0x01 ? "Used" : "Not used");
2850 if (dmp
.msg_type
>= ACK
) {
2851 proto_item_set_len (en
, offset
- boffset
);
2855 if (dmp
.version
>= DMP_VERSION_2
) {
2856 envelope
= tvb_get_guint8 (tvb
, offset
);
2857 /* Extensions Present */
2858 tf
= proto_tree_add_boolean_format (envelope_tree
, hf_envelope_extensions
,
2859 tvb
, offset
, 1, envelope
,
2861 (envelope
& 0x80) ? "Present" : "Absent");
2862 field_tree
= proto_item_add_subtree (tf
, ett_envelope_extensions
);
2863 proto_tree_add_item (field_tree
, hf_envelope_extensions
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2864 dmp
.extensions
= (envelope
& 0x80);
2866 /* Message Identifier Type */
2867 dmp
.msg_id_type
= (envelope
& 0x60) >> 5;
2868 tf
= proto_tree_add_item (envelope_tree
, hf_envelope_msg_id_type
,
2869 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2870 field_tree
= proto_item_add_subtree (tf
, ett_envelope_msg_id_type
);
2871 proto_tree_add_item (field_tree
, hf_envelope_msg_id_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2873 if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) {
2874 /* MTS Identifier Length */
2875 dmp
.mts_id_length
= (envelope
& 0x1F);
2876 dmp
.mts_id_item
= proto_tree_add_item(envelope_tree
, hf_envelope_mts_id_length
,
2877 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2878 field_tree
= proto_item_add_subtree (dmp
.mts_id_item
, ett_envelope_mts_id_length
);
2879 proto_tree_add_item (field_tree
, hf_envelope_mts_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2882 proto_tree_add_item (field_tree
, hf_envelope_msg_id_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2883 if (envelope
& 0x10) {
2884 /* Using Short Identifier (12 bits) */
2885 using_short_id
= TRUE
;
2887 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x0F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2888 if (envelope
& 0x0F) {
2889 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
2896 /* Message Identifier */
2897 dmp
.msg_id
= tvb_get_ntohs (tvb
, offset
);
2898 if (using_short_id
) {
2899 dmp
.msg_id
&= 0x0FFF;
2901 tf
= proto_tree_add_uint (envelope_tree
, hf_envelope_msg_id
, tvb
, offset
, 2, dmp
.msg_id
);
2902 hidden_item
= proto_tree_add_uint (envelope_tree
, hf_dmp_id
, tvb
, offset
, 2, dmp
.msg_id
);
2903 if (using_short_id
) {
2904 field_tree
= proto_item_add_subtree (tf
, ett_envelope_msg_id
);
2905 proto_tree_add_item (field_tree
, hf_envelope_msg_id_12bit
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2906 } else if (dmp
.version
>= DMP_VERSION_2
&& dmp
.msg_id_type
== ONLY_DMP_ID
&& dmp
.msg_id
< 4096) {
2907 expert_add_info(pinfo
, tf
, &ei_envelope_msg_id
);
2909 PROTO_ITEM_SET_HIDDEN (hidden_item
);
2912 if (dmp
.version
>= DMP_VERSION_2
) {
2913 if ((dmp
.msg_type
!= REPORT
) && (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
)) {
2914 offset
= dissect_mts_identifier (tvb
, pinfo
, envelope_tree
, offset
, FALSE
);
2918 /* Submission Time */
2919 subm_time
= tvb_get_ntohs (tvb
, offset
);
2920 dmp
.subm_time
= dmp_dec_subm_time ((guint16
)(subm_time
& 0x7FFF),
2921 (gint32
) pinfo
->fd
->abs_ts
.secs
);
2922 tf
= proto_tree_add_uint_format_value(envelope_tree
, hf_envelope_subm_time
, tvb
,
2923 offset
, 2, subm_time
,
2925 (subm_time
& 0x7FFF) >= 0x7FF8 ?
2927 abs_time_secs_to_str (dmp
.subm_time
, ABSOLUTE_TIME_LOCAL
, TRUE
));
2928 field_tree
= proto_item_add_subtree (tf
, ett_envelope_subm_time
);
2929 proto_tree_add_item (field_tree
, hf_envelope_time_diff_present
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2930 proto_tree_add_item (field_tree
, hf_envelope_subm_time_value
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2933 if (subm_time
& 0x8000) {
2934 /* Timed Difference */
2935 time_diff
= tvb_get_guint8 (tvb
, offset
);
2936 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_time_diff
,
2937 tvb
, offset
, 1, time_diff
,
2938 "Time Difference: ");
2939 field_tree
= proto_item_add_subtree (tf
, ett_envelope_time_diff
);
2940 proto_tree_add_item (field_tree
, hf_envelope_time_diff_value
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2941 secs
= dmp_dec_time_diff (time_diff
);
2942 if (secs
== DMP_TIME_RESERVED
) {
2943 proto_item_append_text (tf
, "Reserved (0x%2.2x)", time_diff
);
2945 proto_item_append_text (tf
, "%s", time_secs_to_str (secs
));
2950 /* Envelope Flags */
2951 envelope
= tvb_get_guint8 (tvb
, offset
);
2952 tf
= proto_tree_add_uint_format (envelope_tree
, hf_envelope_flags
,
2953 tvb
, offset
, 1, envelope
,
2956 field_tree
= proto_item_add_subtree (tf
, ett_envelope_flags
);
2957 proto_tree_add_item (field_tree
, hf_envelope_content_id_discarded
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2958 proto_tree_add_item (field_tree
, hf_envelope_recip_reassign_prohib
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2959 proto_tree_add_item (field_tree
, hf_envelope_dl_expansion_prohib
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2961 if (envelope
& 0xE0) {
2962 env_flags
= wmem_strdup_printf (wmem_packet_scope(), "%s%s%s",
2963 (envelope
& 0x80) ? ", ContId discarded" : "",
2964 (envelope
& 0x40) ? ", Reass prohibited" : "",
2965 (envelope
& 0x20) ? ", DLE prohibited" : "");
2966 proto_item_append_text (tf
, ":%s", &env_flags
[1]);
2968 proto_item_append_text (tf
, " (none)");
2971 /* Recipient Count */
2972 no_rec
= (envelope
& 0x1F);
2973 tf
= proto_tree_add_uint(envelope_tree
, hf_envelope_recipients
,
2974 tvb
, offset
, 1, envelope
);
2976 field_tree
= proto_item_add_subtree (tf
, ett_envelope_recipients
);
2977 proto_tree_add_item (field_tree
, hf_envelope_recipients
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2981 /* Extended Recipient Count */
2982 value16
= tvb_get_ntohs (tvb
, offset
);
2983 no_rec
= value16
& 0x7FFF;
2984 tf
= proto_tree_add_uint_format_value(envelope_tree
,hf_envelope_ext_recipients
,
2985 tvb
, offset
, 2, value16
,
2988 " (incorrect, reserved value)" : ""));
2990 field_tree
= proto_item_add_subtree (tf
, ett_envelope_ext_recipients
);
2991 en
= proto_tree_add_item (field_tree
, hf_reserved_0x8000
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2992 if (value16
& 0x8000) {
2993 expert_add_info(pinfo
, en
, &ei_reserved_value
);
2995 proto_tree_add_item (field_tree
, hf_envelope_ext_recipients
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2999 if (dmp
.msg_type
!= REPORT
) {
3000 /* Originator - Not present for reports */
3001 offset
= dissect_dmp_originator (tvb
, pinfo
, envelope_tree
, offset
);
3004 for (i
= 0; i
< no_rec
; i
++) {
3006 offset
= dissect_dmp_address (tvb
, pinfo
, envelope_tree
, offset
,
3007 &prev_rec_no
, FALSE
);
3010 if (dmp
.version
>= DMP_VERSION_2
) {
3011 if ((dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) &&
3012 dmp
.notif_req
&& (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
))
3014 offset
= dissect_ipm_identifier (tvb
, pinfo
, envelope_tree
, offset
, FALSE
);
3018 proto_item_set_len (en
, offset
- boffset
);
3023 static void dissect_dmp_structured_id (tvbuff_t
*tvb
, proto_tree
*body_tree
,
3028 offset
+= dmp_struct_offset
;
3029 switch (dmp_struct_format
) {
3031 case STRUCT_ID_UINT8
:
3032 dmp
.struct_id
= wmem_strdup_printf (wmem_packet_scope(), "%u", tvb_get_guint8 (tvb
, offset
));
3033 proto_tree_add_item (body_tree
, hf_message_bodyid_uint8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3036 case STRUCT_ID_UINT16
:
3037 dmp
.struct_id
= wmem_strdup_printf (wmem_packet_scope(), "%u", tvb_get_ntohs (tvb
, offset
));
3038 proto_tree_add_item (body_tree
, hf_message_bodyid_uint16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3041 case STRUCT_ID_UINT32
:
3042 dmp
.struct_id
= wmem_strdup_printf (wmem_packet_scope(), "%u", tvb_get_ntohl (tvb
, offset
));
3043 proto_tree_add_item (body_tree
, hf_message_bodyid_uint32
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3046 case STRUCT_ID_UINT64
:
3047 dmp
.struct_id
= wmem_strdup_printf (wmem_packet_scope(), "%" G_GINT64_MODIFIER
"u", tvb_get_ntoh64 (tvb
, offset
));
3048 proto_tree_add_item (body_tree
, hf_message_bodyid_uint64
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
3051 case STRUCT_ID_STRING
:
3052 dmp
.struct_id
= tvb_get_string (wmem_packet_scope(), tvb
, offset
, (gint
) dmp_struct_length
);
3053 proto_tree_add_item (body_tree
, hf_message_bodyid_string
, tvb
, offset
, dmp_struct_length
, ENC_ASCII
|ENC_NA
);
3056 case STRUCT_ID_ZSTRING
:
3057 dmp
.struct_id
= tvb_get_stringz (wmem_packet_scope(), tvb
, offset
, &length
);
3058 proto_tree_add_item (body_tree
, hf_message_bodyid_zstring
, tvb
, offset
, length
, ENC_ASCII
|ENC_NA
);
3065 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3066 * and chapter 6.3.8.1 IPM 88 message structure
3068 static gint
dissect_dmp_message (tvbuff_t
*tvb
, packet_info
*pinfo
,
3069 proto_tree
*dmp_tree
, gint offset
)
3071 tvbuff_t
*next_tvb
= NULL
;
3072 proto_tree
*message_tree
= NULL
;
3073 proto_tree
*field_tree
= NULL
;
3074 proto_item
*en
= NULL
, *tf
= NULL
, *tr
= NULL
;
3075 guint8 message
, eit
= 0, compr_alg
= ALGORITHM_NONE
;
3076 gint len
, boffset
= offset
;
3078 en
= proto_tree_add_item (dmp_tree
, hf_message_body
, tvb
, offset
, -1, ENC_NA
);
3079 message_tree
= proto_item_add_subtree (en
, ett_message
);
3081 if (dmp
.body_format
== FREE_TEXT_SUBJECT
) {
3082 len
= tvb_strsize (tvb
, offset
);
3083 if (dmp_subject_as_id
) {
3084 dmp
.struct_id
= tvb_get_string (wmem_packet_scope(), tvb
, offset
, len
);
3086 proto_tree_add_item (message_tree
, hf_message_subject
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3090 if (dmp
.body_format
== FREE_TEXT
|| dmp
.body_format
== FREE_TEXT_SUBJECT
) {
3091 message
= tvb_get_guint8 (tvb
, offset
);
3092 eit
= (message
& 0xE0) >> 5;
3093 compr_alg
= (message
& 0x18) >> 3;
3094 /* Encoded Information Type */
3095 tf
= proto_tree_add_item (message_tree
, hf_message_eit
,
3096 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3097 field_tree
= proto_item_add_subtree (tf
, ett_message_eit
);
3098 proto_tree_add_item (field_tree
, hf_message_eit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3099 proto_item_append_text (en
, ", Type: %s",
3100 val_to_str_const (eit
, eit_vals
, "Unknown"));
3102 /* Compression Algorithm */
3103 tf
= proto_tree_add_item (message_tree
, hf_message_compr
,
3104 tvb
, offset
, 1,ENC_BIG_ENDIAN
);
3105 field_tree
= proto_item_add_subtree (tf
, ett_message_compr
);
3106 tr
= proto_tree_add_item (field_tree
, hf_message_compr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3107 if (compr_alg
== ALGORITHM_ZLIB
) {
3108 proto_item_append_text (en
, " (compressed)");
3109 } else if (compr_alg
!= ALGORITHM_NONE
) {
3110 expert_add_info(pinfo
, tr
, &ei_message_compr
);
3113 if (message
& 0x07) {
3115 tf
= proto_tree_add_item(message_tree
, hf_reserved_0x07
,
3116 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3117 field_tree
= proto_item_add_subtree (tf
, ett_message_body_reserved
);
3118 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x07
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3119 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3124 len
= tvb_length_remaining (tvb
, offset
);
3129 tf
= proto_tree_add_none_format (message_tree
, hf_message_body_data
, tvb
,
3131 "%sUser data, Length: %d",
3132 (compr_alg
== ALGORITHM_ZLIB
) ?
3133 "Compressed " : "", len
);
3134 field_tree
= proto_item_add_subtree (tf
, ett_message_body
);
3136 if (dmp
.body_format
== STRUCTURED
) {
3137 /* Structured Message ID */
3138 dissect_dmp_structured_id (tvb
, field_tree
, offset
);
3139 proto_tree_add_item (field_tree
, hf_message_body_structured
, tvb
, offset
, len
, ENC_NA
);
3140 } else if (len
> 0 && (dmp
.body_format
== FREE_TEXT
||
3141 dmp
.body_format
== FREE_TEXT_SUBJECT
)) {
3142 if (compr_alg
== ALGORITHM_ZLIB
) {
3143 if ((next_tvb
= tvb_child_uncompress (tvb
, tvb
, offset
, len
)) != NULL
) {
3144 gint zlen
= tvb_length (next_tvb
);
3145 add_new_data_source (pinfo
, next_tvb
, "Uncompressed User data");
3146 tf
= proto_tree_add_none_format (message_tree
,
3147 hf_message_body_uncompr
,
3149 "Uncompressed User data, "
3150 "Length: %d", zlen
);
3151 field_tree
= proto_item_add_subtree (tf
, ett_message_body_uncompr
);
3152 proto_tree_add_item (field_tree
, hf_message_body_uncompressed
, next_tvb
, 0, -1, ENC_ASCII
|ENC_NA
);
3154 proto_tree_add_expert(message_tree
, pinfo
, &ei_message_body_uncompressed
, tvb
, offset
, -1);
3156 } else if (eit
!= EIT_BILATERAL
) {
3157 proto_tree_add_item (field_tree
, hf_message_body_plain
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3162 if (dmp
.struct_id
) {
3163 proto_item_append_text (en
, ", Id: %s", format_text (dmp
.struct_id
, strlen (dmp
.struct_id
)));
3166 proto_item_set_len (en
, offset
- boffset
);
3171 /* Ref chapter 6.3.9.1 Report structure */
3172 static gint
dissect_dmp_report (tvbuff_t
*tvb
, packet_info
*pinfo
,
3173 proto_tree
*dmp_tree
, gint offset
,
3174 guint
*prev_rec_no
, gint num
)
3176 proto_tree
*report_tree
= NULL
;
3177 proto_tree
*field_tree
= NULL
;
3178 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3180 gboolean info_present
;
3182 gint len
, boffset
= offset
;
3185 report
= tvb_get_guint8 (tvb
, offset
);
3186 rep_type
= (report
& 0x80) >> 7;
3188 en
= proto_tree_add_item (dmp_tree
, hf_non_delivery_report
, tvb
, offset
, 4, ENC_NA
);
3190 en
= proto_tree_add_item (dmp_tree
, hf_delivery_report
, tvb
, offset
, 4, ENC_NA
);
3192 proto_item_append_text (en
, " (#%d)", num
);
3194 report_tree
= proto_item_add_subtree (en
, ett_report
);
3197 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_type
,
3198 tvb
, offset
, 1, report
,
3199 "Report Type: %s", rep_type
?
3200 report_type
.true_string
:
3201 report_type
.false_string
);
3202 field_tree
= proto_item_add_subtree (tf
, ett_report_type
);
3203 proto_tree_add_item (field_tree
, hf_report_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3205 if (rep_type
== DR
) {
3208 info_present
= (report
& 0x40);
3209 tf
= proto_tree_add_boolean_format (report_tree
,hf_report_info_present_dr
,
3210 tvb
, offset
, 1, report
,
3211 "Info Present: %s", (report
& 0x40) ? "Present" : "Absent");
3212 field_tree
= proto_item_add_subtree (tf
, ett_report_info_present_dr
);
3213 proto_tree_add_item (field_tree
, hf_report_info_present_dr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3215 /* Address Encoding */
3216 dmp
.addr_enc
= ((report
& 0x20) >> 5);
3217 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_addr_enc_dr
,
3218 tvb
, offset
, 1, report
,
3219 "Address Encoding: %s",
3221 addr_enc
.true_string
:
3222 addr_enc
.false_string
);
3223 field_tree
= proto_item_add_subtree (tf
, ett_report_addr_enc_dr
);
3224 proto_tree_add_item (field_tree
, hf_report_addr_enc_dr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3226 if (report
& 0x1F) {
3228 tf
= proto_tree_add_item(report_tree
, hf_reserved_0x1F
,
3229 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3230 field_tree
= proto_item_add_subtree (tf
, ett_report_reserved
);
3231 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x1F
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3232 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3238 report
= tvb_get_guint8 (tvb
, offset
);
3239 tf
= proto_tree_add_uint_format (report_tree
, hf_report_del_time
,
3240 tvb
, offset
, 1, report
,
3242 field_tree
= proto_item_add_subtree (tf
, ett_report_del_time
);
3243 ei
= proto_tree_add_item (field_tree
, hf_report_del_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3244 secs
= dmp_dec_del_time (report
);
3245 if (secs
== DMP_TIME_RESERVED
) {
3246 proto_item_append_text (tf
, "Reserved (0x%2.2x)", report
);
3247 proto_item_append_text (ei
, " (Reserved)");
3249 proto_item_append_text (tf
, "%s (%s)", time_secs_to_str (secs
),
3250 abs_time_secs_to_str (dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, TRUE
));
3251 proto_item_append_text (ei
, " (%s from submission time)", time_secs_to_str (secs
));
3255 /* Address Encoding */
3256 dmp
.addr_enc
= ((report
& 0x40) >> 6);
3257 tf
= proto_tree_add_boolean_format (report_tree
, hf_report_addr_enc_ndr
,
3258 tvb
, offset
, 1, report
,
3259 "Address Encoding: %s",
3261 addr_enc
.true_string
:
3262 addr_enc
.false_string
);
3263 field_tree
= proto_item_add_subtree (tf
, ett_report_addr_enc_ndr
);
3264 proto_tree_add_item (field_tree
, hf_report_addr_enc_ndr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3267 tf
= proto_tree_add_uint_format (report_tree
, hf_report_reason
,
3268 tvb
, offset
, 1, report
,
3269 "Reason%s: %s (%d)",
3270 ((report
& 0x3F) < 0x3D) ? " (P1)":"",
3271 non_del_reason_str (report
& 0x3F),
3273 field_tree
= proto_item_add_subtree (tf
, ett_report_reason
);
3274 proto_tree_add_item (field_tree
, hf_report_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3278 report
= tvb_get_guint8 (tvb
, offset
);
3279 info_present
= (report
& 0x80);
3280 tf
= proto_tree_add_boolean_format (report_tree
,
3281 hf_report_info_present_ndr
,
3282 tvb
, offset
, 1, report
,
3283 "Info Present: %s", (report
& 0x80) ? "Present" : "Absent");
3284 field_tree
= proto_item_add_subtree (tf
, ett_report_info_present_ndr
);
3285 proto_tree_add_item (field_tree
, hf_report_info_present_ndr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3288 tf
= proto_tree_add_uint_format (report_tree
, hf_report_diagn
,
3289 tvb
, offset
, 1, report
,
3290 "Diagnostic%s: %s (%d)",
3291 ((report
& 0x7F) < 0x7C) ? " (P1)":"",
3292 non_del_diagn_str (report
& 0x7F),
3294 field_tree
= proto_item_add_subtree (tf
, ett_report_diagn
);
3295 proto_tree_add_item (field_tree
, hf_report_diagn
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3299 offset
= dissect_dmp_address (tvb
, pinfo
, report_tree
, offset
,
3303 /* Supplementary Information */
3304 len
= tvb_strsize (tvb
, offset
);
3305 tf
= proto_tree_add_uint_format (report_tree
, hf_report_suppl_info_len
,
3306 tvb
, offset
, len
, len
,
3307 "Supplementary Information, Length: %d",
3310 if ((offset
- boffset
+ len
) > 128) {
3311 proto_item_append_text (tf
, " (incorrect, should be less than %d)",
3312 128 - (offset
- boffset
));
3314 field_tree
= proto_item_add_subtree (tf
, ett_report_suppl_info
);
3315 proto_tree_add_item (field_tree
, hf_report_suppl_info
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3320 proto_item_set_len (en
, offset
- boffset
);
3325 /* Ref chapter 6.3.10.1 Notification structure */
3326 static gint
dissect_dmp_notification (tvbuff_t
*tvb
, packet_info
*pinfo _U_
,
3327 proto_tree
*dmp_tree
, gint offset
)
3329 proto_tree
*notif_tree
= NULL
;
3330 proto_tree
*field_tree
= NULL
;
3331 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3332 guint8 notif
, rec_time
, on_typex
= 0xFF;
3333 gint len
, boffset
= offset
;
3336 if (dmp
.notif_type
== RN
) {
3337 en
= proto_tree_add_item (dmp_tree
, hf_receipt_notif
, tvb
, offset
, 4, ENC_NA
);
3338 } else if (dmp
.notif_type
== NRN
) {
3339 en
= proto_tree_add_item (dmp_tree
, hf_non_receipt_notif
, tvb
, offset
, 4, ENC_NA
);
3340 } else if (dmp
.notif_type
== ON
) {
3341 en
= proto_tree_add_item (dmp_tree
, hf_other_notif
, tvb
, offset
, 4, ENC_NA
);
3345 notif_tree
= proto_item_add_subtree (en
, ett_notif
);
3347 if (dmp
.notif_type
== RN
|| dmp
.notif_type
== ON
) {
3349 rec_time
= tvb_get_guint8 (tvb
, offset
);
3350 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_rec_time
,
3351 tvb
, offset
, 1, rec_time
,
3353 field_tree
= proto_item_add_subtree (tf
, ett_notif_rec_time
);
3354 ei
= proto_tree_add_item (field_tree
, hf_notif_rec_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3355 secs
= dmp_dec_exp_time (rec_time
);
3356 if (secs
== DMP_TIME_NOT_PRESENT
) {
3357 proto_item_append_text (tf
, "Not present");
3358 proto_item_append_text (ei
, " (not present)");
3359 } else if (secs
== DMP_TIME_RESERVED
) {
3360 proto_item_append_text (tf
, "Reserved (0x%2.2x)", rec_time
);
3361 proto_item_append_text (ei
, " (Reserved)");
3363 proto_item_append_text (tf
, "%s (%s)", time_secs_to_str (secs
),
3364 abs_time_secs_to_str (dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, TRUE
));
3365 proto_item_append_text (ei
, " (%s from submission time)", time_secs_to_str (secs
));
3369 if (dmp
.notif_type
== ON
) {
3371 on_typex
= tvb_get_guint8 (tvb
, offset
);
3372 proto_tree_add_item (notif_tree
, hf_notif_on_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3376 /* Supplementary Information */
3377 len
= tvb_strsize (tvb
, offset
);
3378 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_suppl_info_len
,
3379 tvb
, offset
, len
, len
,
3380 "Supplementary Information, Length: %d",
3383 if ((offset
- boffset
+ len
) > 128) {
3384 proto_item_append_text (tf
, " (incorrect, should be less than %d)",
3385 128 - (offset
- boffset
));
3387 field_tree
= proto_item_add_subtree (tf
, ett_notif_suppl_info
);
3388 proto_tree_add_item (field_tree
, hf_notif_suppl_info
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3392 if ((dmp
.notif_type
== ON
) && (on_typex
< 0x03)) {
3393 /* ACP127 Receipient */
3394 len
= tvb_strsize (tvb
, offset
);
3395 tf
= proto_tree_add_uint_format (notif_tree
, hf_notif_acp127
,
3396 tvb
, offset
, len
, len
,
3397 "ACP127 Recipient, Length: %d",
3401 proto_item_append_text (tf
, " (incorrect, must be less than 64)");
3403 field_tree
= proto_item_add_subtree (tf
, ett_notif_acp127recip
);
3404 proto_tree_add_item (field_tree
, hf_notif_acp127recip
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3408 } else if (dmp
.notif_type
== NRN
) {
3409 /* Non-Recipient Reason */
3410 notif
= tvb_get_guint8 (tvb
, offset
);
3411 proto_tree_add_uint_format (notif_tree
, hf_notif_non_rec_reason
,
3412 tvb
, offset
, 1, notif
,
3413 "Non-Receipt Reason%s: %s (%d)",
3414 (notif
< 0x10) ? " (P22)" : "",
3415 nrn_reason_str (notif
), notif
);
3418 /* Discard Reason */
3419 notif
= tvb_get_guint8 (tvb
, offset
);
3420 proto_tree_add_uint_format (notif_tree
, hf_notif_discard_reason
,
3421 tvb
, offset
, 1, notif
,
3422 "Discard Reason%s: %s (%d)",
3423 (notif
< 0x10) ? " (P22)" : "",
3424 discard_reason_str (notif
), notif
);
3428 proto_item_set_len (en
, offset
- boffset
);
3433 /* Ref chapter 6.2.1.2.8 SecurityCategories */
3434 static gint
dissect_dmp_security_category (tvbuff_t
*tvb
, packet_info
*pinfo
,
3436 const gchar
**label_string
,
3437 gint offset
, guint8 ext
)
3439 proto_tree
*field_tree
= NULL
;
3440 proto_item
*tf
= NULL
, *tr
= NULL
;
3441 gchar
*sec_cat
= NULL
;
3443 gboolean country_code
= FALSE
;
3445 message
= tvb_get_guint8 (tvb
, offset
);
3446 tf
= proto_tree_add_uint_format (tree
, hf_message_sec_cat_nat
, tvb
,
3447 offset
, 1, message
, "Security Categories");
3448 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_cat
);
3452 case SEC_CAT_EXT_NONE
:
3453 proto_tree_add_item (field_tree
, hf_message_sec_cat_cl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3454 proto_tree_add_item (field_tree
, hf_message_sec_cat_cs
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3455 proto_tree_add_item (field_tree
, hf_message_sec_cat_ex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3456 proto_tree_add_item (field_tree
, hf_message_sec_cat_ne
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3458 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x08
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3459 if (message
& 0x08) {
3460 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3462 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x04
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3463 if (message
& 0x04) {
3464 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3467 if (message
& 0xF0) {
3468 sec_cat
= wmem_strdup_printf (wmem_packet_scope(), "%s%s%s%s",
3469 (message
& 0x80) ? ",cl" : "",
3470 (message
& 0x40) ? ",cs" : "",
3471 (message
& 0x20) ? ",ex" : "",
3472 (message
& 0x10) ? ",ne" : "");
3473 proto_item_append_text (tf
, ": %s", &sec_cat
[1]);
3474 *label_string
= wmem_strconcat(wmem_packet_scope(), *label_string
, sec_cat
, NULL
);
3478 case SEC_CAT_EXT_PERMISSIVE
:
3479 if ((message
>> 2) == 0x3F) {
3480 /* Fake entry because nat_pol_id defines 0x3F as reserved */
3481 proto_tree_add_uint_format (field_tree
, hf_message_sec_cat_permissive
, tvb
, offset
, 1,
3482 message
, "1111 11.. = Next byte has Country Code (0x3F)");
3483 country_code
= TRUE
;
3485 tr
= proto_tree_add_item (field_tree
, hf_message_sec_cat_permissive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3486 proto_item_append_text (tf
, ": rel-to-%s", get_nat_pol_id_short (message
>> 2));
3487 *label_string
= wmem_strdup_printf(wmem_packet_scope(), "%s,rel-to-%s", *label_string
, get_nat_pol_id_short (message
>> 2));
3488 if ((message
>> 2) == 0) {
3489 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3494 case SEC_CAT_EXT_RESTRICTIVE
:
3495 proto_tree_add_item (field_tree
, hf_message_sec_cat_restrictive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3496 proto_item_append_text (tf
, " (restrictive: 0x%2.2x)", message
>> 2);
3503 proto_item_append_text (tf
, " (0x%2.2x)", message
);
3505 if (dmp
.version
== 1) {
3506 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x02
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3507 if (message
& 0x02) {
3508 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3510 tr
= proto_tree_add_item (field_tree
, hf_reserved_0x01
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3511 if (message
& 0x01) {
3512 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3515 tr
= proto_tree_add_item (field_tree
, hf_message_sec_cat_extended
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3516 if ((message
& 0x01) && (message
& 0x02)) {
3517 expert_add_info(pinfo
, tr
, &ei_reserved_value
);
3518 } else if (message
& 0x01 || message
& 0x02) {
3519 proto_item_append_text (tf
, " (extended)");
3520 offset
= dissect_dmp_security_category (tvb
, pinfo
, tree
, label_string
, offset
+1, message
& 0x03);
3524 proto_tree_add_item (field_tree
, hf_message_sec_cat_country_code
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
3525 proto_item_append_text (tf
, " (rel-to country-code: %d)", tvb_get_guint8 (tvb
, offset
+1));
3526 proto_item_set_len (tf
, 2);
3535 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3536 * and chapter 6.3.8.1 IPM 88 message structure
3537 * and chapter 6.3.9.1 Report structure
3538 * and chapter 6.3.10.1 Notification structure
3540 static gint
dissect_dmp_content (tvbuff_t
*tvb
, packet_info
*pinfo
,
3541 proto_tree
*dmp_tree
, gint offset
)
3543 proto_tree
*message_tree
= NULL
;
3544 proto_tree
*field_tree
= NULL
;
3545 proto_item
*en
= NULL
, *ei
= NULL
, *tf
= NULL
;
3546 proto_item
*hidden_item
;
3547 const char *label_string
= wmem_strdup (wmem_packet_scope(), "");
3548 const gchar
*class_name
= NULL
;
3549 guint8 message
, dmp_sec_pol
, dmp_sec_class
, dmp_nation
= 0, exp_time
, dtg
;
3551 guint prev_rec_no
= 0;
3552 gint rep_len
, rep_no
= 1;
3553 gint loffset
, boffset
= offset
;
3555 if (dmp
.msg_type
== REPORT
) {
3556 en
= proto_tree_add_item (dmp_tree
, hf_report_content
, tvb
, offset
, 7, ENC_NA
);
3557 } else if (dmp
.msg_type
== NOTIF
) {
3558 en
= proto_tree_add_item (dmp_tree
, hf_notif_content
, tvb
, offset
, 7, ENC_NA
);
3560 en
= proto_tree_add_item (dmp_tree
, hf_message_content
, tvb
, offset
, 7, ENC_NA
);
3562 message_tree
= proto_item_add_subtree (en
, ett_content
);
3564 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3565 message
= tvb_get_guint8 (tvb
, offset
);
3566 dmp
.body_format
= (message
& 0x03);
3568 if (dmp
.msg_type
== STANAG
) {
3570 dmp
.st_type
= (message
& 0xC0) >> 6;
3571 tf
= proto_tree_add_uint_format (message_tree
, hf_message_st_type
,
3572 tvb
, offset
, 1, message
,
3573 "Message Type: %s (%d)",
3574 val_to_str_const (dmp
.st_type
,
3575 message_type_vals
, ""),
3577 field_tree
= proto_item_add_subtree (tf
, ett_message_st_type
);
3578 proto_tree_add_item (field_tree
, hf_message_st_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3580 if ((message
& 0x20) >> 5) {
3582 tf
= proto_tree_add_item(message_tree
, hf_reserved_0x20
,
3583 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3584 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3585 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x20
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3586 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3590 dmp
.prec
= (message
& 0x1C) >> 2;
3591 tf
= proto_tree_add_item(message_tree
, hf_message_precedence
,
3592 tvb
, offset
, 1,ENC_BIG_ENDIAN
);
3593 field_tree
= proto_item_add_subtree (tf
, ett_message_precedence
);
3594 proto_tree_add_item (field_tree
, hf_message_precedence
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3597 if ((message
& 0xE0) >> 5) {
3599 tf
= proto_tree_add_item(message_tree
, hf_reserved_0xE0
,
3600 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3601 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3602 tf
= proto_tree_add_item (field_tree
, hf_reserved_0xE0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3603 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3607 dmp
.prec
= (message
& 0x1C) >> 2;
3608 tf
= proto_tree_add_item(message_tree
, hf_message_importance
,
3609 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3610 field_tree
= proto_item_add_subtree (tf
, ett_message_importance
);
3611 proto_tree_add_item (field_tree
, hf_message_importance
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3615 tf
= proto_tree_add_uint_format (message_tree
, hf_message_body_format
,
3616 tvb
, offset
, 1, message
,
3617 "Body Format: %s (%d)",
3618 val_to_str_const (message
& 0x03,
3619 body_format_vals
, ""),
3621 field_tree
= proto_item_add_subtree (tf
, ett_message_body_format
);
3622 proto_tree_add_item (field_tree
, hf_message_body_format
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3626 message
= tvb_get_guint8 (tvb
, offset
);
3627 /* Security Classification */
3628 dmp_sec_class
= (message
& 0xE0) >> 5;
3629 dmp_sec_pol
= (message
& 0x1C) >> 2;
3630 if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3631 dmp_nation
= tvb_get_guint8 (tvb
, offset
+ 1);
3634 loffset
= offset
; /* Offset to start of security label */
3635 if (dmp_sec_pol
== NATIONAL
&& dmp_local_nation
!= 0) {
3636 class_name
= dmp_national_sec_class (dmp_local_nation
, dmp_sec_class
);
3637 } else if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3638 class_name
= dmp_national_sec_class (dmp_nation
, dmp_sec_class
);
3640 if ((dmp_sec_pol
== NATO
|| dmp_sec_pol
== NATIONAL
) && !class_name
) {
3641 class_name
= val_to_str_const (dmp_sec_class
, sec_class
, "");
3643 if (class_name
&& class_name
[0]) {
3644 tf
= proto_tree_add_uint_format_value(message_tree
, hf_message_sec_class_val
,
3645 tvb
, offset
, 1, message
,
3647 class_name
, dmp_sec_class
);
3649 tf
= proto_tree_add_uint_format_value(message_tree
, hf_message_sec_class_val
,
3650 tvb
, offset
, 1, message
,
3654 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_class
);
3655 tf
= proto_tree_add_item (field_tree
, hf_message_sec_class_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3657 proto_item_append_text (tf
, " (%s)", class_name
);
3658 label_string
= wmem_strconcat(wmem_packet_scope(), label_string
, class_name
, NULL
);
3661 /* Security Policy */
3662 tf
= proto_tree_add_uint_format (message_tree
, hf_message_sec_pol
,
3663 tvb
, offset
, 1, message
,
3664 "Security Policy: %s (%d)",
3665 val_to_str (dmp_sec_pol
, sec_pol
, "%d"),
3667 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_pol
);
3668 proto_tree_add_item (field_tree
, hf_message_sec_pol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3670 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3672 tf
= proto_tree_add_item (message_tree
, hf_message_heading_flags
, tvb
, offset
, 1, ENC_NA
);
3673 field_tree
= proto_item_add_subtree (tf
, ett_message_heading_flags
);
3674 proto_tree_add_item (field_tree
, hf_message_auth_users
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3675 proto_tree_add_item (field_tree
, hf_message_subject_disc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3676 if (message
& 0x03) {
3677 proto_item_append_text (tf
, ": %s%s%s discarded",
3678 (message
& 0x02) ? "Authorizing users" : "",
3679 (message
& 0x03) == 0x03 ? " and " : "",
3680 (message
& 0x01) ? "Subject" : "");
3682 proto_item_append_text (tf
, " (none)");
3684 } else if (dmp
.msg_type
== NOTIF
) {
3685 /* Notification Type */
3686 dmp
.notif_type
= (message
& 0x03);
3687 tf
= proto_tree_add_uint_format (message_tree
, hf_notif_type
,
3688 tvb
, offset
, 1, message
,
3689 "Notification Type: %s",
3690 val_to_str_const (dmp
.notif_type
, notif_type
,
3692 field_tree
= proto_item_add_subtree (tf
, ett_notif_type
);
3693 proto_tree_add_item (field_tree
, hf_notif_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3694 } else if (message
& 0x02) {
3696 tf
= proto_tree_add_item(message_tree
, hf_reserved_0x02
,
3697 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3698 field_tree
= proto_item_add_subtree (tf
, ett_message_reserved
);
3699 tf
= proto_tree_add_item (field_tree
, hf_reserved_0x02
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3700 expert_add_info(pinfo
, tf
, &ei_reserved_value
);
3704 if (dmp_sec_pol
== NATIONAL
&& dmp_local_nation
!= 0) {
3705 /* Show configured national policy */
3706 tf
= proto_tree_add_uint (message_tree
, hf_message_national_policy_id
,
3707 tvb
, offset
, 0, dmp_local_nation
);
3708 PROTO_ITEM_SET_GENERATED (tf
);
3709 } else if (dmp_sec_pol
== EXTENDED_NATIONAL
) {
3710 /* National Policy Identifier */
3711 proto_tree_add_item (message_tree
, hf_message_national_policy_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3713 } else if (dmp_sec_pol
== EXTENDED_MISSION
) {
3714 /* Mission Policy Identifier */
3715 message
= tvb_get_guint8 (tvb
, offset
);
3716 if (message
== 0xFF) {
3717 proto_tree_add_uint_format_value(message_tree
, hf_message_mission_policy_id
,
3718 tvb
, offset
, 1, message
,
3721 proto_tree_add_item (message_tree
, hf_message_mission_policy_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3726 /* Security Categories */
3727 if (dmp_sec_pol
== NATO
|| dmp_sec_pol
== NATIONAL
|| dmp_sec_pol
== EXTENDED_NATIONAL
) {
3728 offset
= dissect_dmp_security_category (tvb
, pinfo
, message_tree
, &label_string
, offset
, 0);
3729 proto_item_append_text (en
, ", Security Label: %s", label_string
);
3730 tf
= proto_tree_add_string (message_tree
, hf_message_sec_label
, tvb
, loffset
,
3731 offset
- loffset
+ 1, label_string
);
3732 PROTO_ITEM_SET_GENERATED (tf
);
3734 tf
= proto_tree_add_item (message_tree
, hf_message_sec_cat_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3735 field_tree
= proto_item_add_subtree (tf
, ett_message_sec_cat
);
3737 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit7
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3738 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit6
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3739 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3740 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit4
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3741 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3742 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3743 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3744 proto_tree_add_item (field_tree
, hf_message_sec_cat_bit0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3748 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3750 exp_time
= tvb_get_guint8 (tvb
, offset
);
3751 tf
= proto_tree_add_uint_format (message_tree
, hf_message_exp_time
,
3752 tvb
, offset
, 1, exp_time
,
3754 field_tree
= proto_item_add_subtree (tf
, ett_message_exp_time
);
3755 ei
= proto_tree_add_item (field_tree
, hf_message_exp_time_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3756 secs
= dmp_dec_exp_time (exp_time
);
3757 if (secs
== DMP_TIME_NOT_PRESENT
) {
3758 proto_item_append_text (tf
, "Not present");
3759 proto_item_append_text (ei
, " (not present)");
3760 } else if (secs
== DMP_TIME_RESERVED
) {
3761 proto_item_append_text (tf
, "Reserved (0x%2.2x)", exp_time
);
3762 proto_item_append_text (ei
, " (Reserved)");
3764 proto_item_append_text (tf
, "%s (%s)", time_secs_to_str (secs
),
3765 abs_time_secs_to_str (dmp
.subm_time
+ secs
, ABSOLUTE_TIME_LOCAL
, TRUE
));
3766 proto_item_append_text (ei
, " (%s from submission time)", time_secs_to_str (secs
));
3771 if (dmp
.msg_type
== STANAG
) {
3772 dtg
= tvb_get_guint8 (tvb
, offset
);
3773 tf
= proto_tree_add_uint_format (message_tree
, hf_message_dtg
, tvb
, offset
, 1, dtg
, "DTG: ");
3774 field_tree
= proto_item_add_subtree (tf
, ett_message_dtg
);
3775 proto_tree_add_item (field_tree
, hf_message_dtg_sign
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3776 proto_tree_add_item (field_tree
, hf_message_dtg_val
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3777 secs
= dmp_dec_dtg (dtg
& 0x7F);
3778 if (secs
== DMP_TIME_NOT_PRESENT
) {
3779 proto_item_append_text (tf
, "Not present");
3780 } else if (secs
== DMP_TIME_RESERVED
) {
3781 proto_item_append_text (tf
, "Reserved (0x%2.2x)", dtg
& 0x7F);
3782 } else if (secs
== 0) {
3783 proto_item_append_text (tf
, "0 minutes in the %s (%s)",
3784 (dtg
& 0x80) ? dtg_sign
.true_string
:
3785 dtg_sign
.false_string
,
3786 abs_time_secs_to_str (dmp
.subm_time
, ABSOLUTE_TIME_LOCAL
, TRUE
));
3788 proto_item_append_text (tf
, "%s in the %s (%s)", time_secs_to_str(secs
),
3789 (dtg
& 0x80) ? dtg_sign
.true_string
:
3790 dtg_sign
.false_string
, (dtg
& 0x80) ?
3791 abs_time_secs_to_str (dmp
.subm_time
+ secs
, ABSOLUTE_TIME_LOCAL
, TRUE
) :
3792 abs_time_secs_to_str (dmp
.subm_time
- secs
, ABSOLUTE_TIME_LOCAL
, TRUE
));
3797 if (dmp
.msg_type
== STANAG
) {
3799 offset
= dissect_dmp_sic (tvb
, pinfo
, message_tree
, offset
);
3800 } else if (dmp
.msg_type
== REPORT
|| dmp
.msg_type
== NOTIF
) {
3801 if (dmp
.version
== DMP_VERSION_1
|| dmp
.msg_id_type
== ONLY_DMP_ID
) {
3802 /* Subject Message Identifier */
3803 dmp
.subj_id
= tvb_get_ntohs (tvb
, offset
);
3804 proto_tree_add_item (message_tree
, hf_message_subj_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3805 hidden_item
= proto_tree_add_item (message_tree
, hf_dmp_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3806 PROTO_ITEM_SET_HIDDEN (hidden_item
);
3808 } else if (dmp
.msg_id_type
== X400_MSG_ID
|| dmp
.msg_id_type
== NAT_MSG_ID
) {
3809 if (dmp
.msg_type
== REPORT
) {
3810 /* Subject MTS Identifier */
3811 offset
= dissect_mts_identifier (tvb
, pinfo
, message_tree
, offset
, TRUE
);
3813 /* Subject IPM Identifier */
3814 offset
= dissect_ipm_identifier (tvb
, pinfo
, message_tree
, offset
, TRUE
);
3817 tf
= proto_tree_add_uint (message_tree
, hf_message_subj_id
, tvb
, offset
, 0, dmp
.subj_id
);
3818 PROTO_ITEM_SET_GENERATED (tf
);
3819 hidden_item
= proto_tree_add_uint (message_tree
, hf_dmp_id
, tvb
, offset
, 0, dmp
.subj_id
);
3820 PROTO_ITEM_SET_GENERATED (hidden_item
);
3821 PROTO_ITEM_SET_HIDDEN (hidden_item
);
3826 if (use_seq_ack_analysis
) {
3827 register_dmp_id (pinfo
, 0);
3830 proto_item_set_len (en
, offset
- boffset
);
3832 if (dmp
.msg_type
== STANAG
|| dmp
.msg_type
== IPM
) {
3834 offset
= dissect_dmp_message (tvb
, pinfo
, dmp_tree
, offset
);
3835 } else if (dmp
.msg_type
== REPORT
) {
3836 /* One or more Delivery Report or Non-Delivery Report Data */
3837 rep_len
= tvb_length (tvb
);
3841 while (offset
< rep_len
) {
3842 offset
= dissect_dmp_report (tvb
, pinfo
, dmp_tree
, offset
, &prev_rec_no
, rep_no
++);
3844 } else if (dmp
.msg_type
== NOTIF
) {
3845 /* Notification Data */
3846 offset
= dissect_dmp_notification (tvb
, pinfo
, dmp_tree
, offset
);
3852 static gint
dissect_dmp_extensions (tvbuff_t
*tvb
, packet_info
*pinfo _U_
,
3853 proto_tree
*dmp_tree
, gint offset
)
3855 proto_tree
*exts_tree
, *ext_tree
, *hdr_tree
;
3856 proto_item
*exts_item
, *en
;
3857 guint8 ext_hdr
, ext_length
;
3858 gboolean more_extensions
= TRUE
;
3859 gint num_ext
= 0, boffset
= offset
;
3861 exts_item
= proto_tree_add_item (dmp_tree
, hf_extensions
, tvb
, offset
, -1, ENC_NA
);
3862 exts_tree
= proto_item_add_subtree (exts_item
, ett_extensions
);
3864 while (more_extensions
) {
3865 /* Extensions Present */
3866 ext_hdr
= tvb_get_guint8 (tvb
, offset
);
3867 more_extensions
= (ext_hdr
& 0x80);
3868 ext_length
= (ext_hdr
& 0x7F) + 1;
3870 en
= proto_tree_add_none_format (exts_tree
, hf_extension
, tvb
, offset
, ext_length
+ 1,
3871 "Extension (#%d)", num_ext
+ 1);
3872 ext_tree
= proto_item_add_subtree (en
, ett_extension
);
3874 en
= proto_tree_add_none_format (ext_tree
, hf_extension_header
, tvb
, offset
, 1,
3875 "Extension Length: %u, More %s", ext_length
,
3876 (ext_hdr
& 0x80) ? "Present" : "Not present");
3877 hdr_tree
= proto_item_add_subtree (en
, ett_extension_header
);
3878 proto_tree_add_item (hdr_tree
, hf_extension_more
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3879 proto_tree_add_item (hdr_tree
, hf_extension_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3882 proto_tree_add_item (ext_tree
, hf_extension_data
, tvb
, offset
, ext_length
, ENC_NA
);
3883 offset
+= ext_length
;
3887 proto_item_append_text (exts_item
, " (%d item%s)", num_ext
, plurality (num_ext
, "", "s"));
3888 proto_item_set_len (exts_item
, offset
- boffset
);
3893 static void dissect_dmp (tvbuff_t
*tvb
, packet_info
*pinfo
,
3896 proto_tree
*dmp_tree
= NULL
, *checksum_tree
= NULL
;
3897 proto_item
*ti
= NULL
, *en
= NULL
;
3898 guint16 checksum1
= 0, checksum2
= 1;
3899 gint length
, offset
= 0;
3900 gboolean retrans_or_dup_ack
= FALSE
;
3902 col_set_str (pinfo
->cinfo
, COL_PROTOCOL
, "DMP");
3903 col_clear (pinfo
->cinfo
, COL_INFO
);
3905 /* Initialize global data structure */
3906 memset (&dmp
, 0, sizeof (dmp
));
3908 ti
= proto_tree_add_item (tree
, proto_dmp
, tvb
, offset
, -1, ENC_NA
);
3909 dmp_tree
= proto_item_add_subtree (ti
, ett_dmp
);
3911 offset
= dissect_dmp_envelope (tvb
, pinfo
, dmp_tree
, offset
);
3913 if (dmp
.version
> DMP_VERSION_2
) {
3914 /* Unsupported DMP Version, no point to continue */
3915 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "Unsupported Version: %d", dmp
.version
);
3919 if (dmp
.extensions
) {
3920 offset
= dissect_dmp_extensions (tvb
, pinfo
, dmp_tree
, offset
);
3923 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3924 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
))
3926 offset
= dissect_dmp_content (tvb
, pinfo
, dmp_tree
, offset
);
3927 } else if (dmp
.msg_type
== ACK
) {
3928 offset
= dissect_dmp_ack (tvb
, pinfo
, dmp_tree
, offset
);
3932 length
= tvb_length (tvb
);
3933 checksum1
= crc16_x25_ccitt_tvb (tvb
, length
- 2);
3934 checksum2
= tvb_get_ntohs (tvb
, offset
);
3936 en
= proto_tree_add_item (dmp_tree
, hf_checksum
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3937 checksum_tree
= proto_item_add_subtree (en
, ett_checksum
);
3938 if (checksum1
== checksum2
) {
3939 proto_item_append_text (en
, " (correct)");
3940 en
= proto_tree_add_boolean (checksum_tree
, hf_checksum_good
, tvb
,
3942 PROTO_ITEM_SET_GENERATED (en
);
3943 en
= proto_tree_add_boolean (checksum_tree
, hf_checksum_bad
, tvb
,
3945 PROTO_ITEM_SET_GENERATED (en
);
3947 proto_item_append_text (en
, " (incorrect, should be 0x%04x)",
3949 expert_add_info(pinfo
, en
, &ei_checksum_bad
);
3950 en
= proto_tree_add_boolean (checksum_tree
, hf_checksum_good
, tvb
,
3952 PROTO_ITEM_SET_GENERATED (en
);
3953 en
= proto_tree_add_boolean (checksum_tree
, hf_checksum_bad
, tvb
,
3955 PROTO_ITEM_SET_GENERATED (en
);
3959 if (use_seq_ack_analysis
) {
3960 dmp_add_seq_ack_analysis (tvb
, pinfo
, dmp_tree
, offset
);
3963 if (((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3964 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
)) &&
3965 dmp
.id_val
&& dmp
.id_val
->msg_resend_count
)
3968 if (dmp
.msg_type
== REPORT
) {
3969 retrans_num
= dmp
.id_val
->rep_id
;
3970 } else if (dmp
.msg_type
== NOTIF
) {
3971 retrans_num
= dmp
.id_val
->not_id
;
3973 retrans_num
= dmp
.id_val
->msg_id
;
3975 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "[Retrans %d#%d] ",
3976 retrans_num
, dmp
.id_val
->msg_resend_count
);
3977 retrans_or_dup_ack
= TRUE
;
3978 } else if (dmp
.msg_type
== ACK
&& dmp
.id_val
&& dmp
.id_val
->ack_resend_count
) {
3979 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "[Dup ACK %d#%d] ",
3980 dmp
.id_val
->ack_id
, dmp
.id_val
->ack_resend_count
);
3981 retrans_or_dup_ack
= TRUE
;
3983 if (dmp_align
&& !retrans_or_dup_ack
) {
3984 if (dmp
.msg_type
== ACK
) {
3985 /* ACK does not have "Msg Id" */
3986 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "%-45.45s", msg_type_to_str ());
3988 col_append_fstr (pinfo
->cinfo
, COL_INFO
, "%-31.31s", msg_type_to_str ());
3991 col_append_str (pinfo
->cinfo
, COL_INFO
, msg_type_to_str ());
3993 if ((dmp
.msg_type
== STANAG
) || (dmp
.msg_type
== IPM
) ||
3994 (dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
))
3996 if (dmp_align
&& !retrans_or_dup_ack
) {
3997 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Msg Id: %5d", dmp
.msg_id
);
3999 col_append_fstr (pinfo
->cinfo
, COL_INFO
, ", Msg Id: %d", dmp
.msg_id
);
4002 if ((dmp
.msg_type
== REPORT
) || (dmp
.msg_type
== NOTIF
) ||
4003 (dmp
.msg_type
== ACK
))
4005 if (dmp_align
&& !retrans_or_dup_ack
) {
4006 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Subj Id: %5d",
4009 col_append_fstr (pinfo
->cinfo
, COL_INFO
, ", Subj Id: %d",
4012 } else if (dmp
.struct_id
) {
4013 if (dmp_align
&& !retrans_or_dup_ack
) {
4014 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Body Id: %s",
4015 format_text (dmp
.struct_id
, strlen (dmp
.struct_id
)));
4017 col_append_fstr (pinfo
->cinfo
, COL_INFO
, ", Body Id: %s",
4018 format_text (dmp
.struct_id
, strlen (dmp
.struct_id
)));
4021 if (dmp
.checksum
&& (checksum1
!= checksum2
)) {
4022 col_append_str (pinfo
->cinfo
, COL_INFO
, ", Checksum incorrect");
4025 proto_item_append_text (ti
, ", Version: %d%s, %s", dmp
.version
,
4026 (dmp
.prot_id
== PROT_NAT
? " (national)" : ""),
4030 static void dmp_init_routine (void)
4032 if (dmp_id_hash_table
) {
4033 g_hash_table_destroy (dmp_id_hash_table
);
4035 if (dmp_long_id_hash_table
) {
4036 g_hash_table_destroy (dmp_long_id_hash_table
);
4039 dmp_id_hash_table
= g_hash_table_new (dmp_id_hash
, dmp_id_hash_equal
);
4040 dmp_long_id_hash_table
= g_hash_table_new (g_str_hash
, g_str_equal
);
4043 void proto_register_dmp (void)
4045 static hf_register_info hf
[] = {
4050 { "DMP Identifier", "dmp.id", FT_UINT16
, BASE_DEC
,
4051 NULL
, 0x0, NULL
, HFILL
}},
4053 /* MTS Identifier */
4055 { "MTS Identifier", "dmp.mts", FT_STRING
, BASE_NONE
,
4056 NULL
, 0x0, NULL
, HFILL
} },
4058 /* IPM Identifier */
4060 { "IPM Identifier", "dmp.ipm", FT_STRING
, BASE_NONE
,
4061 NULL
, 0x0, NULL
, HFILL
} },
4067 { "Envelope", "dmp.envelope", FT_NONE
, BASE_NONE
,
4068 NULL
, 0x0, NULL
, HFILL
}},
4071 { &hf_envelope_protocol_id
,
4072 { "Protocol Identifier", "dmp.protocol_id", FT_UINT8
,
4073 BASE_HEX
, NULL
, 0xF8, NULL
, HFILL
}},
4074 { &hf_envelope_version
,
4075 { "Protocol Version", "dmp.version", FT_UINT8
, BASE_DEC
,
4076 VALS(version_vals
), 0x07, NULL
, HFILL
} },
4077 { &hf_envelope_version_value
,
4078 { "Protocol Version", "dmp.version_value", FT_UINT8
, BASE_DEC
,
4079 VALS(version_vals
), 0x07, NULL
, HFILL
} },
4081 /* Envelope elements (byte 1) */
4082 { &hf_envelope_hop_count
,
4083 { "Hop Count", "dmp.hop_count", FT_UINT8
, BASE_DEC
,
4084 NULL
, 0xE0, NULL
, HFILL
} },
4085 { &hf_envelope_hop_count_value
,
4086 { "Hop Count", "dmp.hop_count_value", FT_UINT8
, BASE_DEC
,
4087 NULL
, 0xE0, NULL
, HFILL
} },
4088 { &hf_envelope_rec_present
,
4089 { "Recipient Present", "dmp.rec_present", FT_BOOLEAN
, 8,
4090 TFS (&tfs_present_absent
), 0x20, NULL
, HFILL
} },
4091 { &hf_envelope_addr_enc
,
4092 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4093 TFS (&addr_enc
), 0x10, NULL
, HFILL
} },
4094 { &hf_envelope_checksum
,
4095 { "Checksum", "dmp.checksum_used", FT_BOOLEAN
, 8,
4096 TFS (&tfs_used_notused
), 0x08, "Checksum Used", HFILL
} },
4097 { &hf_envelope_type
,
4098 { "Content Type", "dmp.content_type", FT_UINT8
, BASE_DEC
,
4099 VALS(type_vals
), 0x07, NULL
, HFILL
} },
4101 /* Envelope elements (byte 2) */
4102 { &hf_envelope_extensions
,
4103 { "Extensions", "dmp.extensions_used", FT_BOOLEAN
, 8,
4104 TFS (&tfs_present_absent
), 0x80, "Extensions Used", HFILL
} },
4105 { &hf_envelope_msg_id_type
,
4106 { "Message Identifier Type", "dmp.msg_id_type", FT_UINT8
, BASE_DEC
,
4107 VALS(msg_id_type_vals
), 0x60, NULL
, HFILL
} },
4108 { &hf_envelope_msg_id_length
,
4109 { "Message Identifier Length", "dmp.msg_id_short", FT_UINT8
, BASE_DEC
,
4110 VALS(msg_id_length_vals
), 0x10, NULL
, HFILL
}},
4111 { &hf_envelope_mts_id_length
,
4112 { "MTS Identifier Length", "dmp.mts_id_length", FT_UINT8
, BASE_DEC
,
4113 NULL
, 0x1F, NULL
, HFILL
} },
4114 { &hf_envelope_ipm_id_modifier
,
4115 { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8
, BASE_DEC
,
4116 VALS(ipm_id_modifier
), 0xC0, NULL
, HFILL
} },
4117 { &hf_envelope_ipm_id_length
,
4118 { "IPM Identifier Length", "dmp.ipm_id_length", FT_UINT8
, BASE_DEC
,
4119 NULL
, 0x3F, NULL
, HFILL
} },
4121 { &hf_thales_ipm_id_modifier
,
4122 { "IPM Identifier Modifier", "dmp.ipm_id_modifier", FT_UINT8
, BASE_DEC
,
4123 VALS(thales_ipm_id_modifier
), 0xC0, "Thales XOmail IPM Identifier Modifier", HFILL
} },
4125 /* Message identifier */
4126 { &hf_envelope_msg_id
,
4127 { "Message Identifier", "dmp.msg_id", FT_UINT16
, BASE_DEC
,
4128 NULL
, 0x0, NULL
, HFILL
}},
4129 { &hf_envelope_msg_id_12bit
,
4130 { "Message Identifier", "dmp.msg_id", FT_UINT16
, BASE_DEC
,
4131 NULL
, 0x0FFF, NULL
, HFILL
}},
4133 /* MTS Identifier */
4134 { &hf_envelope_mts_id
,
4135 { "MTS Identifier", "dmp.mts_id", FT_STRING
, BASE_NONE
,
4136 NULL
, 0x0, NULL
, HFILL
} },
4138 /* IPM Identifier */
4139 { &hf_envelope_ipm_id
,
4140 { "IPM Identifier", "dmp.ipm_id", FT_STRING
, BASE_NONE
,
4141 NULL
, 0x0, NULL
, HFILL
} },
4145 { "Extensions", "dmp.extensions", FT_NONE
, BASE_NONE
,
4146 NULL
, 0x0, NULL
, HFILL
}},
4148 { "Extension", "dmp.extension", FT_NONE
, BASE_NONE
,
4149 NULL
, 0x0, NULL
, HFILL
} },
4150 { &hf_extension_header
,
4151 { "Extension Header", "dmp.extension_header", FT_NONE
, BASE_NONE
,
4152 NULL
, 0x0, NULL
, HFILL
}},
4153 { &hf_extension_more
,
4154 { "More Extensions", "dmp.extension_more", FT_BOOLEAN
, 8,
4155 TFS (&tfs_present_absent
), 0x80, NULL
, HFILL
} },
4156 { &hf_extension_length
,
4157 { "Extension Length (minus one)", "dmp.extension_length", FT_UINT8
, BASE_DEC
,
4158 NULL
, 0x7F, "Extension Length minus one", HFILL
} },
4159 { &hf_extension_data
,
4160 { "Extension Data", "dmp.extension_data", FT_BYTES
, BASE_NONE
,
4161 NULL
, 0x0, NULL
, HFILL
} },
4163 /* Submission time */
4164 { &hf_envelope_subm_time
,
4165 { "Submission Time", "dmp.subm_time", FT_UINT16
, BASE_HEX
,
4166 NULL
, 0x0, NULL
, HFILL
} },
4167 { &hf_envelope_time_diff_present
,
4168 { "Time Diff", "dmp.time_diff_present", FT_BOOLEAN
, 16,
4169 TFS (&tfs_present_absent
), 0x8000, "Time Diff Present", HFILL
} },
4170 { &hf_envelope_subm_time_value
,
4171 { "Submission Time Value", "dmp.subm_time_value", FT_UINT16
,
4172 BASE_HEX
, NULL
, 0x7FFF, NULL
, HFILL
} },
4173 { &hf_envelope_time_diff
,
4174 { "Time Difference", "dmp.time_diff", FT_UINT8
, BASE_HEX
,
4175 NULL
, 0xFF, NULL
, HFILL
} },
4176 { &hf_envelope_time_diff_value
,
4177 { "Time Difference Value", "dmp.time_diff_value", FT_UINT8
,
4178 BASE_HEX
, NULL
, 0xFF, NULL
, HFILL
} },
4180 /* Envelope flags */
4181 { &hf_envelope_flags
,
4182 { "Flags", "dmp.envelope_flags", FT_UINT8
, BASE_DEC
,
4183 NULL
, 0x0, "Envelope Flags", HFILL
}},
4184 { &hf_envelope_content_id_discarded
,
4185 { "Content Identifier discarded", "dmp.cont_id_discarded",
4186 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
4188 { &hf_envelope_recip_reassign_prohib
,
4189 { "Recipient reassign prohibited","dmp.recip_reassign_prohib",
4190 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
4192 { &hf_envelope_dl_expansion_prohib
,
4193 { "DL expansion prohibited", "dmp.dl_expansion_prohib",
4194 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20, NULL
,
4197 /* Recipient Count */
4198 { &hf_envelope_recipients
,
4199 { "Recipient Count", "dmp.rec_count", FT_UINT8
, BASE_DEC
,
4200 NULL
, 0x1F, NULL
, HFILL
}},
4201 { &hf_envelope_ext_recipients
,
4202 { "Extended Recipient Count", "dmp.ext_rec_count", FT_UINT16
,
4203 BASE_DEC
, NULL
, 0x7FFF, NULL
, HFILL
}},
4208 { &hf_addr_recipient
,
4209 { "Recipient Number", "dmp.recipient", FT_NONE
, BASE_NONE
,
4210 NULL
, 0x0, "Recipient", HFILL
} },
4211 { &hf_addr_originator
,
4212 { "Originator", "dmp.originator", FT_NONE
, BASE_NONE
,
4213 NULL
, 0x0, NULL
, HFILL
} },
4214 { &hf_addr_reporting_name
,
4215 { "Reporting Name Number", "dmp.reporting_name", FT_NONE
,
4216 BASE_NONE
, NULL
, 0x0, "Reporting Name", HFILL
} },
4217 { &hf_addr_dl_expanded
,
4218 { "DL Expanded", "dmp.dl_expanded", FT_BOOLEAN
, BASE_NONE
,
4219 NULL
, 0x0, "Message has been DL expanded", HFILL
} },
4221 { "Intended Recipient", "dmp.int_rec", FT_BOOLEAN
, BASE_NONE
,
4222 NULL
, 0x0, "Message has an intended recipient", HFILL
} },
4227 { &hf_addr_dir_addr_ext
,
4228 { "Address Extended", "dmp.addr_ext", FT_BOOLEAN
, 8,
4229 NULL
, 0x80, NULL
, HFILL
} },
4230 { &hf_addr_dir_rec_no
,
4231 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8
,
4232 BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
} },
4233 { &hf_addr_dir_rec_no_generated
,
4234 { "Recipient Number", "dmp.rec_no", FT_UINT32
,
4235 BASE_DEC
, NULL
, 0x0, "Recipient Number Offset", HFILL
} },
4236 { &hf_addr_dir_rec_no1
,
4237 { "Recipient Number (bits 3-0)", "dmp.rec_no_offset1", FT_UINT8
,
4238 BASE_DEC
, NULL
, 0xF0, "Recipient Number (bits 3-0) Offset", HFILL
} },
4239 { &hf_addr_dir_rec_no2
,
4240 { "Recipient Number (bits 9-4)", "dmp.rec_no_offset2", FT_UINT8
,
4241 BASE_DEC
, NULL
, 0x3F, "Recipient Number (bits 9-4) Offset", HFILL
} },
4242 { &hf_addr_dir_rec_no3
,
4243 { "Recipient Number (bits 14-10)", "dmp.rec_no_offset3", FT_UINT8
,
4244 BASE_DEC
, NULL
, 0x1F, "Recipient Number (bits 14-10) Offset",HFILL
} },
4245 { &hf_addr_dir_rep_req1
,
4246 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4247 VALS (report_vals_ext
), 0x0C, NULL
, HFILL
} },
4248 { &hf_addr_dir_rep_req2
,
4249 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4250 VALS (report_vals_ext
), 0xC0, NULL
, HFILL
} },
4251 { &hf_addr_dir_rep_req3
,
4252 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4253 VALS (report_vals
), 0xC0, NULL
, HFILL
} },
4254 { &hf_addr_dir_not_req1
,
4255 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4256 VALS (notif_vals_ext
), 0x03, NULL
, HFILL
} },
4257 { &hf_addr_dir_not_req2
,
4258 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4259 VALS (notif_vals_ext
), 0xC0, NULL
, HFILL
} },
4260 { &hf_addr_dir_not_req3
,
4261 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4262 VALS (notif_vals
), 0xC0, NULL
, HFILL
} },
4263 { &hf_addr_dir_action
,
4264 { "Action", "dmp.action", FT_BOOLEAN
, 8,
4265 TFS (&tfs_yes_no
), 0x80, NULL
, HFILL
} },
4266 { &hf_addr_dir_address
,
4267 { "Direct Address", "dmp.direct_addr", FT_UINT8
,
4268 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4269 { &hf_addr_dir_address_generated
,
4270 { "Direct Address", "dmp.direct_addr", FT_UINT32
,
4271 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4272 { &hf_addr_dir_address1
,
4273 { "Direct Address (bits 6-0)", "dmp.direct_addr1", FT_UINT8
,
4274 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4275 { &hf_addr_dir_address2
,
4276 { "Direct Address (bits 12-7)", "dmp.direct_addr2", FT_UINT8
,
4277 BASE_DEC
, NULL
, 0x3F, NULL
, HFILL
} },
4278 { &hf_addr_dir_address3
,
4279 { "Direct Address (bits 18-13)", "dmp.direct_addr3", FT_UINT8
,
4280 BASE_DEC
, NULL
, 0x3F, NULL
, HFILL
} },
4285 { &hf_addr_ext_form
,
4286 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4287 VALS (&addr_form
), 0xE0, NULL
, HFILL
} },
4288 { &hf_addr_ext_form_orig_v1
,
4289 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4290 VALS (&addr_form_orig_v1
), 0xE0, NULL
, HFILL
} },
4291 { &hf_addr_ext_form_orig
,
4292 { "Address Form", "dmp.addr_form", FT_UINT8
, BASE_DEC
,
4293 VALS (&addr_form_orig
), 0xE0, NULL
, HFILL
} },
4294 { &hf_addr_ext_action
,
4295 { "Action", "dmp.action", FT_BOOLEAN
, 8,
4296 TFS (&tfs_yes_no
), 0x10, NULL
, HFILL
} },
4297 { &hf_addr_ext_rep_req
,
4298 { "Report Request", "dmp.rep_rec", FT_UINT8
, BASE_HEX
,
4299 VALS (report_vals
), 0x0C, NULL
, HFILL
} },
4300 { &hf_addr_ext_not_req
,
4301 { "Notification Request", "dmp.not_req", FT_UINT8
, BASE_HEX
,
4302 VALS (notif_vals
), 0x03, NULL
, HFILL
} },
4303 { &hf_addr_ext_rec_ext
,
4304 { "Recipient Number Extended", "dmp.rec_no_ext", FT_BOOLEAN
, 8,
4305 NULL
, 0x80, NULL
, HFILL
} },
4306 { &hf_addr_ext_rec_no
,
4307 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8
,
4308 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
} },
4309 { &hf_addr_ext_rec_no_generated
,
4310 { "Recipient Number", "dmp.rec_no", FT_UINT32
,
4311 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4312 { &hf_addr_ext_rec_no1
,
4313 { "Recipient Number (bits 6-0)", "dmp.rec_no_offset1", FT_UINT8
,
4314 BASE_DEC
, NULL
, 0x7F, "Recipient Number (bits 6-0) Offset", HFILL
} },
4315 { &hf_addr_ext_rec_no2
,
4316 { "Recipient Number (bits 14-7)", "dmp.rec_no_offset2", FT_UINT8
,
4317 BASE_DEC
, NULL
, 0xFF, "Recipient Number (bits 14-7) Offset", HFILL
} },
4318 { &hf_addr_ext_address
,
4319 { "Extended Address", "dmp.addr_form", FT_NONE
, BASE_NONE
,
4320 NULL
, 0x0, NULL
, HFILL
} },
4321 { &hf_addr_ext_type
,
4322 { "Address Type", "dmp.addr_type", FT_UINT8
, BASE_DEC
,
4323 VALS (&ext_addr_type
), 0xE0, NULL
, HFILL
} },
4324 { &hf_addr_ext_type_ext
,
4325 { "Address Type Extended", "dmp.addr_type_ext", FT_UINT8
,
4326 BASE_DEC
, VALS (&ext_addr_type_ext
), 0xE0, NULL
,
4328 { &hf_addr_ext_length
,
4329 { "Address Length", "dmp.addr_length", FT_UINT8
,
4330 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4331 { &hf_addr_ext_length_generated
,
4332 { "Address Length", "dmp.addr_length", FT_UINT32
,
4333 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4334 { &hf_addr_ext_length1
,
4335 { "Address Length (bits 4-0)", "dmp.addr_length1", FT_UINT8
,
4336 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4337 { &hf_addr_ext_length2
,
4338 { "Address Length (bits 9-5)", "dmp.addr_length2", FT_UINT8
,
4339 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
4340 { &hf_addr_ext_asn1_ber
,
4341 { "ASN.1 BER-encoded OR-name", "dmp.or_name", FT_NONE
,
4342 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4343 { &hf_addr_ext_asn1_per
,
4344 { "ASN.1 PER-encoded OR-name", "dmp.asn1_per", FT_BYTES
,
4345 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4346 { &hf_addr_ext_unknown
,
4347 { "Unknown encoded address", "dmp.addr_unknown", FT_BYTES
,
4348 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4353 { &hf_message_content
,
4354 { "Message Content", "dmp.message", FT_NONE
, BASE_NONE
,
4355 NULL
, 0x0, NULL
, HFILL
} },
4356 { &hf_report_content
,
4357 { "Report Content", "dmp.report", FT_NONE
, BASE_NONE
,
4358 NULL
, 0x0, NULL
, HFILL
} },
4359 { &hf_notif_content
,
4360 { "Notification Content", "dmp.notification", FT_NONE
, BASE_NONE
,
4361 NULL
, 0x0, NULL
, HFILL
} },
4363 { &hf_message_st_type
,
4364 { "Message type", "dmp.msg_type", FT_UINT8
, BASE_DEC
,
4365 VALS (message_type_vals
), 0xC0, NULL
, HFILL
} },
4366 { &hf_message_precedence
,
4367 { "Precedence", "dmp.precedence", FT_UINT8
, BASE_DEC
,
4368 VALS (precedence
), 0x1C, NULL
, HFILL
} },
4369 { &hf_message_importance
,
4370 { "Importance", "dmp.importance", FT_UINT8
, BASE_DEC
,
4371 VALS (importance
), 0x1C, NULL
, HFILL
} },
4372 { &hf_message_body_format
,
4373 { "Body format", "dmp.body_format", FT_UINT8
, BASE_DEC
,
4374 VALS (body_format_vals
), 0x03, NULL
, HFILL
} },
4376 /* Security Values */
4377 { &hf_message_sec_label
,
4378 { "Security Label", "dmp.sec_label", FT_STRING
, BASE_NONE
,
4379 NULL
, 0x0, NULL
, HFILL
} },
4380 { &hf_message_sec_class_val
,
4381 { "Security Classification", "dmp.sec_class", FT_UINT8
,
4382 BASE_DEC
, NULL
, 0xE0, NULL
, HFILL
}},
4383 { &hf_message_sec_pol
,
4384 { "Security Policy", "dmp.sec_pol", FT_UINT8
, BASE_DEC
,
4385 VALS (sec_pol
), 0x1C, NULL
, HFILL
} },
4386 { &hf_message_heading_flags
,
4387 { "Heading Flags", "dmp.heading_flags", FT_NONE
, BASE_NONE
,
4388 NULL
, 0x0, NULL
, HFILL
} },
4389 { &hf_message_auth_users
,
4390 { "Authorizing users discarded", "dmp.auth_discarded",
4391 FT_BOOLEAN
, 8, TFS (&tfs_yes_no
), 0x02,
4393 { &hf_message_subject_disc
,
4394 { "Subject discarded", "dmp.subject_discarded", FT_BOOLEAN
, 8,
4395 TFS (&tfs_yes_no
), 0x01, NULL
, HFILL
} },
4397 /* National Policy Identifier */
4398 { &hf_message_national_policy_id
,
4399 { "National Policy Identifier", "dmp.nat_pol_id", FT_UINT8
,
4400 BASE_DEC
, VALS(nat_pol_id
), 0x0, NULL
,
4403 /* Mission Policy Identifier */
4404 { &hf_message_mission_policy_id
,
4405 { "Mission Policy Identifier", "dmp.mission_pol_id", FT_UINT8
,
4406 BASE_DEC
, NULL
, 0x0, NULL
,
4409 /* Security Categories */
4410 { &hf_message_sec_cat_nat
,
4411 { "Security Categories", "dmp.sec_cat", FT_UINT8
, BASE_HEX
,
4412 NULL
, 0x0, NULL
, HFILL
} },
4413 { &hf_message_sec_cat_val
,
4414 { "Security Categories", "dmp.sec_cat", FT_UINT8
, BASE_HEX
,
4415 NULL
, 0x0, NULL
, HFILL
} },
4416 { &hf_message_sec_cat_cl
,
4417 { "Clear", "dmp.sec_cat.cl", FT_BOOLEAN
, 8,
4418 TFS (&tfs_set_notset
), 0x80, NULL
, HFILL
} },
4419 { &hf_message_sec_cat_cs
,
4420 { "Crypto Security", "dmp.sec_cat.cs", FT_BOOLEAN
, 8,
4421 TFS (&tfs_set_notset
), 0x40, NULL
, HFILL
} },
4422 { &hf_message_sec_cat_ex
,
4423 { "Exclusive", "dmp.sec_cat.ex", FT_BOOLEAN
, 8,
4424 TFS (&tfs_set_notset
), 0x20, NULL
, HFILL
} },
4425 { &hf_message_sec_cat_ne
,
4426 { "National Eyes Only", "dmp.sec_cat.ne", FT_BOOLEAN
, 8,
4427 TFS (&tfs_set_notset
), 0x10, NULL
, HFILL
} },
4428 { &hf_message_sec_cat_permissive
,
4429 { "Releasable to", "dmp.sec_cat.permissive", FT_UINT8
, BASE_HEX
,
4430 VALS (nat_pol_id
), 0xFC, NULL
, HFILL
} },
4431 { &hf_message_sec_cat_country_code
,
4432 { "Country Code", "dmp.sec_cat.country", FT_UINT8
, BASE_DEC
,
4433 NULL
, 0x00, NULL
, HFILL
} },
4434 { &hf_message_sec_cat_restrictive
,
4435 { "Restrictive", "dmp.sec_cat.restrictive", FT_UINT8
, BASE_HEX
,
4436 NULL
, 0xFC, NULL
, HFILL
} },
4437 { &hf_message_sec_cat_extended
,
4438 { "Extended", "dmp.sec_cat.extended", FT_UINT8
, BASE_HEX
,
4439 VALS (ext_sec_cat
), 0x03, "Extended Security Category", HFILL
} },
4440 { &hf_message_sec_cat_bit0
,
4441 { "Bit 0", "dmp.sec_cat.bit0", FT_BOOLEAN
, 8,
4442 TFS (&tfs_set_notset
), 0x01, NULL
, HFILL
} },
4443 { &hf_message_sec_cat_bit1
,
4444 { "Bit 1", "dmp.sec_cat.bit1", FT_BOOLEAN
, 8,
4445 TFS (&tfs_set_notset
), 0x02, NULL
, HFILL
} },
4446 { &hf_message_sec_cat_bit2
,
4447 { "Bit 2", "dmp.sec_cat.bit2", FT_BOOLEAN
, 8,
4448 TFS (&tfs_set_notset
), 0x04, NULL
, HFILL
} },
4449 { &hf_message_sec_cat_bit3
,
4450 { "Bit 3", "dmp.sec_cat.bit3", FT_BOOLEAN
, 8,
4451 TFS (&tfs_set_notset
), 0x08, NULL
, HFILL
} },
4452 { &hf_message_sec_cat_bit4
,
4453 { "Bit 4", "dmp.sec_cat.bit4", FT_BOOLEAN
, 8,
4454 TFS (&tfs_set_notset
), 0x10, NULL
, HFILL
} },
4455 { &hf_message_sec_cat_bit5
,
4456 { "Bit 5", "dmp.sec_cat.bit5", FT_BOOLEAN
, 8,
4457 TFS (&tfs_set_notset
), 0x20, NULL
, HFILL
} },
4458 { &hf_message_sec_cat_bit6
,
4459 { "Bit 6", "dmp.sec_cat.bit6", FT_BOOLEAN
, 8,
4460 TFS (&tfs_set_notset
), 0x40, NULL
, HFILL
} },
4461 { &hf_message_sec_cat_bit7
,
4462 { "Bit 7", "dmp.sec_cat.bit7", FT_BOOLEAN
, 8,
4463 TFS (&tfs_set_notset
), 0x80, NULL
, HFILL
} },
4466 { &hf_message_exp_time
,
4467 { "Expiry Time", "dmp.expiry_time", FT_UINT8
, BASE_HEX
,
4468 NULL
, 0x0, NULL
, HFILL
} },
4469 { &hf_message_exp_time_val
,
4470 { "Expiry Time Value", "dmp.expiry_time_val", FT_UINT8
, BASE_HEX
,
4471 NULL
, 0xFF, NULL
, HFILL
} },
4475 { "DTG", "dmp.dtg", FT_UINT8
, BASE_HEX
,
4476 NULL
, 0xFF, NULL
, HFILL
} },
4477 { &hf_message_dtg_sign
,
4478 { "DTG in the", "dmp.dtg.sign", FT_BOOLEAN
, 8, TFS (&dtg_sign
),
4479 0x80, "Sign", HFILL
} },
4480 { &hf_message_dtg_val
,
4481 { "DTG Value", "dmp.dtg.val", FT_UINT8
, BASE_HEX
, NULL
,
4482 0x7F, NULL
, HFILL
} },
4486 { "SIC", "dmp.sic", FT_STRING
, BASE_NONE
,
4487 NULL
, 0x0, NULL
, HFILL
} },
4488 { &hf_message_sic_key
,
4489 { "SICs", "dmp.sic_key", FT_NONE
, BASE_NONE
,
4490 NULL
, 0x0, "SIC Content", HFILL
} },
4491 { &hf_message_sic_key_values
,
4492 { "Content Byte", "dmp.sic_key.values", FT_UINT8
, BASE_HEX
,
4493 NULL
, 0x0, "SIC Content Byte", HFILL
} },
4494 { &hf_message_sic_key_type
,
4495 { "Type", "dmp.sic_key.type", FT_UINT8
, BASE_HEX
,
4496 VALS (sic_key_type
), 0xF0, "SIC Content Type", HFILL
} },
4497 { &hf_message_sic_key_chars
,
4498 { "Valid Characters", "dmp.sic_key.chars", FT_BOOLEAN
, 8,
4499 TFS (&sic_key_chars
), 0x08, "SIC Valid Characters", HFILL
} },
4500 { &hf_message_sic_key_num
,
4501 { "Number of SICs", "dmp.sic_key.num", FT_UINT8
, BASE_HEX
,
4502 VALS (sic_key_num
), 0x07, NULL
, HFILL
} },
4503 { &hf_message_sic_bitmap
,
4504 { "Length Bitmap (0 = 3 bytes, 1 = 4-8 bytes)", "dmp.sic_bitmap",
4505 FT_UINT8
, BASE_HEX
, NULL
, 0xFF, "SIC Length Bitmap", HFILL
} },
4506 { &hf_message_sic_bits
,
4507 { "Bit 7-4", "dmp.sic_bits", FT_UINT8
, BASE_HEX
,
4508 VALS(sic_bit_vals
), 0xF0, "SIC Bit 7-4, Characters [A-Z0-9] only",
4510 { &hf_message_sic_bits_any
,
4511 { "Bit 7-4", "dmp.sic_bits_any", FT_UINT8
, BASE_HEX
,
4512 VALS(sic_bit_any_vals
), 0xF0, "SIC Bit 7-4, Any valid characters",
4515 /* Subject Message Id */
4516 { &hf_message_subj_id
,
4517 { "Subject Message Identifier", "dmp.subj_id", FT_UINT16
,
4518 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4520 /* Subject MTS Identifier */
4521 { &hf_message_subj_mts_id
,
4522 { "Subject MTS Identifier", "dmp.subj_mts_id", FT_STRING
, BASE_NONE
,
4523 NULL
, 0x0, NULL
, HFILL
} },
4525 /* Subject IPM Identifier */
4526 { &hf_message_subj_ipm_id
,
4527 { "Subject IPM Identifier", "dmp.subj_ipm_id", FT_STRING
, BASE_NONE
,
4528 NULL
, 0x0, NULL
, HFILL
} },
4534 { "Message Body", "dmp.body", FT_NONE
, BASE_NONE
, NULL
,
4539 { "EIT", "dmp.body.eit", FT_UINT8
, BASE_DEC
,
4540 VALS(eit_vals
), 0xE0, "Encoded Information Type", HFILL
} },
4541 { &hf_message_compr
,
4542 { "Compression", "dmp.body.compression", FT_UINT8
, BASE_DEC
,
4543 VALS(compression_vals
), 0x18, NULL
, HFILL
} },
4546 { &hf_message_subject
,
4547 { "Subject", "dmp.subject", FT_STRINGZ
, BASE_NONE
,
4548 NULL
, 0x0, NULL
, HFILL
} },
4551 { &hf_message_body_data
,
4552 { "User data", "dmp.body.data", FT_NONE
, BASE_NONE
,
4553 NULL
, 0x0, NULL
, HFILL
} },
4554 { &hf_message_body_plain
,
4555 { "Message Body", "dmp.body.plain", FT_STRING
, BASE_NONE
,
4556 NULL
, 0x0, NULL
, HFILL
} },
4557 { &hf_message_bodyid_uint8
,
4558 { "Structured Id", "dmp.body.id", FT_UINT8
, BASE_DEC
,
4559 NULL
, 0x0, "Structured Body Id (1 byte)", HFILL
} },
4560 { &hf_message_bodyid_uint16
,
4561 { "Structured Id", "dmp.body.id", FT_UINT16
, BASE_DEC
,
4562 NULL
, 0x0, "Structured Body Id (2 bytes)", HFILL
} },
4563 { &hf_message_bodyid_uint32
,
4564 { "Structured Id", "dmp.body.id", FT_UINT32
, BASE_DEC
,
4565 NULL
, 0x0, "Structured Body Id (4 bytes)", HFILL
} },
4566 { &hf_message_bodyid_uint64
,
4567 { "Structured Id", "dmp.body.id", FT_UINT64
, BASE_DEC
,
4568 NULL
, 0x0, "Structured Body Id (8 bytes)", HFILL
} },
4569 { &hf_message_bodyid_string
,
4570 { "Structured Id", "dmp.body.id", FT_STRING
, BASE_NONE
,
4571 NULL
, 0x0, "Structured Body Id (fixed text string)", HFILL
} },
4572 { &hf_message_bodyid_zstring
,
4573 { "Structured Id", "dmp.body.id", FT_STRINGZ
, BASE_NONE
,
4574 NULL
, 0x0, "Structured Body Id (zero terminated text string)",
4576 { &hf_message_body_structured
,
4577 { "Structured Body", "dmp.body.structured", FT_BYTES
, BASE_NONE
,
4578 NULL
, 0x0, NULL
, HFILL
} },
4579 { &hf_message_body_uncompr
,
4580 { "Uncompressed User data", "dmp.body.uncompressed", FT_NONE
,
4581 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4582 { &hf_message_body_uncompressed
,
4583 { "Uncompressed Message Body", "dmp.body.uncompressed",
4584 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
,
4590 { &hf_delivery_report
,
4591 { "Delivery Report", "dmp.dr", FT_NONE
, BASE_NONE
, NULL
,
4593 { &hf_non_delivery_report
,
4594 { "Non-Delivery Report", "dmp.ndr", FT_NONE
, BASE_NONE
, NULL
,
4598 { "Report Type", "dmp.report_type", FT_BOOLEAN
, 8,
4599 TFS (&report_type
), 0x80, NULL
, HFILL
} },
4600 { &hf_report_info_present_dr
,
4601 { "Info Present", "dmp.info_present", FT_BOOLEAN
, 8,
4602 TFS (&tfs_present_absent
), 0x40, NULL
, HFILL
} },
4603 { &hf_report_addr_enc_dr
,
4604 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4605 TFS (&addr_enc
), 0x20, NULL
, HFILL
} },
4606 { &hf_report_del_time
,
4607 { "Delivery Time", "dmp.delivery_time", FT_UINT8
, BASE_HEX
,
4608 NULL
, 0x0, NULL
, HFILL
} },
4609 { &hf_report_del_time_val
,
4610 { "Delivery Time Value", "dmp.delivery_time_val", FT_UINT8
,
4611 BASE_HEX
, NULL
, 0xFF, NULL
, HFILL
} },
4612 { &hf_report_addr_enc_ndr
,
4613 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN
, 8,
4614 TFS (&addr_enc
), 0x40, NULL
, HFILL
} },
4615 { &hf_report_reason
,
4616 { "Reason (P1)", "dmp.report_reason", FT_UINT8
, BASE_DEC
,
4617 VALS (p1_NonDeliveryReasonCode_vals
), 0x3F,
4618 "Reason", HFILL
} },
4619 { &hf_report_info_present_ndr
,
4620 { "Info Present", "dmp.info_present", FT_BOOLEAN
, 8,
4621 TFS (&tfs_present_absent
), 0x80, NULL
, HFILL
} },
4623 { "Diagnostic (P1)", "dmp.report_diagnostic", FT_UINT8
, BASE_DEC
,
4624 VALS (p1_NonDeliveryDiagnosticCode_vals
), 0x7F,
4625 "Diagnostic", HFILL
} },
4626 { &hf_report_suppl_info_len
,
4627 { "Supplementary Information", "dmp.suppl_info_len", FT_UINT8
,
4628 BASE_DEC
, NULL
, 0x0, "Supplementary Information Length", HFILL
} },
4629 { &hf_report_suppl_info
,
4630 { "Supplementary Information", "dmp.suppl_info", FT_STRINGZ
,
4631 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4636 { &hf_receipt_notif
,
4637 { "Receipt Notification (RN)", "dmp.rn", FT_NONE
, BASE_NONE
,
4638 NULL
, 0x0, NULL
, HFILL
} },
4639 { &hf_non_receipt_notif
,
4640 { "Non-Receipt Notification (NRN)", "dmp.nrn", FT_NONE
, BASE_NONE
,
4641 NULL
, 0x0, NULL
, HFILL
} },
4643 { "Other Notification (ON)", "dmp.on", FT_NONE
, BASE_NONE
,
4644 NULL
, 0x0, NULL
, HFILL
} },
4647 { "Notification Type", "dmp.notif_type", FT_UINT8
, BASE_DEC
,
4648 VALS (notif_type
), 0x03, NULL
, HFILL
} },
4649 { &hf_notif_rec_time
,
4650 { "Receipt Time", "dmp.receipt_time", FT_UINT8
, BASE_HEX
,
4651 NULL
, 0x0, NULL
, HFILL
} },
4652 { &hf_notif_rec_time_val
,
4653 { "Receipt Time Value", "dmp.receipt_time_val", FT_UINT8
,
4654 BASE_HEX
, NULL
, 0xFF, NULL
, HFILL
} },
4655 { &hf_notif_suppl_info_len
,
4656 { "Supplementary Information", "dmp.suppl_info_len",
4657 FT_UINT8
, BASE_DEC
, NULL
, 0x0, "Supplementary Information Length",
4659 { &hf_notif_suppl_info
,
4660 { "Supplementary Information", "dmp.suppl_info",
4661 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0, NULL
,
4663 { &hf_notif_non_rec_reason
,
4664 { "Non-Receipt Reason", "dmp.notif_non_rec_reason",
4665 FT_UINT8
, BASE_DEC
, VALS (p22_NonReceiptReasonField_vals
), 0x0,
4667 { &hf_notif_discard_reason
,
4668 { "Discard Reason", "dmp.notif_discard_reason", FT_UINT8
,
4669 BASE_DEC
, VALS (p22_DiscardReasonField_vals
), 0x0,
4671 { &hf_notif_on_type
,
4672 { "ON Type", "dmp.notif_on_type", FT_UINT8
, BASE_DEC
,
4673 VALS (on_type
), 0x0, NULL
, HFILL
} },
4675 { "ACP127 Recipient", "dmp.acp127recip_len", FT_UINT8
,
4676 BASE_DEC
, NULL
, 0x0, "ACP 127 Recipient Length", HFILL
} },
4677 { &hf_notif_acp127recip
,
4678 { "ACP127 Recipient", "dmp.acp127recip", FT_STRINGZ
,
4679 BASE_NONE
, NULL
, 0x0, "ACP 127 Recipient", HFILL
} },
4685 { "Acknowledgement", "dmp.ack", FT_NONE
, BASE_NONE
,
4686 NULL
, 0x0, NULL
, HFILL
} },
4688 { "Ack Reason", "dmp.ack_reason", FT_UINT8
, BASE_DEC
,
4689 VALS (&ack_reason
), 0x0, "Reason", HFILL
} },
4690 { &hf_ack_diagnostic
,
4691 { "Ack Diagnostic", "dmp.ack_diagnostic", FT_UINT8
, BASE_DEC
,
4692 NULL
, 0x0, "Diagnostic", HFILL
} },
4694 { "Recipient List", "dmp.ack_rec_list", FT_NONE
, BASE_NONE
,
4695 NULL
, 0x0, NULL
, HFILL
} },
4701 { "Checksum", "dmp.checksum", FT_UINT16
, BASE_HEX
,
4702 NULL
, 0x0, NULL
, HFILL
} },
4703 { &hf_checksum_good
,
4704 { "Good", "dmp.checksum_good", FT_BOOLEAN
, BASE_NONE
,
4705 NULL
, 0x0, "True: checksum matches packet content; False: doesn't match content or not checked", HFILL
} },
4707 { "Bad", "dmp.checksum_bad", FT_BOOLEAN
, BASE_NONE
,
4708 NULL
, 0x0, "True: checksum doesn't match packet content; False: matches content or not checked", HFILL
} },
4711 ** Ack matching / Resend
4713 { &hf_analysis_ack_time
,
4714 { "Acknowledgement Time", "dmp.analysis.ack_time", FT_RELATIVE_TIME
, BASE_NONE
,
4715 NULL
, 0x0, "The time between the Message and the Acknowledge", HFILL
} },
4716 { &hf_analysis_rep_time
,
4717 { "Report Reply Time", "dmp.analysis.report_time", FT_RELATIVE_TIME
, BASE_NONE
,
4718 NULL
, 0x0, "The time between the Message and the Report", HFILL
} },
4719 { &hf_analysis_not_time
,
4720 { "Notification Reply Time", "dmp.analysis.notif_time", FT_RELATIVE_TIME
, BASE_NONE
,
4721 NULL
, 0x0, "The time between the Message and the Notification", HFILL
} },
4722 { &hf_analysis_total_time
,
4723 { "Total Time", "dmp.analysis.total_time", FT_RELATIVE_TIME
, BASE_NONE
,
4724 NULL
, 0x0, "The time between the first Message and the Acknowledge", HFILL
} },
4725 { &hf_analysis_retrans_time
,
4726 { "Retransmission Time", "dmp.analysis.retrans_time", FT_RELATIVE_TIME
, BASE_NONE
,
4727 NULL
, 0x0, "The time between the last Message and this Message", HFILL
} },
4728 { &hf_analysis_total_retrans_time
,
4729 { "Total Retransmission Time", "dmp.analysis.total_retrans_time", FT_RELATIVE_TIME
, BASE_NONE
,
4730 NULL
, 0x0, "The time between the first Message and this Message", HFILL
} },
4731 { &hf_analysis_msg_num
,
4732 { "Message in", "dmp.analysis.msg_in", FT_FRAMENUM
, BASE_NONE
,
4733 NULL
, 0x0, "This packet has a Message in this frame", HFILL
} },
4734 { &hf_analysis_ack_num
,
4735 { "Acknowledgement in", "dmp.analysis.ack_in", FT_FRAMENUM
, BASE_NONE
,
4736 NULL
, 0x0, "This packet has an Acknowledgement in this frame", HFILL
} },
4737 { &hf_analysis_rep_num
,
4738 { "Report in", "dmp.analysis.report_in", FT_FRAMENUM
, BASE_NONE
,
4739 NULL
, 0x0, "This packet has a Report in this frame", HFILL
} },
4740 { &hf_analysis_not_num
,
4741 { "Notification in", "dmp.analysis.notif_in", FT_FRAMENUM
, BASE_NONE
,
4742 NULL
, 0x0, "This packet has a Notification in this frame", HFILL
} },
4743 { &hf_analysis_ack_missing
,
4744 { "Acknowledgement missing", "dmp.analysis.ack_missing", FT_NONE
, BASE_NONE
,
4745 NULL
, 0x0, "The acknowledgement for this packet is missing", HFILL
} },
4746 { &hf_analysis_retrans_no
,
4747 { "Retransmission #", "dmp.analysis.retrans_no", FT_UINT32
, BASE_DEC
,
4748 NULL
, 0x0, "Retransmission count", HFILL
} },
4749 { &hf_analysis_ack_dup_no
,
4750 { "Duplicate ACK #", "dmp.analysis.dup_ack_no", FT_UINT32
, BASE_DEC
,
4751 NULL
, 0x0, "Duplicate Acknowledgement count", HFILL
} },
4752 { &hf_analysis_msg_resend_from
,
4753 { "Retransmission of Message sent in", "dmp.analysis.msg_first_sent_in",
4754 FT_FRAMENUM
, BASE_NONE
,
4755 NULL
, 0x0, "This Message was first sent in this frame", HFILL
} },
4756 { &hf_analysis_rep_resend_from
,
4757 { "Retransmission of Report sent in", "dmp.analysis.report_first_sent_in",
4758 FT_FRAMENUM
, BASE_NONE
,
4759 NULL
, 0x0, "This Report was first sent in this frame", HFILL
} },
4760 { &hf_analysis_not_resend_from
,
4761 { "Retransmission of Notification sent in", "dmp.analysis.notif_first_sent_in",
4762 FT_FRAMENUM
, BASE_NONE
,
4763 NULL
, 0x0, "This Notification was first sent in this frame", HFILL
} },
4764 { &hf_analysis_ack_resend_from
,
4765 { "Retransmission of Acknowledgement sent in", "dmp.analysis.ack_first_sent_in",
4766 FT_FRAMENUM
, BASE_NONE
,
4767 NULL
, 0x0, "This Acknowledgement was first sent in this frame", HFILL
} },
4772 { &hf_reserved_0x01
,
4773 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4774 NULL
, 0x01, NULL
, HFILL
} },
4775 { &hf_reserved_0x02
,
4776 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4777 NULL
, 0x02, NULL
, HFILL
} },
4778 { &hf_reserved_0x04
,
4779 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4780 NULL
, 0x04, NULL
, HFILL
} },
4781 { &hf_reserved_0x07
,
4782 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4783 NULL
, 0x07, NULL
, HFILL
} },
4784 { &hf_reserved_0x08
,
4785 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4786 NULL
, 0x08, NULL
, HFILL
} },
4787 { &hf_reserved_0x0F
,
4788 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4789 NULL
, 0x0F, NULL
, HFILL
} },
4790 { &hf_reserved_0x1F
,
4791 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4792 NULL
, 0x1F, NULL
, HFILL
} },
4793 { &hf_reserved_0x20
,
4794 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4795 NULL
, 0x20, NULL
, HFILL
} },
4796 { &hf_reserved_0x40
,
4797 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4798 NULL
, 0x40, NULL
, HFILL
} },
4799 { &hf_reserved_0xC0
,
4800 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4801 NULL
, 0xC0, NULL
, HFILL
} },
4802 { &hf_reserved_0xE0
,
4803 { "Reserved", "dmp.reserved", FT_UINT8
, BASE_DEC
,
4804 NULL
, 0xE0, NULL
, HFILL
} },
4805 { &hf_reserved_0x8000
,
4806 { "Reserved", "dmp.reserved", FT_UINT16
, BASE_DEC
,
4807 NULL
, 0x8000, NULL
, HFILL
} },
4810 static gint
*ett
[] = {
4813 &ett_envelope_version
,
4814 &ett_envelope_hop_count
,
4815 &ett_envelope_rec_present
,
4816 &ett_envelope_addr_enc
,
4817 &ett_envelope_checksum
,
4818 &ett_envelope_extensions
,
4819 &ett_envelope_msg_id_type
,
4820 &ett_envelope_msg_id
,
4821 &ett_envelope_mts_id_length
,
4822 &ett_envelope_ipm_id_length
,
4823 &ett_envelope_cont_type
,
4824 &ett_envelope_subm_time
,
4825 &ett_envelope_time_diff
,
4826 &ett_envelope_flags
,
4827 &ett_envelope_recipients
,
4828 &ett_envelope_ext_recipients
,
4829 &ett_envelope_addresses
,
4831 &ett_address_direct
,
4832 &ett_address_rec_no
,
4833 &ett_address_extended
,
4834 &ett_address_ext_form
,
4835 &ett_address_ext_rec_no
,
4836 &ett_address_ext_action
,
4837 &ett_address_ext_rep_req
,
4838 &ett_address_ext_not_req
,
4839 &ett_address_ext_type
,
4840 &ett_address_ext_length
,
4843 &ett_extension_header
,
4846 &ett_message_st_type
,
4847 &ett_message_reserved
,
4848 &ett_message_precedence
,
4849 &ett_message_importance
,
4850 &ett_message_body_format
,
4851 &ett_message_sec_class
,
4852 &ett_message_sec_pol
,
4853 &ett_message_sec_cat
,
4854 &ett_message_heading_flags
,
4855 &ett_message_exp_time
,
4858 &ett_message_sic_key
,
4859 &ett_message_sic_bitmap
,
4860 &ett_message_sic_bits
,
4863 &ett_message_body_reserved
,
4865 &ett_message_body_uncompr
,
4868 &ett_report_info_present_dr
,
4869 &ett_report_info_present_ndr
,
4870 &ett_report_addr_enc_dr
,
4871 &ett_report_addr_enc_ndr
,
4872 &ett_report_reserved
,
4873 &ett_report_del_time
,
4875 &ett_report_suppl_info
,
4879 &ett_notif_rec_time
,
4880 &ett_notif_suppl_info
,
4881 &ett_notif_acp127recip
,
4888 static ei_register_info ei
[] = {
4889 { &ei_reserved_value
, { "dmp.reserved.expert", PI_UNDECODED
, PI_WARN
, "Reserved value", EXPFILL
}},
4890 { &ei_message_sic_illegal
, { "dmp.sic.illegal", PI_UNDECODED
, PI_NOTE
, "Illegal SIC", EXPFILL
}},
4891 { &ei_analysis_ack_unexpected
, { "dmp.analysis.ack_unexpected", PI_SEQUENCE
, PI_NOTE
, "Unexpected ACK", EXPFILL
}},
4892 { &ei_analysis_ack_missing
, { "dmp.analysis.ack_missing.expert", PI_SEQUENCE
, PI_NOTE
, "Acknowledgement missing", EXPFILL
}},
4893 { &ei_analysis_msg_missing
, { "dmp.analysis.msg_missing", PI_SEQUENCE
, PI_NOTE
, "Message missing", EXPFILL
}},
4894 { &ei_analysis_retrans_no
, { "dmp.analysis.retrans_no.expert", PI_SEQUENCE
, PI_NOTE
, "Retransmission #", EXPFILL
}},
4895 { &ei_analysis_ack_dup_no
, { "dmp.analysis.dup_ack_no.expert", PI_SEQUENCE
, PI_NOTE
, "Dup ACK #", EXPFILL
}},
4896 { &ei_addr_dir_rec_no_generated
, { "dmp.rec_no.expert", PI_MALFORMED
, PI_WARN
, "Recipient number too big", EXPFILL
}},
4897 { &ei_addr_ext_rec_no_generated
, { "dmp.rec_no.expert", PI_MALFORMED
, PI_WARN
, "Recipient number too big", EXPFILL
}},
4898 { &ei_ack_reason
, { "dmp.ack_reason.expert", PI_RESPONSE_CODE
, PI_NOTE
, "ACK reason: %s", EXPFILL
}},
4899 { &ei_envelope_version_value
, { "dmp.version_value.unsupported", PI_UNDECODED
, PI_ERROR
, "Unsupported DMP Version", EXPFILL
}},
4900 { &ei_envelope_msg_id
, { "dmp.msg_id.short_id", PI_PROTOCOL
, PI_NOTE
, "Id < 4096 - should use ShortId", EXPFILL
}},
4901 { &ei_message_compr
, { "dmp.body.compression.unknown", PI_UNDECODED
, PI_WARN
, "Unknown compression algorithm", EXPFILL
}},
4902 { &ei_message_body_uncompressed
, { "dmp.body.uncompressed.fail", PI_UNDECODED
, PI_WARN
, "Error: Unable to uncompress content", EXPFILL
}},
4903 { &ei_checksum_bad
, { "dmp.checksum_bad.expert", PI_CHECKSUM
, PI_WARN
, "Bad checksum", EXPFILL
}},
4906 static uat_field_t attributes_flds
[] = {
4907 UAT_FLD_VS(dmp_security_class
,nation
, "Nation", nat_pol_id
, 0),
4908 UAT_FLD_DEC(dmp_security_class
,sec_class
, "Classification", "Security Classification"),
4909 UAT_FLD_CSTRING(dmp_security_class
,name
, "Name", "Classification Name"),
4913 uat_t
*attributes_uat
= uat_new("DMP Security Classifications",
4914 sizeof(dmp_security_class_t
),
4915 "dmp_security_classifications",
4917 (void**) &dmp_security_classes
,
4918 &num_dmp_security_classes
,
4919 UAT_AFFECTS_DISSECTION
, /* affects dissection of packets, but not set of named fields */
4920 "ChDMPSecurityClassifications",
4927 module_t
*dmp_module
;
4928 expert_module_t
* expert_dmp
;
4930 proto_dmp
= proto_register_protocol (PNAME
, PSNAME
, PFNAME
);
4932 dmp_handle
= register_dissector(PFNAME
, dissect_dmp
, proto_dmp
);
4934 proto_register_field_array (proto_dmp
, hf
, array_length (hf
));
4935 proto_register_subtree_array (ett
, array_length (ett
));
4936 expert_dmp
= expert_register_protocol(proto_dmp
);
4937 expert_register_field_array(expert_dmp
, ei
, array_length(ei
));
4938 register_init_routine (&dmp_init_routine
);
4940 /* Set default UDP ports */
4941 range_convert_str (&global_dmp_port_range
, DEFAULT_DMP_PORT_RANGE
,
4944 /* Build national values */
4945 build_national_strings ();
4947 /* Register our configuration options */
4948 dmp_module
= prefs_register_protocol (proto_dmp
, proto_reg_handoff_dmp
);
4950 prefs_register_obsolete_preference (dmp_module
, "udp_port");
4951 prefs_register_obsolete_preference (dmp_module
, "udp_port_second");
4953 prefs_register_range_preference (dmp_module
, "udp_ports",
4955 "Port numbers used for DMP traffic",
4956 &global_dmp_port_range
, MAX_UDP_PORT
);
4957 prefs_register_enum_preference (dmp_module
, "national_decode",
4958 "National decoding",
4959 "Select the type of decoding for nationally-defined values",
4960 &dmp_nat_decode
, national_decoding
,
4962 prefs_register_enum_preference (dmp_module
, "local_nation",
4963 "Nation of local server",
4964 "Select the nation of sending server. This is used when presenting"
4965 " security classification values in messages with security"
4966 " policy set to National (nation of local server)",
4967 &dmp_local_nation
, dmp_national_values
,
4969 prefs_register_uat_preference (dmp_module
, "classes_table",
4970 "National Security Classifications",
4971 "Translation table for national security classifications. This is used"
4972 " when presenting security classification values in messages with"
4973 " security policy set to National or Extended National",
4975 prefs_register_bool_preference (dmp_module
, "seq_ack_analysis",
4977 "Calculate sequence/acknowledgement analysis",
4978 &use_seq_ack_analysis
);
4979 prefs_register_bool_preference (dmp_module
, "align_ids",
4980 "Align identifiers in info list",
4981 "Align identifiers in info list"
4982 " (does not align when retransmission or"
4983 " duplicate acknowledgement indication)",
4985 prefs_register_bool_preference (dmp_module
, "subject_as_id",
4986 "Print subject as body id",
4987 "Print subject as body id in free text "
4988 "messages with subject",
4989 &dmp_subject_as_id
);
4990 prefs_register_enum_preference (dmp_module
, "struct_print",
4991 "Structured message id format",
4992 "Format of the structured message id",
4993 &dmp_struct_format
, struct_id_options
,
4995 prefs_register_uint_preference (dmp_module
, "struct_offset",
4996 "Offset to structured message id",
4997 "Used to set where the structured message "
4998 "id starts in the User Data",
4999 10, &dmp_struct_offset
);
5001 prefs_register_uint_preference (dmp_module
, "struct_length",
5002 "Fixed text string length",
5003 "Used to set length of fixed text string "
5004 "in the structured message id format "
5005 "(maximum 128 characters)",
5006 10, &dmp_struct_length
);
5009 void proto_reg_handoff_dmp (void)
5011 static range_t
*dmp_port_range
;
5012 static gboolean dmp_prefs_initialized
= FALSE
;
5014 if (!dmp_prefs_initialized
) {
5015 dmp_prefs_initialized
= TRUE
;
5017 dissector_delete_uint_range ("udp.port", dmp_port_range
, dmp_handle
);
5018 g_free (dmp_port_range
);
5021 /* Save port number for later deletion */
5022 dmp_port_range
= range_copy (global_dmp_port_range
);
5024 dissector_add_uint_range ("udp.port", dmp_port_range
, dmp_handle
);
5033 * indent-tabs-mode: nil
5036 * ex: set shiftwidth=2 tabstop=8 expandtab:
5037 * :indentSize=2:tabSize=8:noTabs=true: