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 is activated when using unreliable bearer services.
8 * Copyright 2006, Stig Bjørlykke <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
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 * - Obtain a dedicated UDP port number for DMP
34 * - Add Transmission/Retransmission statistics
41 #include <epan/packet.h>
42 #include <epan/address.h>
43 #include <epan/addr_resolv.h>
44 #include <epan/to_str.h>
45 #include <epan/prefs.h>
46 #include <epan/emem.h>
47 #include <epan/expert.h>
48 #include <epan/crc16.h>
52 #include <epan/asn1.h>
53 #include "packet-x411.h"
54 #include "packet-x420.h"
56 #define PNAME "Direct Message Profile"
60 /* Recommended UDP Port Numbers */
61 /* Default disabled */
62 #define DEFAULT_DMP_PORT_RANGE ""
64 /* Version supported */
67 /* Message Type (dmp.msg_type) */
74 /* Report Type (dmp.report_type) */
78 /* Notification Type (dmp.notif_type) */
83 /* Address Encoding (dmp.addr_enc) */
84 #define DIRECT_ADDR 0x0
85 #define EXTENDED_ADDR 0x1
87 /* Address type (internal values) */
92 /* Extended Address Form (dmp_addr_form) */
95 #define P1_EXTENDED 0x2
96 #define P2_EXTENDED 0x3
97 #define P1_P2_DIRECT 0x4
98 #define P1_DIRECT_P2_EXTENDED 0x5
99 #define P1_EXTENDED_P2_DIRECT 0x6
100 #define P1_P2_EXTENDED 0x7
102 /* Extended Address Type */
106 /* Security Policy (dmp_sec_pol) */
109 #define EXTENDED_NATIONAL 0x6
110 #define EXTENDED_MISSION 0x7
112 /* Body Format (dmp.body_format) */
113 #define FREE_TEXT 0x0
114 #define FREE_TEXT_SUBJECT 0x1
115 #define STRUCTURED 0x2
117 /* Encoded Information Types */
118 #define EIT_BILATERAL 0x3
120 /* Compression Algorithm */
121 #define ALGORITHM_NONE 0x0
122 #define ALGORITHM_ZLIB 0x1
124 /* Type of structured id to print */
125 #define STRUCT_ID_NONE 0
126 #define STRUCT_ID_UINT8 1
127 #define STRUCT_ID_UINT16 2
128 #define STRUCT_ID_UINT32 3
129 #define STRUCT_ID_UINT64 4
130 #define STRUCT_ID_STRING 5
131 #define STRUCT_ID_ZSTRING 6
133 /* Maximum lengths */
134 #define MAX_SIC_LEN 30
135 #define MAX_MSG_TYPE_LEN 46
136 #define MAX_SEC_CAT_LEN 33
137 #define MAX_ENV_FLAGS_LEN 100
138 #define MAX_STRUCT_ID_LEN 128
140 void proto_reg_handoff_dmp (void);
142 static int proto_dmp = -1;
144 static int hf_dmp_id = -1;
146 static int hf_envelope = -1;
147 static int hf_envelope_protocol_id = -1;
148 static int hf_envelope_version = -1;
149 static int hf_envelope_hop_count = -1;
150 static int hf_envelope_rec_present = -1;
151 static int hf_envelope_addr_enc = -1;
152 static int hf_envelope_checksum = -1;
153 static int hf_envelope_type = -1;
154 static int hf_envelope_msg_id = -1;
155 static int hf_envelope_subm_time = -1;
156 static int hf_envelope_subm_time_value = -1;
157 static int hf_envelope_time_diff_present = -1;
158 static int hf_envelope_time_diff = -1;
159 static int hf_envelope_time_diff_value = -1;
160 static int hf_envelope_flags = -1;
161 static int hf_envelope_content_id_discarded = -1;
162 static int hf_envelope_recip_reassign_prohib = -1;
163 static int hf_envelope_dl_expansion_prohib = -1;
164 static int hf_envelope_recipients = -1;
165 static int hf_envelope_ext_recipients = -1;
167 static int hf_message_content = -1;
168 static int hf_report_content = -1;
169 static int hf_notif_content = -1;
171 static int hf_addr_recipient = -1;
172 static int hf_addr_originator = -1;
173 static int hf_addr_reporting_name = -1;
174 static int hf_addr_dir_addr_ext = -1;
175 static int hf_addr_dir_rec_no = -1;
176 static int hf_addr_dir_rec_no1 = -1;
177 static int hf_addr_dir_rec_no2 = -1;
178 static int hf_addr_dir_rec_no3 = -1;
179 static int hf_addr_dir_rec_no_generated = -1;
180 static int hf_addr_dir_rep_req1 = -1;
181 static int hf_addr_dir_rep_req2 = -1;
182 static int hf_addr_dir_rep_req3 = -1;
183 static int hf_addr_dir_not_req1 = -1;
184 static int hf_addr_dir_not_req2 = -1;
185 static int hf_addr_dir_not_req3 = -1;
186 static int hf_addr_dir_action = -1;
187 static int hf_addr_dir_address = -1;
188 static int hf_addr_dir_address1 = -1;
189 static int hf_addr_dir_address2 = -1;
190 static int hf_addr_dir_address3 = -1;
191 static int hf_addr_dir_address_generated = -1;
193 static int hf_addr_ext_form = -1;
194 static int hf_addr_ext_action = -1;
195 static int hf_addr_ext_rep_req = -1;
196 static int hf_addr_ext_not_req = -1;
197 static int hf_addr_ext_rec_ext = -1;
198 static int hf_addr_ext_rec_no = -1;
199 static int hf_addr_ext_rec_no1 = -1;
200 static int hf_addr_ext_rec_no2 = -1;
201 static int hf_addr_ext_rec_no_generated = -1;
202 static int hf_addr_ext_address = -1;
203 static int hf_addr_ext_type = -1;
204 static int hf_addr_ext_type_ext = -1;
205 static int hf_addr_ext_length = -1;
206 static int hf_addr_ext_length1 = -1;
207 static int hf_addr_ext_length2 = -1;
208 static int hf_addr_ext_length_generated = -1;
209 static int hf_addr_ext_asn1_ber = -1;
210 static int hf_addr_ext_asn1_per = -1;
211 static int hf_addr_ext_unknown = -1;
213 static int hf_message_body = -1;
214 static int hf_message_st_type = -1;
215 static int hf_message_precedence = -1;
216 static int hf_message_importance = -1;
217 static int hf_message_body_format = -1;
218 static int hf_message_sec_class_nat = -1;
219 static int hf_message_sec_class_val = -1;
220 static int hf_message_sec_pol = -1;
221 static int hf_message_heading_flags = -1;
222 static int hf_message_auth_users = -1;
223 static int hf_message_subject_disc = -1;
224 static int hf_message_national_policy_id = -1;
225 static int hf_message_mission_policy_id = -1;
226 static int hf_message_sec_cat_nat = -1;
227 static int hf_message_sec_cat_val = -1;
228 static int hf_message_sec_cat_cl = -1;
229 static int hf_message_sec_cat_cs = -1;
230 static int hf_message_sec_cat_ex = -1;
231 static int hf_message_sec_cat_ne = -1;
232 static int hf_message_sec_cat_bit0 = -1;
233 static int hf_message_sec_cat_bit1 = -1;
234 static int hf_message_sec_cat_bit2 = -1;
235 static int hf_message_sec_cat_bit3 = -1;
236 static int hf_message_sec_cat_bit4 = -1;
237 static int hf_message_sec_cat_bit5 = -1;
238 static int hf_message_sec_cat_bit6 = -1;
239 static int hf_message_sec_cat_bit7 = -1;
240 static int hf_message_exp_time = -1;
241 static int hf_message_exp_time_val = -1;
242 static int hf_message_dtg = -1;
243 static int hf_message_dtg_sign = -1;
244 static int hf_message_dtg_val = -1;
245 static int hf_message_sic = -1;
246 static int hf_message_sic_key = -1;
247 static int hf_message_sic_key_values = -1;
248 static int hf_message_sic_key_type = -1;
249 static int hf_message_sic_key_chars = -1;
250 static int hf_message_sic_key_num = -1;
251 static int hf_message_sic_bitmap = -1;
252 static int hf_message_sic_bits = -1;
253 static int hf_message_sic_bits_any = -1;
254 static int hf_message_subj_id = -1;
255 static int hf_message_subject = -1;
256 static int hf_message_eit = -1;
257 static int hf_message_compr = -1;
258 static int hf_message_body_data = -1;
259 static int hf_message_body_plain = -1;
260 static int hf_message_bodyid_uint8 = -1;
261 static int hf_message_bodyid_uint16 = -1;
262 static int hf_message_bodyid_uint32 = -1;
263 static int hf_message_bodyid_uint64 = -1;
264 static int hf_message_bodyid_string = -1;
265 static int hf_message_bodyid_zstring = -1;
266 static int hf_message_body_structured = -1;
267 static int hf_message_body_uncompr = -1;
268 static int hf_message_body_uncompressed = -1;
270 static int hf_delivery_report = -1;
271 static int hf_non_delivery_report = -1;
272 static int hf_report_type = -1;
273 static int hf_report_info_present_dr = -1;
274 static int hf_report_addr_enc_dr = -1;
275 static int hf_report_del_time = -1;
276 static int hf_report_addr_enc_ndr = -1;
277 static int hf_report_reason = -1;
278 static int hf_report_info_present_ndr = -1;
279 static int hf_report_diagn = -1;
280 static int hf_report_suppl_info_len = -1;
281 static int hf_report_suppl_info = -1;
283 static int hf_receipt_notif = -1;
284 static int hf_non_receipt_notif = -1;
285 static int hf_other_notif = -1;
286 static int hf_notif_type = -1;
287 static int hf_notif_rec_time = -1;
288 static int hf_notif_rec_time_val = -1;
289 static int hf_notif_suppl_info_len = -1;
290 static int hf_notif_suppl_info = -1;
291 static int hf_notif_non_rec_reason = -1;
292 static int hf_notif_discard_reason = -1;
293 static int hf_notif_on_type = -1;
294 static int hf_notif_acp127 = -1;
295 static int hf_notif_acp127recip = -1;
297 static int hf_ack = -1;
298 static int hf_ack_reason = -1;
299 static int hf_ack_diagnostic = -1;
300 static int hf_ack_recips = -1;
302 static int hf_checksum = -1;
303 static int hf_checksum_good = -1;
304 static int hf_checksum_bad = -1;
306 static int hf_analysis_ack_time = -1;
307 static int hf_analysis_total_time = -1;
308 static int hf_analysis_retrans_time = -1;
309 static int hf_analysis_total_retrans_time = -1;
310 static int hf_analysis_msg_num = -1;
311 static int hf_analysis_msg_missing = -1;
312 static int hf_analysis_retrans_no = -1;
313 static int hf_analysis_ack_num = -1;
314 static int hf_analysis_ack_missing = -1;
315 static int hf_analysis_ack_dup_no = -1;
316 static int hf_analysis_rep_num = -1;
317 static int hf_analysis_rep_time = -1;
318 static int hf_analysis_not_num = -1;
319 static int hf_analysis_not_time = -1;
320 static int hf_analysis_msg_resend_from = -1;
321 static int hf_analysis_rep_resend_from = -1;
322 static int hf_analysis_not_resend_from = -1;
323 static int hf_analysis_ack_resend_from = -1;
325 static int hf_reserved_0x01 = -1;
326 static int hf_reserved_0x02 = -1;
327 static int hf_reserved_0x04 = -1;
328 static int hf_reserved_0x07 = -1;
329 static int hf_reserved_0x08 = -1;
330 static int hf_reserved_0x1F = -1;
331 static int hf_reserved_0x20 = -1;
332 static int hf_reserved_0x40 = -1;
333 static int hf_reserved_0xC0 = -1;
334 static int hf_reserved_0xE0 = -1;
335 static int hf_reserved_0x8000 = -1;
337 static gint ett_dmp = -1;
338 static gint ett_envelope = -1;
339 static gint ett_envelope_version = -1;
340 static gint ett_envelope_hop_count = -1;
341 static gint ett_envelope_rec_present = -1;
342 static gint ett_envelope_addr_enc = -1;
343 static gint ett_envelope_checksum = -1;
344 static gint ett_envelope_cont_type = -1;
345 static gint ett_envelope_subm_time = -1;
346 static gint ett_envelope_time_diff = -1;
347 static gint ett_envelope_flags = -1;
348 static gint ett_envelope_recipients = -1;
349 static gint ett_envelope_ext_recipients = -1;
350 static gint ett_envelope_addresses = -1;
352 static gint ett_address = -1;
353 static gint ett_address_direct = -1;
354 static gint ett_address_rec_no = -1;
355 static gint ett_address_extended = -1;
356 static gint ett_address_ext_form = -1;
357 static gint ett_address_ext_rec_no = -1;
358 static gint ett_address_ext_action = -1;
359 static gint ett_address_ext_rep_req = -1;
360 static gint ett_address_ext_not_req = -1;
361 static gint ett_address_ext_type = -1;
362 static gint ett_address_ext_length = -1;
364 static gint ett_content = -1;
366 static gint ett_message = -1;
367 static gint ett_message_st_type = -1;
368 static gint ett_message_reserved = -1;
369 static gint ett_message_precedence = -1;
370 static gint ett_message_importance = -1;
371 static gint ett_message_body_format = -1;
372 static gint ett_message_sec_class = -1;
373 static gint ett_message_sec_pol = -1;
374 static gint ett_message_sec_cat = -1;
375 static gint ett_message_heading_flags = -1;
376 static gint ett_message_exp_time = -1;
377 static gint ett_message_dtg = -1;
378 static gint ett_message_sic = -1;
379 static gint ett_message_sic_key = -1;
380 static gint ett_message_sic_bitmap = -1;
381 static gint ett_message_sic_bits = -1;
382 static gint ett_message_eit = -1;
383 static gint ett_message_compr = -1;
384 static gint ett_message_body_reserved = -1;
385 static gint ett_message_body = -1;
386 static gint ett_message_body_uncompr = -1;
388 static gint ett_report = -1;
389 static gint ett_report_type = -1;
390 static gint ett_report_info_present_dr = -1;
391 static gint ett_report_info_present_ndr = -1;
392 static gint ett_report_addr_enc_dr = -1;
393 static gint ett_report_addr_enc_ndr = -1;
394 static gint ett_report_reserved = -1;
395 static gint ett_report_del_time = -1;
396 static gint ett_report_reason = -1;
397 static gint ett_report_suppl_info = -1;
398 static gint ett_report_diagn = -1;
400 static gint ett_notif = -1;
401 static gint ett_notif_type = -1;
402 static gint ett_notif_rec_time = -1;
403 static gint ett_notif_suppl_info = -1;
404 static gint ett_notif_acp127recip = -1;
406 static gint ett_ack = -1;
407 static gint ett_ack_recips = -1;
409 static gint ett_checksum = -1;
411 static gint ett_analysis = -1;
413 static dissector_handle_t dmp_handle;
415 typedef struct _dmp_id_key {
421 typedef struct _dmp_id_val {
422 gint msg_type; /* Message type */
423 guint prev_msg_id; /* Previous message package num */
424 guint msg_id; /* Message package num */
425 guint ack_id; /* Acknowledgement package num */
426 guint rep_id; /* Report package num */
427 guint not_id; /* Notification package num */
428 nstime_t msg_time; /* Message receive time */
429 nstime_t first_msg_time; /* First message receive time */
430 nstime_t prev_msg_time; /* Previous message receive time */
431 nstime_t rep_not_msg_time; /* Report or Notification time */
432 guint32 msg_resend_count; /* Message resend counter */
433 guint32 ack_resend_count; /* Acknowledgement resend counter */
436 static GHashTable *dmp_id_hash_table = NULL;
438 /* Global values used in several functions */
439 static struct dmp_data {
455 gboolean ack_rec_present;
459 /* User definable values */
460 static range_t *global_dmp_port_range;
461 static gboolean use_seq_ack_analysis = TRUE;
462 static gboolean dmp_align = FALSE;
463 static gboolean dmp_subject_as_id = FALSE;
464 static gint dmp_struct_format = STRUCT_ID_NONE;
465 static guint dmp_struct_offset = 0;
466 static guint dmp_struct_length = 1;
468 static const true_false_string addr_enc = {
469 "Use Extended Encoding", "Use Direct Encoding"
472 static const true_false_string used_notused = {
476 static const true_false_string checksum = {
477 "Checksum used", "Checksum not used"
480 static const true_false_string set_notset = {
484 static const true_false_string yes_no = {
488 static const true_false_string dtg_sign = {
492 static const true_false_string report_type = {
493 "Non-Delivery Report", "Delivery Report"
496 static const true_false_string present_values = {
500 static const value_string version_vals[] = {
511 static const value_string type_vals[] = {
513 { 0x1, "Message (E-Mail)" },
515 { 0x3, "Notification" },
516 { 0x4, "Acknowledgement" },
517 { 0x5, "Unknown Content" },
518 { 0x6, "Unknown Content" },
519 { 0x7, "Unknown Content" },
522 static const value_string report_vals[] = {
523 { 0x0, "No Report" },
524 { 0x1, "Delivery Report" },
525 { 0x2, "Non-Delivery Report" },
529 static const value_string report_vals_ext[] = {
530 { 0x0, "No Report" },
531 { 0x1, "Delivery Report" },
532 { 0x2, "Non-Delivery Report" },
533 { 0x3, "Recipient Number Extended" },
536 /* Note the space in front of these values */
537 static const value_string report_vals_short[] = {
542 static const value_string notif_vals[] = {
543 { 0x0, "No Notification" },
544 { 0x1, "Receipt Notification" },
545 { 0x2, "Non-Receipt Notification" },
549 static const value_string notif_vals_ext[] = {
550 { 0x0, "No Notification" },
551 { 0x1, "Receipt Notification" },
552 { 0x2, "Non-Receipt Notification" },
553 { 0x3, "Direct Address Extended" },
556 /* Note the space in front of these values */
557 static const value_string notif_vals_short[] = {
562 static const value_string notif_type [] = {
563 { 0x0, "Receipt Notification (RN)" },
564 { 0x1, "Non-Receipt Notification (NRN)" },
565 { 0x2, "Other Notification (ON)" },
566 { 0x3, "Unknown Notification" },
569 static const value_string addr_type_str [] = {
571 { P1_ADDRESS, "P1 " },
572 { P2_ADDRESS, "P2/P722 " },
575 static const value_string addr_form [] = {
576 { 0x0, "P1 address only, Direct Address" },
577 { 0x1, "P22/P722 address only, Direct Address" },
578 { 0x2, "P1 address only, Extended Address" },
579 { 0x3, "P22/P722 address only, Extended Address" },
580 { 0x4, "P1 and P22/P722 addresses, Direct Address" },
581 { 0x5, "P1, Direct Address and P22/P722 addresses, Extended Address" },
582 { 0x6, "P1, Extended ADdress and P22/P722 addresses, Direct Address" },
583 { 0x7, "P1 and P22/P722 addresses, Extended Address" },
586 static const value_string addr_form_orig [] = {
587 { 0x0, "Direct Address" },
589 { 0x2, "Extended Address" },
597 static const value_string ext_addr_type [] = {
598 { 0x0, "ASN.1 BER-encoded OR-name" },
599 { 0x1, "ASN.1 PER-encoded OR-name" },
605 { 0x7, "Address Length Extended" },
608 static const value_string ext_addr_type_ext [] = {
609 { 0x0, "ASN.1 BER-encoded OR-name" },
610 { 0x1, "ASN.1 PER-encoded OR-name" },
619 static const value_string ext_addr_type_short [] = {
620 { 0x0, "OR-name (BER)" },
621 { 0x1, "OR-name (PER)" },
630 static const value_string message_type_vals[] = {
631 { 0x0, "Operation" },
637 static const value_string precedence[] = {
641 { 0x3, "Immediate" },
644 { 0x6, "Priority, Info Precedence: Routine" },
645 { 0x7, "Immediate, Info Precedence: Routine" },
648 static const value_string importance[] = {
659 static const value_string sec_class[] = {
661 { 0x1, "Unclassified" },
663 { 0x3, "Restricted" },
665 { 0x5, "Confidential" },
667 { 0x7, "Top secret" },
670 static const value_string sec_pol[] = {
671 { 0x0, "Network defined" },
672 { 0x1, "Network defined" },
673 { 0x2, "Network defined" },
674 { 0x3, "Network defined" },
676 { 0x5, "National (nation of local server)" },
677 { 0x6, "Extended, National" },
678 { 0x7, "Extended, Mission Defined" },
681 static const value_string nat_pol_id[] = {
683 { 0x01, "Belgium (BE)" },
684 { 0x02, "Bulgaria (BG)" },
685 { 0x03, "Canada (CA)" },
686 { 0x04, "Czech Republic (CZ)" },
687 { 0x05, "Denmark (DK)" },
688 { 0x06, "Estonia (ES)" },
689 { 0x07, "France (FR)" },
690 { 0x08, "Germany (DE)" },
691 { 0x09, "Greece (GR)" },
692 { 0x0A, "Hungary (HU)" },
693 { 0x0B, "Iceland (IS)" },
694 { 0x0C, "Italy (IT)" },
695 { 0x0D, "Latvia (LV)" },
696 { 0x0E, "Lithuania (LT)" },
697 { 0x0F, "Luxemburg (LU)" },
698 { 0x10, "Netherlands (NL)" },
699 { 0x11, "Norway (NO)" },
700 { 0x12, "Poland (PL)" },
701 { 0x13, "Portugal (PT)" },
702 { 0x14, "Romania (RO)" },
703 { 0x15, "Slovakia (SK)" },
704 { 0x16, "Slovenia (SI)" },
705 { 0x17, "Spain (ES)" },
706 { 0x18, "Turkey (TR)" },
707 { 0x19, "United Kingdom (GB)" },
708 { 0x1A, "United States (US)" },
709 { 0xFF, "Reserved" },
712 static const value_string sic_key_type[] = {
713 { 0xc, "2 or more 3-character SICs" },
714 { 0xd, "1 or more 3-to-8 character SICs" },
717 static const true_false_string sic_key_chars = {
718 "Any", "[A-Z0-9] only"
721 static const value_string sic_key_num[] = {
733 static const value_string sic_bit_vals[] = {
734 { 0, "length:6, bytes:4" },
735 { 1, "length:6, bytes:4" },
736 { 2, "length:6, bytes:4" },
737 { 3, "length:6, bytes:4" },
738 { 4, "length:6, bytes:4" },
739 { 5, "length:6, bytes:4" },
740 { 6, "length:6, bytes:4" },
741 { 7, "length:6, bytes:4" },
742 { 8, "length:6, bytes:4" },
744 { 10, "length:5, bytes:4" },
745 { 11, "length:8, bytes:6" },
746 { 12, "length:4, bytes:3" },
747 { 13, "length:4, bytes:3" },
748 { 14, "length:7, bytes:5" },
749 { 15, "length:7, bytes:5" },
752 static const value_string sic_bit_any_vals[] = {
753 { 0, "length:5, bytes:4" },
754 { 1, "length:5, bytes:4" },
755 { 2, "length:5, bytes:4" },
756 { 3, "length:5, bytes:4" },
757 { 4, "length:5, bytes:4" },
758 { 5, "length:5, bytes:4" },
759 { 6, "length:5, bytes:4" },
760 { 7, "length:5, bytes:4" },
761 { 8, "length:5, bytes:4" },
762 { 9, "length:8, bytes:7" },
763 { 10, "length:4, bytes:4" },
764 { 11, "length:7, bytes:6" },
765 { 12, "length:6, bytes:5" },
766 { 13, "length:6, bytes:5" },
767 { 14, "length:6, bytes:5" },
768 { 15, "length:6, bytes:5" },
771 static const value_string body_format_vals[] = {
772 { 0x0, "Free text" },
773 { 0x1, "Free text including subject" },
774 { 0x2, "Structured" },
778 static const value_string eit_vals[] = {
781 { 0x2, "General text" },
782 { 0x3, "Bilaterally defined (binary data)" },
789 static const value_string compression_vals[] = {
790 { 0x0, "No compression" },
791 { 0x1, "ZLib compressed" },
796 static const value_string ack_reason [] = {
797 { 0x00, "Successful, positive acknowledgement" },
798 { 0x01, "Unspecified error" },
799 { 0x02, "Checksum incorrect" },
802 static const value_string non_del_reason [] = {
803 { 0x3D, "Unknown reason" },
804 { 0x3E, "Reason code greater than 0x3c (60)" },
805 { 0x3F, "Reserved" },
808 static const value_string non_del_diagn [] = {
809 { 0x7C, "Diagnostic not specified" },
810 { 0x7D, "Unknown diagnostic" },
811 { 0x7E, "Diagnostic code greater than 0x7b (123)" },
812 { 0x7F, "Reserved" },
815 static const value_string discard_reason [] = {
816 { 0xFE, "Discard Reason absent" },
817 { 0xFF, "Reserved" },
820 static const value_string on_type [] = {
821 { 0x00, "acp127-nn" },
822 { 0x01, "acp127-pn" },
823 { 0x02, "acp127-tn" },
826 static const value_string ack_msg_type [] = {
827 { STANAG, " (message)" },
828 { IPM, " (e-mail)" },
829 { REPORT, " (report)" },
830 { NOTIF, " (notif)" },
834 static enum_val_t struct_id_options[] = {
835 { "none", "None", STRUCT_ID_NONE },
836 { "1byte", "1 Byte value", STRUCT_ID_UINT8 },
837 { "2byte", "2 Byte value", STRUCT_ID_UINT16 },
838 { "4byte", "4 Byte value", STRUCT_ID_UINT32 },
839 { "8byte", "8 Byte value", STRUCT_ID_UINT64 },
840 { "fstring", "Fixed text string", STRUCT_ID_STRING },
841 { "zstring", "Zero terminated text string", STRUCT_ID_ZSTRING },
845 static const gchar *msg_type_to_str (void)
847 gchar *msg_type = ep_alloc (MAX_MSG_TYPE_LEN);
848 gboolean have_msg = FALSE;
850 switch (dmp.msg_type) {
853 /* Include message type and precedence */
854 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "%s (%s) [%s]",
855 val_to_str (dmp.msg_type, type_vals, "Unknown"),
856 val_to_str (dmp.st_type, message_type_vals, "Unknown"),
857 (dmp.prec == 0x6 || dmp.prec == 0x7) ?
858 val_to_str (dmp.prec-4, precedence, "Unknown") :
859 val_to_str (dmp.prec, precedence, "Unknown"));
863 /* Include importance */
864 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "%s [%s]",
865 val_to_str (dmp.msg_type, type_vals, "Unknown"),
866 val_to_str (dmp.prec, importance, "Unknown"));
870 /* Include report types included */
871 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "Report (%s%s%s)",
872 dmp.dr ? "DR" : "", (dmp.dr && dmp.ndr) ? " and " : "",
873 dmp.ndr ? "NDR" : "");
877 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "%s",
878 val_to_str (dmp.notif_type, notif_type, "Unknown"));
882 /* If we have msg_time we have a matching packet */
883 have_msg = (dmp.id_val &&
884 (dmp.id_val->msg_time.secs>0 || dmp.id_val->msg_time.nsecs>0));
885 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "Acknowledgement%s%s",
886 have_msg ? val_to_str (dmp.id_val->msg_type, ack_msg_type,
887 " (unknown:%d)") : "",
888 dmp.ack_reason ? " [negative]" : "");
892 g_snprintf (msg_type, MAX_MSG_TYPE_LEN, "Unknown");
899 static const gchar *non_del_reason_str (guint32 value)
902 /* Standard values according to X.411 */
903 return val_to_str (value, x411_NonDeliveryReasonCode_vals, "Unknown");
905 return val_to_str (value, non_del_reason, "Unknown");
909 static const gchar *non_del_diagn_str (guint32 value)
912 /* Standard values according to X.411 */
913 return val_to_str (value, x411_NonDeliveryDiagnosticCode_vals, "Unknown");
915 return val_to_str (value, non_del_diagn, "Unknown");
919 static const gchar *nrn_reason_str (guint32 value)
921 /* Standard values according to X.420 */
922 return val_to_str (value, x420_NonReceiptReasonField_vals, "Reserved");
925 static const gchar *discard_reason_str (guint32 value)
928 /* Standard values according to X.420 */
929 return val_to_str (value, x420_DiscardReasonField_vals, "Reserved");
931 return val_to_str (value, discard_reason, "Unknown");
935 /* Ref chapter 6.2.8.10 TimeDifference */
936 static gint32 dmp_dec_time_diff (guint8 dmp_time_diff)
938 gint32 time_diff = 0;
940 if (dmp_time_diff <= 0x01) {
941 /* Reserved - low value */
943 } else if (dmp_time_diff <= 0x1D) {
944 /* Number of 2-second units (2-58 seconds) */
945 time_diff = dmp_time_diff * 2;
946 } else if (dmp_time_diff <= 0x91) {
947 /* Number of 15-second units (1 min - 29 min 45 sec) */
948 time_diff = (dmp_time_diff - 0x1D + 3) * 15;
949 } else if (dmp_time_diff <= 0xDF) {
950 /* Number of 5-minute units (30 min - 6 hours 55 min) */
951 time_diff = (dmp_time_diff - 0x91 + 5) * 5*60;
952 } else if (dmp_time_diff <= 0xF7) {
953 /* Number of 30-minute units (7 hours - 18 hours 30 min) */
954 time_diff = (dmp_time_diff - 0xDF + 7) * 30*60;
956 /* Reserved - high value */
964 * Ref chapter 6.3.7.2.10 ExpiryTime
965 * and chapter 6.3.9.2.2 DeliveryTime
967 static gint32 dmp_dec_exp_del_time (guint8 timev, gboolean expiry_time)
969 gint32 time_value = 0;
971 if (expiry_time && (timev == 0x00)) {
974 } else if (timev <= 0x1D) {
975 /* Number of 2-second units (2-58 seconds) */
976 time_value = timev * 2;
977 } else if (timev <= 0x91) {
978 /* Number of 15-second units (1 min - 29 min 45 sec) */
979 time_value = (timev - 0x1D + 3) * 15;
980 } else if (timev <= 0xBB) {
981 /* Number of 5-minute units (30 min - 3 hours 55 min) */
982 time_value = (timev - 0x91 + 5) * 5*60;
983 } else if (timev <= 0xE3) {
984 /* Number of 30-minute units (4 hours - 23 hours 30 min) */
985 time_value = (timev - 0xBB + 7) * 30*60;
986 } else if (timev < 0xFF) {
987 /* Number of 2-hour units (24 - 78 hours) */
988 time_value = (timev - 0xE3 + 11) * 2*3600;
997 static gint32 dmp_dec_exp_time (guint8 expiry_time)
999 return dmp_dec_exp_del_time (expiry_time, TRUE);
1002 static gint32 dmp_dec_del_time (guint8 delivery_time)
1004 return dmp_dec_exp_del_time (delivery_time, FALSE);
1007 /* Ref chapter 6.3.7.2.11 DTG */
1008 static gint32 dmp_dec_dtg (guint32 dtg)
1015 } else if (dtg <= 0x3C) {
1016 /* Number of minutes (0-59 min) */
1017 value = (dtg - 1) * 60;
1018 } else if (dtg <= 0x64) {
1019 /* Number of 15-minute units (1 hour - 10 hours 45 min) */
1020 value = (dtg - 0x3C + 3) * 15 * 60;
1021 } else if (dtg < 0x7F) {
1022 /* Number of hours (11-36 hours) */
1023 value = (dtg - 0x64 + 10) * 3600;
1033 * Ref chapter 7.10.11.1 Submission time
1035 * start_time (current time)
1036 * delta1 = E (encoded submission time)
1037 * delta2 = C (encoded current time)
1038 * 0x01C2 = Pn + 15min (maximum point for S1)
1039 * 0x7E38 = Pn+1 - 15min (minimum point for S3)
1040 * 0x7FF8 = Pn+1 (length of P (period))
1042 static gint32 dmp_dec_subm_time (guint16 delta1, gint32 start_time)
1044 gint32 subm_time = start_time;
1047 delta2 = (guint16) ((subm_time / 2) % 0x7FF8);
1049 if ((delta1 < 0x01C2) && (delta2 >= delta1 + 0x7E38)) {
1050 subm_time += 2 * (0x7FF8 - delta2 + delta1);
1051 } else if ((delta1 >= 0x01C2) && (delta2 < delta1 - 0x01C2)) {
1052 subm_time -= 2 * (0x7FF8 - delta1 + delta2);
1054 subm_time -= 2 * (delta2 - delta1);
1060 /* Ref chapter 6.3.7.2.12 SIC */
1061 static gboolean dmp_dec_xbyte_sic (guint64 bin, gchar *sic,
1062 guint8 no_char, gboolean any)
1064 gboolean failure = FALSE;
1069 if (no_char >= MAX_SIC_LEN) {
1070 /* Illegal length */
1071 g_snprintf (sic, MAX_SIC_LEN, "Illegal length: %d", no_char);
1081 for (i = 0; i < no_char; i++) {
1082 p = (guint64) pow (multiplier, no_char - 1 - i);
1085 sic[i] = (gchar) tmp;
1088 } else if (sic[i] <= 35) {
1089 sic[i] += ('A' - 10);
1093 } else if (sic[i] <= 61) {
1094 sic[i] += ('a' - 36);
1095 } else if (sic[i] == 62) {
1097 } else if (sic[i] == 63) {
1099 } else if (sic[i] == 64) {
1101 } else if (sic[i] == 65) {
1103 } else if (sic[i] == 66) {
1105 } else if (sic[i] == 67) {
1107 } else if (sic[i] == 68) {
1109 } else if (sic[i] == 69) {
1111 } else if (sic[i] == 70) {
1113 } else if (sic[i] == 71) {
1115 } else if (sic[i] == 72) {
1117 } else if (sic[i] == 73) {
1129 static guint dmp_id_hash (gconstpointer k)
1131 dmp_id_key *dmpx=(dmp_id_key *)k;
1135 static gint dmp_id_hash_equal (gconstpointer k1, gconstpointer k2)
1137 dmp_id_key *dmp1=(dmp_id_key *)k1;
1138 dmp_id_key *dmp2=(dmp_id_key *)k2;
1139 if (dmp1->id != dmp2->id)
1142 return (ADDRESSES_EQUAL (&dmp1->src, &dmp2->src) &&
1143 ADDRESSES_EQUAL (&dmp1->dst, &dmp2->dst));
1146 static void register_dmp_id (packet_info *pinfo, guint8 reason)
1148 dmp_id_val *dmp_data = NULL, *pkg_data = NULL;
1149 dmp_id_key *dmp_key = NULL;
1150 nstime_t msg_time = { 0, 0 };
1153 if (pinfo->in_error_pkt) {
1154 /* No analysis of error packets */
1158 dmp_key = se_alloc (sizeof (dmp_id_key));
1160 if (!pinfo->fd->flags.visited &&
1161 (dmp.msg_type == REPORT || dmp.msg_type == NOTIF))
1163 /* Try to match corresponding message */
1164 dmp_key->id = (guint) dmp.subj_id;
1165 SE_COPY_ADDRESS(&dmp_key->src, &(pinfo->dst));
1166 SE_COPY_ADDRESS(&dmp_key->dst, &(pinfo->src));
1168 dmp_data = (dmp_id_val *) g_hash_table_lookup (dmp_id_hash_table, dmp_key);
1172 if (dmp_data->prev_msg_id > 0) {
1173 msg_id = dmp_data->prev_msg_id;
1175 msg_id = dmp_data->msg_id;
1177 msg_time = dmp_data->msg_time;
1181 if (dmp.msg_type == ACK) {
1182 dmp_key->id = (guint) dmp.subj_id;
1183 SE_COPY_ADDRESS(&dmp_key->src, &(pinfo->dst));
1184 SE_COPY_ADDRESS(&dmp_key->dst, &(pinfo->src));
1186 dmp_key->id = (guint) dmp.msg_id;
1187 SE_COPY_ADDRESS(&dmp_key->src, &(pinfo->src));
1188 SE_COPY_ADDRESS(&dmp_key->dst, &(pinfo->dst));
1191 dmp_data = (dmp_id_val *) g_hash_table_lookup (dmp_id_hash_table, dmp_key);
1193 if (!pinfo->fd->flags.visited) {
1195 if (dmp.msg_type == ACK) {
1196 /* Only save this data if positive ack */
1198 if (dmp_data->ack_id == 0) {
1199 /* Only save reference to first ACK */
1200 dmp_data->ack_id = pinfo->fd->num;
1202 /* Only count when resending */
1203 dmp_data->ack_resend_count++;
1207 /* Message resent */
1208 dmp_data->msg_resend_count++;
1209 dmp_data->prev_msg_id = pinfo->fd->num;
1210 dmp_data->prev_msg_time = dmp_data->msg_time;
1211 dmp_data->msg_time = pinfo->fd->abs_ts;
1215 dmp_data = se_alloc (sizeof (dmp_id_val));
1216 memset (dmp_data, 0, sizeof (dmp_id_val));
1217 dmp_data->msg_type = dmp.msg_type;
1219 if (dmp.msg_type == ACK) {
1220 /* No matching message for this ack */
1221 dmp_data->ack_id = pinfo->fd->num;
1223 dmp_data->first_msg_time = pinfo->fd->abs_ts;
1224 dmp_data->msg_time = pinfo->fd->abs_ts;
1226 if (dmp.msg_type == REPORT) {
1227 dmp_data->rep_id = pinfo->fd->num;
1228 dmp_data->msg_id = msg_id;
1229 dmp_data->rep_not_msg_time = msg_time;
1230 } else if (dmp.msg_type == NOTIF) {
1231 dmp_data->not_id = pinfo->fd->num;
1232 dmp_data->msg_id = msg_id;
1233 dmp_data->rep_not_msg_time = msg_time;
1235 dmp_data->msg_id = pinfo->fd->num;
1238 g_hash_table_insert (dmp_id_hash_table, dmp_key, dmp_data);
1242 pkg_data = se_alloc (sizeof (dmp_id_val));
1243 *pkg_data = *dmp_data;
1244 p_add_proto_data (pinfo->fd, proto_dmp, pkg_data);
1246 /* Fetch last values from data saved in packet */
1247 pkg_data = p_get_proto_data (pinfo->fd, proto_dmp);
1249 if (dmp_data && dmp.msg_type != ACK && pkg_data->ack_id == 0) {
1250 pkg_data->ack_id = dmp_data->ack_id;
1254 DISSECTOR_ASSERT (pkg_data);
1255 dmp.id_val = pkg_data;
1258 static void dmp_add_seq_ack_analysis (tvbuff_t *tvb, packet_info *pinfo,
1259 proto_tree *dmp_tree, gint offset)
1261 proto_tree *analysis_tree = NULL;
1262 proto_item *en = NULL, *eh = NULL;
1265 if (dmp.msg_type > ACK || (dmp.msg_type < ACK && !dmp.checksum) ||
1266 dmp.id_val == NULL || pinfo->in_error_pkt)
1268 /* No need for seq/ack analysis */
1272 en = proto_tree_add_text (dmp_tree, tvb, 0, 0, "SEQ/ACK analysis");
1273 PROTO_ITEM_SET_GENERATED (en);
1274 analysis_tree = proto_item_add_subtree (en, ett_analysis);
1276 if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
1277 (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF)) {
1278 if (dmp.id_val->ack_id) {
1279 en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_num, tvb,
1280 0, 0, dmp.id_val->ack_id);
1281 PROTO_ITEM_SET_GENERATED (en);
1282 if (!dmp.checksum) {
1283 proto_item_append_text (en, " (unexpected)");
1284 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1287 } else if (dmp.checksum && !dmp.id_val->msg_resend_count) {
1288 en = proto_tree_add_item (analysis_tree,
1289 hf_analysis_ack_missing,
1290 tvb, offset, 0, FALSE);
1291 if (pinfo->fd->flags.visited) {
1292 /* We do not know this on first visit and we do not want to
1293 add a entry in the "Expert Severity Info" for this note */
1294 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1295 "Acknowledgement missing");
1296 PROTO_ITEM_SET_GENERATED (en);
1300 if (dmp.msg_type == REPORT) {
1301 if (dmp.id_val->msg_id) {
1302 en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_num,
1303 tvb, 0, 0, dmp.id_val->msg_id);
1304 PROTO_ITEM_SET_GENERATED (en);
1306 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->rep_not_msg_time);
1307 en = proto_tree_add_time (analysis_tree, hf_analysis_rep_time,
1309 PROTO_ITEM_SET_GENERATED (en);
1311 en = proto_tree_add_item (analysis_tree, hf_analysis_msg_missing,
1313 PROTO_ITEM_SET_GENERATED (en);
1315 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1318 } else if (dmp.msg_type == NOTIF) {
1319 if (dmp.id_val->msg_id) {
1320 en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_num,
1321 tvb, 0, 0, dmp.id_val->msg_id);
1322 PROTO_ITEM_SET_GENERATED (en);
1324 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->rep_not_msg_time);
1325 en = proto_tree_add_time (analysis_tree, hf_analysis_not_time,
1327 PROTO_ITEM_SET_GENERATED (en);
1329 en = proto_tree_add_item (analysis_tree, hf_analysis_msg_missing,
1331 PROTO_ITEM_SET_GENERATED (en);
1333 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1338 if (dmp.id_val->msg_resend_count) {
1339 en = proto_tree_add_uint (analysis_tree, hf_analysis_retrans_no,
1340 tvb, 0, 0, dmp.id_val->msg_resend_count);
1341 PROTO_ITEM_SET_GENERATED (en);
1343 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1344 "Retransmission #%d",
1345 dmp.id_val->msg_resend_count);
1347 if (dmp.msg_type == REPORT) {
1348 en = proto_tree_add_uint (analysis_tree, hf_analysis_rep_resend_from,
1349 tvb, 0, 0, dmp.id_val->rep_id);
1350 } else if (dmp.msg_type == NOTIF) {
1351 en = proto_tree_add_uint (analysis_tree, hf_analysis_not_resend_from,
1352 tvb, 0, 0, dmp.id_val->not_id);
1354 en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_resend_from,
1355 tvb, 0, 0, dmp.id_val->msg_id);
1357 PROTO_ITEM_SET_GENERATED (en);
1359 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->prev_msg_time);
1360 en = proto_tree_add_time (analysis_tree, hf_analysis_retrans_time,
1362 PROTO_ITEM_SET_GENERATED (en);
1364 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->first_msg_time);
1365 eh = proto_tree_add_time (analysis_tree, hf_analysis_total_retrans_time,
1367 PROTO_ITEM_SET_GENERATED (eh);
1369 if (dmp.id_val->first_msg_time.secs == dmp.id_val->prev_msg_time.secs &&
1370 dmp.id_val->first_msg_time.nsecs == dmp.id_val->prev_msg_time.nsecs) {
1371 /* Time values does not differ, hide the total time */
1372 PROTO_ITEM_SET_HIDDEN (eh);
1375 } else if (dmp.msg_type == ACK) {
1376 if (dmp.id_val->msg_type != ACK) {
1377 if (dmp.id_val->msg_type == REPORT) {
1378 en = proto_tree_add_uint (analysis_tree, hf_analysis_rep_num,
1379 tvb, 0, 0, dmp.id_val->rep_id);
1380 } else if (dmp.id_val->msg_type == NOTIF) {
1381 en = proto_tree_add_uint (analysis_tree, hf_analysis_not_num,
1382 tvb, 0, 0, dmp.id_val->not_id);
1384 en = proto_tree_add_uint (analysis_tree, hf_analysis_msg_num,
1385 tvb, 0, 0, dmp.id_val->msg_id);
1387 PROTO_ITEM_SET_GENERATED (en);
1389 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->msg_time);
1390 en = proto_tree_add_time (analysis_tree, hf_analysis_ack_time,
1392 PROTO_ITEM_SET_GENERATED (en);
1394 nstime_delta (&ns, &pinfo->fd->abs_ts, &dmp.id_val->first_msg_time);
1395 eh = proto_tree_add_time (analysis_tree, hf_analysis_total_time,
1397 PROTO_ITEM_SET_GENERATED (eh);
1399 if (dmp.id_val->first_msg_time.secs == dmp.id_val->msg_time.secs &&
1400 dmp.id_val->first_msg_time.nsecs == dmp.id_val->msg_time.nsecs) {
1401 /* Time values does not differ, hide the total time */
1402 PROTO_ITEM_SET_HIDDEN (eh);
1404 /* Different times, add a reference to the message we have ack'ed */
1405 proto_item_append_text (en, " (from frame %d)",
1406 dmp.id_val->prev_msg_id);
1409 en = proto_tree_add_item (analysis_tree, hf_analysis_msg_missing,
1411 PROTO_ITEM_SET_GENERATED (en);
1413 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1417 if (dmp.id_val->ack_resend_count) {
1418 en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_dup_no,
1419 tvb, 0, 0, dmp.id_val->ack_resend_count);
1420 PROTO_ITEM_SET_GENERATED (en);
1422 expert_add_info_format (pinfo, en, PI_SEQUENCE, PI_NOTE,
1423 "Dup ACK #%d", dmp.id_val->ack_resend_count);
1425 en = proto_tree_add_uint (analysis_tree, hf_analysis_ack_resend_from,
1426 tvb, 0, 0, dmp.id_val->ack_id);
1427 PROTO_ITEM_SET_GENERATED (en);
1432 /* Ref chapter 6.3.7.2.12 SIC */
1433 static gint dissect_dmp_sic (tvbuff_t *tvb, packet_info *pinfo,
1434 proto_tree *message_tree, gint offset)
1436 proto_tree *sic_tree = NULL, *bitmap_tree = NULL, *key_tree = NULL;
1437 proto_item *sf = NULL, *bf = NULL, *kf = NULL;
1439 guint8 key, bitmap, no, i, length = 0;
1440 gboolean any, no_sic = FALSE, failure = FALSE;
1441 gint bytes = 0, boffset = offset;
1444 key = tvb_get_guint8 (tvb, offset);
1445 sic = ep_alloc (MAX_SIC_LEN);
1448 /* 2 bytes, single 3-character SIC, characters [A-Z0-9] only */
1450 value = tvb_get_ntohs (tvb, offset);
1451 failure = dmp_dec_xbyte_sic (value, sic, 3, FALSE);
1452 sf = proto_tree_add_string_format (message_tree, hf_message_sic, tvb,
1454 "SIC: %s [A-Z0-9 only]%s", sic,
1455 failure ? " (invalid)": "");
1457 expert_add_info_format (pinfo, sf, PI_UNDECODED, PI_NOTE, "Illegal SIC");
1461 } else if (key <= 0xBD) {
1462 /* 3 bytes, single 3-character SIC, any valid character */
1464 value = tvb_get_ntohl (tvb, offset);
1465 value = (value >> 8) & 0x48FFFF;
1466 failure = dmp_dec_xbyte_sic (value, sic, 3, TRUE);
1467 sf = proto_tree_add_string_format (message_tree, hf_message_sic, tvb,
1469 "SIC: %s [any character]%s", sic,
1470 failure ? " (invalid)": "");
1472 expert_add_info_format (pinfo, sf, PI_UNDECODED, PI_NOTE, "Illegal SIC");
1476 } else if (key <= 0xBF) {
1477 /* Reserved (not used) */
1478 g_snprintf (sic, MAX_SIC_LEN, "Reserved");
1481 } else if (key <= 0xCF) {
1482 /* 2 or more 3-character SICs */
1484 sf = proto_tree_add_item (message_tree, hf_message_sic_key, tvb,
1486 sic_tree = proto_item_add_subtree (sf, ett_message_sic);
1488 kf = proto_tree_add_item (sic_tree, hf_message_sic_key_values, tvb, offset,
1490 key_tree = proto_item_add_subtree (kf, ett_message_sic_key);
1492 proto_tree_add_item (key_tree, hf_message_sic_key_type, tvb, offset,
1494 proto_tree_add_item (key_tree, hf_message_sic_key_chars, tvb, offset,
1496 proto_tree_add_item (key_tree, hf_message_sic_key_num, tvb, offset,
1501 no = (key & 0x07) + 1;
1502 for (i = 0; i < no; i++) {
1504 value = tvb_get_ntohl (tvb, offset);
1505 value = (value >> 8) & 0x48FFFF;
1508 value = tvb_get_ntohs (tvb, offset);
1511 failure = dmp_dec_xbyte_sic (value, sic, 3, any);
1512 bf = proto_tree_add_string_format (sic_tree, hf_message_sic, tvb,
1514 "SIC %d: %s%s", i + 1, sic,
1515 failure ? " (invalid)": "");
1517 expert_add_info_format (pinfo, bf, PI_UNDECODED, PI_NOTE,
1522 proto_item_append_text (sf, ": %d (3 %s character)", no,
1523 any ? "any" : "[A-Z0-9]");
1525 } else if (key <= 0xDF) {
1526 /* 1 or more 3 to 8 character SICs */
1528 sf = proto_tree_add_item (message_tree, hf_message_sic_key, tvb,
1530 sic_tree = proto_item_add_subtree (sf, ett_message_sic);
1532 kf = proto_tree_add_item (sic_tree, hf_message_sic_key_values, tvb, offset,
1534 key_tree = proto_item_add_subtree (kf, ett_message_sic_key);
1536 proto_tree_add_item (key_tree, hf_message_sic_key_type, tvb, offset,
1538 proto_tree_add_item (key_tree, hf_message_sic_key_chars, tvb, offset,
1540 proto_tree_add_item (key_tree, hf_message_sic_key_num, tvb, offset,
1544 bitmap = tvb_get_guint8 (tvb, offset);
1545 bf = proto_tree_add_uint_format (sic_tree, hf_message_sic_bitmap, tvb,
1547 "Length Bitmap: 0x%2.2x", bitmap);
1548 bitmap_tree = proto_item_add_subtree (bf, ett_message_sic_bitmap);
1549 proto_tree_add_item (bitmap_tree, hf_message_sic_bitmap, tvb, offset,
1553 no = (key & 0x07) + 1;
1556 for (i = 0; i < no; i++) {
1557 if (bitmap & (1 << (7 - i))) {
1558 /* 4 - 8 character */
1559 key = tvb_get_guint8 (tvb, offset);
1561 /* Any valid characters */
1562 if ((key & 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1565 value = tvb_get_ntohl (tvb, offset) & 0x0FFFFFFF;
1566 } else if ((key & 0xC0) == 0xC0) { /* bit 7-4: 11xx */
1569 value = ((guint64)key & 0x3F)<<32|tvb_get_ntohl (tvb, offset + 1);
1570 } else if ((key & 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1573 value = ((guint64)tvb_get_ntohs (tvb, offset) & 0x0FFF) << 32 |
1574 tvb_get_ntohl (tvb, offset + 2);
1575 } else if ((key & 0xF0) == 0x90) { /* bit 7-4: 1001 */
1578 value = ((guint64)(tvb_get_ntohl (tvb, offset)>>8) & 0x0FFF)<<32 |
1579 tvb_get_ntohl (tvb, offset + 3);
1580 } else { /* bit 7-4: 0xxx or 1000 */
1583 value = tvb_get_ntohl (tvb, offset);
1586 /* Characterts [A-Z0-9] only */
1587 if ((key & 0xE0) == 0xC0) { /* bit 7-4: 110x */
1590 value = (tvb_get_ntohl (tvb, offset) >> 8) & 0x1FFFFF;
1591 } else if ((key & 0xF0) == 0xA0) { /* bit 7-4: 1010 */
1594 value = tvb_get_ntohl (tvb, offset) & 0x0FFFFFFF;
1595 } else if ((key & 0xE0) == 0xE0) { /* bit 7-4: 111x */
1598 value = ((guint64)key & 0x1F)<<32 | tvb_get_ntohl (tvb, offset +1);
1599 } else if ((key & 0xF0) == 0xB0) { /* bit 7-4: 1011 */
1602 value = ((guint64)tvb_get_ntohs (tvb, offset) & 0x0FFF) << 32 |
1603 tvb_get_ntohl (tvb, offset + 2);
1604 } else { /* bit 7-4: 0xxx or 1000 */
1607 value = tvb_get_ntohl (tvb, offset);
1613 value = (tvb_get_ntohl (tvb, offset) >> 8) & 0x48FFFF;
1617 value = tvb_get_ntohs (tvb, offset);
1622 failure = dmp_dec_xbyte_sic (value, sic, length, any);
1623 bf = proto_tree_add_string_format (sic_tree, hf_message_sic, tvb,
1625 "SIC %d: %s (%d bytes: %" G_GINT64_MODIFIER "x)%s",
1626 i + 1, sic, bytes, value,
1627 failure ? " (invalid)": "");
1628 if (bitmap & (1 << (7 - i))) {
1629 /* Only if 4 - 8 character */
1630 bitmap_tree = proto_item_add_subtree (bf, ett_message_sic_bits);
1632 proto_tree_add_item (bitmap_tree, hf_message_sic_bits_any, tvb,
1635 proto_tree_add_item (bitmap_tree, hf_message_sic_bits, tvb,
1640 expert_add_info_format (pinfo, bf, PI_UNDECODED, PI_NOTE,
1645 proto_item_append_text (sf, ": %d (3-to-8 %s character)", no,
1646 any ? "any" : "[A-Z0-9]");
1648 } else if (key == 0xFE) {
1650 g_snprintf (sic, MAX_SIC_LEN, "Not present");
1654 /* Resered (not used) */
1655 g_snprintf (sic, MAX_SIC_LEN, "Reserved");
1660 /* Not added any SIC, dump text value */
1661 sf = proto_tree_add_string_format (message_tree, hf_message_sic, tvb,
1662 offset, 1, sic, "SIC: %s", sic);
1666 proto_item_set_len (sf, offset - boffset);
1671 /* Ref chapter 5.2.7.1 Direct Originator Encoding */
1672 static gint dissect_dmp_direct_addr (tvbuff_t *tvb, packet_info *pinfo,
1673 proto_tree *field_tree, proto_item *tf,
1674 gint offset, gint rec_no,
1675 gint rec_ofs, gint addr_type)
1677 proto_tree *addr_tree = NULL;
1678 proto_item *en = NULL;
1682 value = tvb_get_guint8 (tvb, offset);
1683 dir_addr = (value & 0x7F);
1685 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address1, tvb,
1687 "%sDirect Address (bits 6-0): %d",
1688 val_to_str (addr_type, addr_type_str, ""),
1690 addr_tree = proto_item_add_subtree (en, ett_address_direct);
1691 proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset,
1693 proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset,
1698 value = tvb_get_guint8 (tvb, offset);
1699 dir_addr |= ((value & 0x3F) << 7);
1700 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address2, tvb,
1702 "%sDirect Address (bits 12-7): %d",
1703 val_to_str (addr_type, addr_type_str, ""),
1705 addr_tree = proto_item_add_subtree (en, ett_address_direct);
1706 proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset,
1708 en = proto_tree_add_item (addr_tree, hf_reserved_0x40, tvb, offset,
1711 expert_add_info_format (pinfo, en, PI_UNDECODED, PI_WARN,
1714 proto_tree_add_item (addr_tree, hf_addr_dir_address2, tvb, offset,
1720 value = tvb_get_guint8 (tvb, offset);
1721 dir_addr |= ((value & 0x3F) << 13);
1722 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address3, tvb,
1724 "%sDirect Address (bits 18-13): %d",
1725 val_to_str (addr_type,addr_type_str,""),
1727 addr_tree = proto_item_add_subtree (en, ett_address_direct);
1728 en = proto_tree_add_item (addr_tree, hf_reserved_0xC0, tvb, offset,
1731 expert_add_info_format (pinfo, en, PI_UNDECODED, PI_WARN,
1734 proto_tree_add_item (addr_tree, hf_addr_dir_address3, tvb, offset,
1739 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address_generated,
1740 tvb, offset, 0, dir_addr,
1741 "%sDirect Address: %d",
1742 val_to_str (addr_type, addr_type_str, ""),
1744 PROTO_ITEM_SET_GENERATED (en);
1746 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address, tvb,
1748 "%sDirect Address: %d",
1749 val_to_str (addr_type, addr_type_str, ""),
1751 addr_tree = proto_item_add_subtree (en, ett_address_direct);
1752 proto_tree_add_item (addr_tree, hf_addr_dir_addr_ext, tvb, offset,
1754 proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset,
1760 proto_item_append_text (tf, " %d", rec_no);
1761 if (rec_ofs != -1) {
1762 proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
1765 proto_item_append_text (tf, ", %sDirect Address: %d",
1766 val_to_str (addr_type, addr_type_str, ""), dir_addr);
1771 /* Ref 5.3.14 Extended Address */
1772 static gint dissect_dmp_ext_addr (tvbuff_t *tvb, packet_info *pinfo,
1773 proto_tree *field_tree, proto_item *tf,
1774 gint offset, gint rec_no, gint rec_ofs,
1777 proto_tree *addr_tree = NULL, *ext_tree = NULL;
1778 proto_item *en = NULL, *ef = NULL;
1781 gint boffset = offset;
1782 gboolean addr_length_extended = FALSE;
1783 asn1_ctx_t asn1_ctx;
1785 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1787 value = tvb_get_guint8 (tvb, offset);
1788 type = (value & 0xE0) >> 5;
1789 length = (value & 0x1F);
1790 ef = proto_tree_add_none_format (field_tree, hf_addr_ext_address, tvb,
1791 offset, -1, "%sExtended Address",
1792 val_to_str (addr_type, addr_type_str, ""));
1793 ext_tree = proto_item_add_subtree (ef, ett_address_extended);
1795 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_type, tvb,
1796 offset, 1, value, "Address Type: %s",
1797 val_to_str (type, ext_addr_type,
1799 addr_tree = proto_item_add_subtree (en, ett_address_ext_type);
1800 proto_tree_add_item (addr_tree, hf_addr_ext_type, tvb, offset,
1804 addr_length_extended = TRUE;
1805 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length1, tvb,
1807 "Address Length (bits 4-0): %d", length);
1808 addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
1809 proto_tree_add_item (addr_tree, hf_addr_ext_length1, tvb, offset,
1814 value = tvb_get_guint8 (tvb, offset);
1815 type = ((value & 0xE0) >> 5);
1816 length |= ((value & 0x1F) << 5);
1818 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_type_ext, tvb,
1819 offset, 1, value, "Address Type Ext: %s",
1820 val_to_str (type, ext_addr_type_ext,
1822 addr_tree = proto_item_add_subtree (en, ett_address_ext_type);
1823 proto_tree_add_item (addr_tree, hf_addr_ext_type, tvb, offset,
1826 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length2, tvb,
1828 "Address Length (bits 9-5): %d",
1830 addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
1831 proto_tree_add_item (addr_tree, hf_addr_ext_length2, tvb, offset,
1835 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length, tvb,
1836 offset, 1, value, "Address Length: %d",
1838 addr_tree = proto_item_add_subtree (en, ett_address_ext_length);
1839 proto_tree_add_item (addr_tree, hf_addr_ext_length1, tvb, offset,
1844 if (type == ASN1_BER) {
1845 tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, length, length);
1847 dissect_x411_ORName (FALSE, next_tvb, 0, &asn1_ctx, ext_tree,
1848 hf_addr_ext_asn1_ber);
1849 } else if (type == ASN1_PER) {
1850 proto_tree_add_item (ext_tree, hf_addr_ext_asn1_per, tvb, offset,
1853 proto_tree_add_item (ext_tree, hf_addr_ext_unknown, tvb, offset,
1858 if (addr_length_extended) {
1859 en = proto_tree_add_uint_format (ext_tree, hf_addr_ext_length_generated,
1860 tvb, offset, 0, length,
1861 "Address Length: %d", length);
1862 PROTO_ITEM_SET_GENERATED (en);
1865 proto_item_append_text (ef, ", Type: %s, Length: %d",
1866 val_to_str (type, ext_addr_type, "Reserved"),
1870 proto_item_append_text (tf, " %d", rec_no);
1871 if (rec_ofs != -1) {
1872 proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
1875 proto_item_append_text (tf, ", %sExtended Address Type: %s",
1876 val_to_str (addr_type, addr_type_str, ""),
1877 val_to_str (type, ext_addr_type_short, "Reserved"));
1879 proto_item_set_len (ef, offset - boffset);
1884 /* Ref chapter 5.2.8.1 Extended Originator Encoding */
1885 static gint dissect_dmp_originator (tvbuff_t *tvb, packet_info *pinfo,
1886 proto_tree *envelope_tree, gint offset)
1888 proto_tree *field_tree = NULL, *rec_tree = NULL;
1889 proto_item *en = NULL, *tf = NULL;
1890 guint8 value, dmp_addr_form;
1891 gint boffset = offset;
1893 tf = proto_tree_add_item (envelope_tree, hf_addr_originator, tvb, offset,
1895 field_tree = proto_item_add_subtree (tf, ett_address);
1897 if (dmp.addr_enc == DIRECT_ADDR) {
1898 offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf,
1899 offset, -1, -1, ORIGINATOR);
1901 value = tvb_get_guint8 (tvb, offset);
1902 dmp_addr_form = (value & 0xE0) >> 5;
1904 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_form, tvb,
1907 val_to_str (dmp_addr_form,
1908 addr_form_orig, "Reserved"));
1909 rec_tree = proto_item_add_subtree (en, ett_address_ext_form);
1910 proto_tree_add_item (rec_tree, hf_addr_ext_form, tvb, offset,
1912 en = proto_tree_add_item (rec_tree, hf_reserved_0x1F, tvb, offset,
1915 expert_add_info_format (pinfo, en, PI_UNDECODED, PI_WARN,
1920 if (dmp_addr_form == P1_DIRECT) {
1921 offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree,
1924 } else if (dmp_addr_form == P1_EXTENDED) {
1925 offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset, -1,
1928 proto_item_append_text (tf, " (invalid address form)");
1932 proto_item_set_len (tf, offset - boffset);
1937 static void dmp_add_recipient_info (proto_item *tf, guint8 rep_req,
1938 guint8 not_req, gboolean action)
1940 if (rep_req || not_req) {
1941 proto_item_append_text (tf, ", Request:");
1944 proto_item_append_text (tf, "%s",
1945 val_to_str (rep_req, report_vals_short, ""));
1948 proto_item_append_text (tf, "%s",
1949 val_to_str (not_req, notif_vals_short, ""));
1952 if (dmp.msg_type == STANAG) {
1953 proto_item_append_text (tf, " (Action)");
1954 } else if (dmp.msg_type == IPM) {
1955 proto_item_append_text (tf, " (To)");
1958 if (dmp.msg_type == STANAG) {
1959 proto_item_append_text (tf, " (Info)");
1960 } else if (dmp.msg_type == IPM) {
1961 proto_item_append_text (tf, " (Cc)");
1966 /* Ref chapter 5.2.7 Direct Recipient Encoding */
1967 static gint dissect_dmp_direct_encoding (tvbuff_t *tvb, packet_info *pinfo,
1968 proto_tree *field_tree, proto_item *tf,
1969 gint offset, guint *prev_rec_no)
1972 proto_tree *addr_tree = NULL, *rec_tree = NULL;
1973 proto_item *en = NULL;
1974 guint8 rep_req = 0, not_req = 0, value;
1975 gint rec_no, rec_ofs = -1, dir_addr;
1976 gboolean action = FALSE, dir_addr_extended = FALSE;
1978 value = tvb_get_guint8 (tvb, offset);
1979 rec_no = (value & 0xF0) >> 4;
1980 rep_req = (value & 0x0C) >> 2;
1981 not_req = (value & 0x03);
1983 if (rep_req == 0x03) {
1984 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no1,
1985 tvb, offset, 1, value,
1986 "Recipient Number (bits 3-0): %d"
1987 " (offset from previous)",
1988 (value & 0xF0) >> 4);
1990 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no,
1991 tvb, offset, 1, value,
1992 "Recipient Number Offset: %d"
1993 " (offset from previous)",
1994 (value & 0xF0) >> 4);
1996 rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
1997 proto_tree_add_item (rec_tree, hf_addr_dir_rec_no1, tvb, offset,
1999 proto_tree_add_item (rec_tree, hf_addr_dir_rep_req1, tvb, offset,
2001 proto_tree_add_item (rec_tree, hf_addr_dir_not_req1, tvb, offset,
2005 value = tvb_get_guint8 (tvb, offset);
2006 dir_addr = (value & 0x7F);
2007 action = (value & 0x80);
2008 if (not_req == 0x03) {
2009 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address1,
2010 tvb, offset, 1, value,
2011 "Direct Address (bits 6-0): %d",
2014 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address,
2015 tvb, offset, 1, value,
2016 "Direct Address: %d",
2019 addr_tree = proto_item_add_subtree (en, ett_address_direct);
2020 proto_tree_add_item (addr_tree, hf_addr_dir_action, tvb, offset,
2022 proto_tree_add_item (addr_tree, hf_addr_dir_address1, tvb, offset,
2026 if (rep_req == 0x03) {
2027 /* Extended Recipient Number 1 */
2028 value = tvb_get_guint8 (tvb, offset);
2029 rec_no |= ((value & 0x3F) << 4);
2031 rep_req = (value & 0xC0) >> 6;
2033 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no2,
2034 tvb, offset, 1, value,
2035 "Recipient Number (bits 9-4): %d"
2036 " (offset from previous)",
2038 rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
2039 proto_tree_add_item (rec_tree, hf_addr_dir_rep_req2, tvb, offset,
2041 proto_tree_add_item (rec_tree, hf_addr_dir_rec_no2, tvb, offset,
2045 if (rep_req == 0x03) {
2046 /* Extended Recipient Number 2 */
2047 value = tvb_get_guint8 (tvb, offset);
2048 rec_no |= ((value & 0x1F) << 10);
2050 rep_req = (value & 0xC0) >> 6;
2052 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no3,
2053 tvb, offset, 1, value,
2054 "Recipient Number (bits 14-10): %d"
2055 " (offset from previous)",
2057 rec_tree = proto_item_add_subtree (en, ett_address_rec_no);
2058 proto_tree_add_item (rec_tree, hf_addr_dir_rep_req3, tvb, offset,
2060 en = proto_tree_add_item (rec_tree, hf_reserved_0x20, tvb, offset,
2063 expert_add_info_format (pinfo, en, PI_UNDECODED, PI_WARN,
2066 proto_tree_add_item (rec_tree, hf_addr_dir_rec_no3, tvb, offset,
2072 if (not_req == 0x03) {
2073 /* Extended Direct Address 1 */
2074 dir_addr_extended = TRUE;
2075 value = tvb_get_guint8 (tvb, offset);
2076 dir_addr |= ((value & 0x3F) << 7);
2077 not_req = (value & 0xC0) >> 6;
2079 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address2, tvb,
2081 "Direct Address (bits 12-7): %d",
2083 addr_tree = proto_item_add_subtree (en, ett_address_direct);
2084 proto_tree_add_item (addr_tree, hf_addr_dir_not_req2, tvb, offset,
2086 proto_tree_add_item (addr_tree, hf_addr_dir_address2, tvb, offset,
2090 if (not_req == 0x03) {
2091 /* Extended Direct Address 2 */
2092 value = tvb_get_guint8 (tvb, offset);
2093 dir_addr |= ((value & 0x3F) << 13);
2094 not_req = (value & 0xC0) >> 6;
2096 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address3, tvb,
2098 "Direct Address (bits 18-13): %d",
2100 addr_tree = proto_item_add_subtree (en, ett_address_direct);
2101 proto_tree_add_item (addr_tree, hf_addr_dir_not_req3, tvb, offset,
2103 proto_tree_add_item (addr_tree, hf_addr_dir_address3, tvb, offset,
2109 rec_no += (1 + *prev_rec_no);
2110 *prev_rec_no = rec_no;
2112 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_rec_no_generated,
2113 tvb, offset, 0, rec_no,
2114 "Recipient Number: %d", rec_no);
2115 if (rec_no > 32767) {
2116 proto_item_append_text (en, " (maximum 32767)");
2117 expert_add_info_format (pinfo, en, PI_MALFORMED, PI_WARN,
2118 "Recipient number too big");
2120 PROTO_ITEM_SET_GENERATED (en);
2122 if (dir_addr_extended) {
2123 en = proto_tree_add_uint_format (field_tree, hf_addr_dir_address_generated,
2124 tvb, offset, 0, dir_addr,
2125 "Direct Address: %d", dir_addr);
2126 PROTO_ITEM_SET_GENERATED (en);
2129 proto_item_append_text (tf, " %d", rec_no);
2130 if (rec_ofs != -1) {
2131 proto_item_append_text (tf, " (offset from previous: %d)", rec_ofs);
2134 proto_item_append_text (tf, ", Direct Address: %d", dir_addr);
2135 dmp_add_recipient_info (tf, rep_req, not_req, action);
2140 /* Ref 5.2.8.2 Extended Recipient Encoding */
2141 static gint dissect_dmp_ext_encoding (tvbuff_t *tvb, packet_info *pinfo,
2142 proto_tree *field_tree,
2143 proto_item *tf, gint offset,
2146 proto_tree *addr_tree = NULL;
2147 proto_item *en = NULL;
2148 guint8 rep_req = 0, not_req = 0;
2149 guint8 value, dmp_addr_form;
2150 gboolean action = FALSE;
2151 gint rec_no, rec_ofs = -1;
2153 value = tvb_get_guint8 (tvb, offset);
2154 dmp_addr_form = (value & 0xE0) >> 5;
2155 action = (value & 0x10);
2156 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_form, tvb,
2159 val_to_str (dmp_addr_form,
2160 addr_form, "Reserved"));
2161 addr_tree = proto_item_add_subtree (en, ett_address_ext_form);
2162 proto_tree_add_item (addr_tree, hf_addr_ext_form, tvb, offset,
2165 en = proto_tree_add_boolean_format (field_tree, hf_addr_ext_action, tvb,
2166 offset, 1, value, "Action: %s",
2167 action ? yes_no.true_string :
2168 yes_no.false_string);
2169 addr_tree = proto_item_add_subtree (en, ett_address_ext_action);
2170 proto_tree_add_item (addr_tree, hf_addr_ext_action, tvb, offset,
2173 rep_req = (value & 0x0C) >> 2;
2174 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rep_req, tvb,
2176 "Report Request: %s",
2177 val_to_str ((value & 0x0C) >> 2,
2178 report_vals, "Reserved"));
2179 addr_tree = proto_item_add_subtree (en, ett_address_ext_rep_req);
2180 proto_tree_add_item (addr_tree, hf_addr_ext_rep_req, tvb, offset,
2183 not_req = (value & 0x03);
2184 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_not_req, tvb,
2186 "Notification Request: %s",
2187 val_to_str (value & 0x03,
2188 notif_vals, "Reserved"));
2189 addr_tree = proto_item_add_subtree (en, ett_address_ext_not_req);
2190 proto_tree_add_item (addr_tree, hf_addr_ext_not_req, tvb, offset,
2194 value = tvb_get_guint8 (tvb, offset);
2195 rec_no = (value & 0x7F);
2197 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no1, tvb,
2199 "Recipient Number (bits 6-0): %d"
2200 " (offset from previous)",
2202 addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2203 proto_tree_add_item (addr_tree, hf_addr_ext_rec_ext, tvb, offset,
2205 proto_tree_add_item (addr_tree, hf_addr_ext_rec_no1, tvb, offset,
2210 value = tvb_get_guint8 (tvb, offset);
2211 rec_no |= (value << 7);
2213 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no2, tvb,
2215 "Recipient Number (bits 14-7): %d"
2216 " (offset from previous)", value);
2217 addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2218 proto_tree_add_item (addr_tree, hf_addr_ext_rec_no2, tvb, offset,
2223 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no, tvb,
2225 "Recipient Number Offset: %d"
2226 " (offset from previous)",
2228 addr_tree = proto_item_add_subtree (en, ett_address_ext_rec_no);
2229 proto_tree_add_item (addr_tree, hf_addr_ext_rec_ext, tvb, offset,
2231 proto_tree_add_item (addr_tree, hf_addr_ext_rec_no1, tvb, offset,
2237 rec_no += (1 + *prev_rec_no);
2238 *prev_rec_no = rec_no;
2240 en = proto_tree_add_uint_format (field_tree, hf_addr_ext_rec_no_generated,
2241 tvb, offset, 0, rec_no,
2242 "Recipient Number: %d", rec_no);
2243 if (rec_no > 32767) {
2244 proto_item_append_text (en, " (maximum 32767)");
2245 expert_add_info_format (pinfo, en, PI_MALFORMED, PI_WARN,
2246 "Recipient number too big");
2248 PROTO_ITEM_SET_GENERATED (en);
2251 switch (dmp_addr_form) {
2255 case P1_DIRECT_P2_EXTENDED:
2256 offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf, offset,
2257 rec_no, rec_ofs, P1_ADDRESS);
2261 case P1_EXTENDED_P2_DIRECT:
2262 case P1_P2_EXTENDED:
2263 offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset,
2264 rec_no, rec_ofs, P1_ADDRESS);
2269 switch (dmp_addr_form) {
2273 case P1_EXTENDED_P2_DIRECT:
2274 offset = dissect_dmp_direct_addr (tvb, pinfo, field_tree, tf, offset,
2275 rec_no, rec_ofs, P2_ADDRESS);
2279 case P1_DIRECT_P2_EXTENDED:
2280 case P1_P2_EXTENDED:
2281 offset = dissect_dmp_ext_addr (tvb, pinfo, field_tree, tf, offset,
2282 rec_no, rec_ofs, P2_ADDRESS);
2287 dmp_add_recipient_info (tf, rep_req, not_req, action);
2292 /* Ref chapter 5.2 Address encoding */
2293 static gint dissect_dmp_address (tvbuff_t *tvb, packet_info *pinfo,
2294 proto_tree *envelope_tree,
2295 gint offset, guint *prev_rec_no,
2296 gboolean reporting_name)
2298 proto_tree *field_tree = NULL;
2299 proto_item *tf = NULL;
2300 gint boffset = offset;
2302 if (reporting_name) {
2303 tf = proto_tree_add_item (envelope_tree, hf_addr_reporting_name, tvb,
2306 tf = proto_tree_add_none_format (envelope_tree, hf_addr_recipient, tvb,
2307 offset, -1, "Recipient Number");
2309 field_tree = proto_item_add_subtree (tf, ett_address);
2311 if (dmp.addr_enc == DIRECT_ADDR) {
2312 offset = dissect_dmp_direct_encoding (tvb, pinfo, field_tree, tf,
2313 offset, prev_rec_no);
2315 offset = dissect_dmp_ext_encoding (tvb, pinfo, field_tree, tf, offset,
2319 proto_item_set_len (tf, offset - boffset);
2324 /* Ref chapter 6.2.9 Acknowledgement */
2325 static gint dissect_dmp_ack (tvbuff_t *tvb, packet_info *pinfo,
2326 proto_tree *dmp_tree, gint offset)
2328 proto_tree *ack_tree = NULL, *recip_tree = NULL;
2329 proto_item *en = NULL, *rt = NULL;
2330 proto_item *hidden_item;
2331 guint prev_rec_no = 0;
2332 gint rec_len, rec_no = 0;
2333 gint boffset = offset;
2335 en = proto_tree_add_item (dmp_tree, hf_ack, tvb, offset, 4, FALSE);
2336 ack_tree = proto_item_add_subtree (en, ett_ack);
2338 dmp.ack_reason = tvb_get_guint8 (tvb, offset);
2339 proto_item_append_text (en, ", Reason: %s",
2340 val_to_str (dmp.ack_reason, ack_reason, "Reserved"));
2342 rt = proto_tree_add_item (ack_tree, hf_ack_reason, tvb, offset, 1, FALSE);
2343 if (dmp.ack_reason != 0) {
2344 expert_add_info_format (pinfo, rt, PI_RESPONSE_CODE, PI_NOTE, "ACK reason: %s",
2345 val_to_str (dmp.ack_reason, ack_reason, "Reserved"));
2349 proto_tree_add_item (ack_tree, hf_ack_diagnostic, tvb, offset, 1, FALSE);
2352 /* Subject Message Identifier */
2353 dmp.subj_id = tvb_get_ntohs (tvb, offset);
2354 proto_tree_add_item (ack_tree, hf_message_subj_id, tvb, offset, 2, FALSE);
2355 hidden_item = proto_tree_add_item (ack_tree, hf_dmp_id, tvb, offset, 2, FALSE);
2356 PROTO_ITEM_SET_HIDDEN(hidden_item);
2359 if (use_seq_ack_analysis) {
2360 register_dmp_id (pinfo, dmp.ack_reason);
2363 if (dmp.ack_rec_present) {
2364 /* Recipient List */
2365 rec_len = tvb_length (tvb);
2369 if (offset < rec_len) {
2370 rt = proto_tree_add_item (ack_tree, hf_ack_recips, tvb, offset, -1,
2372 recip_tree = proto_item_add_subtree (rt, ett_ack_recips);
2373 while (offset < rec_len) {
2374 offset = dissect_dmp_address (tvb, pinfo, recip_tree, offset,
2375 &prev_rec_no, FALSE);
2378 proto_item_append_text (rt, ", No Recipients: %d", rec_no);
2379 proto_item_set_len (rt, offset - boffset - 4);
2380 proto_item_set_len (en, offset - boffset);
2387 /* Ref chapter 6.2.7 Envelope structure */
2388 static gint dissect_dmp_envelope (tvbuff_t *tvb, packet_info *pinfo,
2389 proto_tree *dmp_tree, gint offset)
2391 proto_tree *envelope_tree = NULL;
2392 proto_tree *field_tree = NULL;
2393 proto_item *en = NULL, *tf = NULL, *vf = NULL;
2394 proto_item *hidden_item;
2395 guint8 envelope, prot_id, time_diff;
2396 guint16 subm_time, no_rec, value16;
2398 gchar *env_flags = NULL;
2399 guint prev_rec_no = 0;
2400 gint boffset = offset, i;
2402 en = proto_tree_add_item (dmp_tree, hf_envelope, tvb, offset, 10, FALSE);
2403 envelope_tree = proto_item_add_subtree (en, ett_envelope);
2405 envelope = tvb_get_guint8 (tvb, offset);
2406 prot_id = (envelope & 0xF8) >> 3;
2407 dmp.version = (envelope & 0x07) + 1;
2409 /* Protocol Version */
2410 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_version,
2411 tvb, offset, 1, dmp.version,
2412 "Protocol Version: %d", dmp.version);
2414 field_tree = proto_item_add_subtree (tf, ett_envelope_version);
2415 vf = proto_tree_add_item (field_tree, hf_envelope_protocol_id, tvb,
2417 if (prot_id == 0x0D) {
2418 proto_item_append_text (vf, " (national version of DMP)");
2419 } else if (prot_id == 0x1D) {
2420 proto_item_append_text (vf, " (correct)");
2422 proto_item_append_text (vf, " (incorrect, should be 0x1d)");
2424 vf = proto_tree_add_item (field_tree, hf_envelope_version, tvb,
2428 if (dmp.version > DMP_VERSION) {
2429 /* Unsupported DMP Version */
2430 proto_item_append_text (vf, " (unsupported)");
2431 proto_item_append_text (tf, " (unsupported)");
2432 expert_add_info_format (pinfo, vf, PI_UNDECODED, PI_ERROR,
2433 "Unsupported DMP Version: %d", dmp.version);
2437 envelope = tvb_get_guint8 (tvb, offset);
2438 dmp.addr_enc = ((envelope & 0x10) >> 4);
2439 dmp.checksum = ((envelope & 0x08) >> 3);
2440 dmp.msg_type = (envelope & 0x07);
2442 if (dmp.msg_type != ACK) {
2444 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_hop_count,
2445 tvb, offset, 1, envelope,
2446 "Hop Count: %d", (envelope & 0xE0) >> 5);
2447 field_tree = proto_item_add_subtree (tf, ett_envelope_hop_count);
2448 proto_tree_add_item (field_tree, hf_envelope_hop_count, tvb,
2451 /* Recipient Present */
2452 dmp.ack_rec_present = (envelope & 0x20);
2453 tf = proto_tree_add_boolean_format (envelope_tree,hf_envelope_rec_present,
2454 tvb, offset, 1, envelope,
2455 "Recipient Present: %s",
2457 present_values.true_string :
2458 present_values.false_string);
2459 field_tree = proto_item_add_subtree (tf, ett_envelope_rec_present);
2460 proto_tree_add_item (field_tree, hf_envelope_rec_present, tvb,
2464 /* Address Encoding */
2465 tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_addr_enc,
2466 tvb, offset, 1, envelope,
2467 "Address Encoding: %s",
2469 addr_enc.true_string :
2470 addr_enc.false_string);
2471 field_tree = proto_item_add_subtree (tf, ett_envelope_addr_enc);
2472 proto_tree_add_item (field_tree, hf_envelope_addr_enc, tvb,
2475 /* Checksum Present */
2476 tf = proto_tree_add_boolean_format (envelope_tree, hf_envelope_checksum,
2477 tvb, offset, 1, envelope,
2480 used_notused.true_string :
2481 used_notused.false_string);
2482 field_tree = proto_item_add_subtree (tf, ett_envelope_checksum);
2483 proto_tree_add_item (field_tree, hf_envelope_checksum, tvb,
2487 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_type,
2488 tvb, offset, 1, envelope,
2489 "Content Type: %s (%d)",
2490 val_to_str (envelope & 0x07,
2491 type_vals, "Unknown"),
2493 field_tree = proto_item_add_subtree (tf, ett_envelope_cont_type);
2494 proto_tree_add_item (field_tree, hf_envelope_type, tvb,
2497 proto_item_append_text (en, ", %s", (envelope >> 3) & 0x01 ?
2498 checksum.true_string : checksum.false_string);
2501 if (dmp.msg_type >= ACK) {
2502 proto_item_set_len (en, offset - boffset);
2506 /* Message Identifier */
2507 dmp.msg_id = tvb_get_ntohs (tvb, offset);
2508 proto_tree_add_item (envelope_tree, hf_envelope_msg_id, tvb, offset,
2510 hidden_item = proto_tree_add_item (envelope_tree, hf_dmp_id, tvb, offset,
2512 PROTO_ITEM_SET_HIDDEN(hidden_item);
2515 /* Submission Time */
2516 subm_time = tvb_get_ntohs (tvb, offset);
2517 dmp.subm_time = dmp_dec_subm_time ((guint16)(subm_time & 0x7FFF),
2518 (gint32) pinfo->fd->abs_ts.secs);
2519 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_subm_time, tvb,
2520 offset, 2, subm_time,
2521 "Submission time: %s",
2522 (subm_time & 0x7FFF) >= 0x7FF8 ?
2524 abs_time_secs_to_str (dmp.subm_time));
2525 field_tree = proto_item_add_subtree (tf, ett_envelope_subm_time);
2526 proto_tree_add_item (field_tree, hf_envelope_time_diff_present, tvb,
2528 proto_tree_add_item (field_tree, hf_envelope_subm_time_value, tvb,
2532 if (subm_time & 0x8000) {
2533 /* Timed Difference */
2534 time_diff = tvb_get_guint8 (tvb, offset);
2535 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_time_diff,
2536 tvb, offset, 1, time_diff,
2537 "Time Difference: ");
2538 field_tree = proto_item_add_subtree (tf, ett_envelope_time_diff);
2539 proto_tree_add_item (field_tree, hf_envelope_time_diff_value, tvb,
2541 secs = dmp_dec_time_diff (time_diff);
2542 if (secs == -1 || secs == -2) {
2543 proto_item_append_text (tf, "Reserved (0x%2.2x)", time_diff);
2545 proto_item_append_text (tf, "%s", time_secs_to_str (secs));
2550 /* Envelope Flags */
2551 envelope = tvb_get_guint8 (tvb, offset);
2552 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_flags,
2553 tvb, offset, 1, envelope,
2556 field_tree = proto_item_add_subtree (tf, ett_envelope_flags);
2557 proto_tree_add_item (field_tree, hf_envelope_content_id_discarded, tvb,
2559 proto_tree_add_item (field_tree, hf_envelope_recip_reassign_prohib, tvb,
2561 proto_tree_add_item (field_tree, hf_envelope_dl_expansion_prohib, tvb,
2564 if (envelope & 0xE0) {
2565 env_flags = ep_alloc (MAX_ENV_FLAGS_LEN);
2567 g_snprintf (env_flags, MAX_ENV_FLAGS_LEN, "%s%s%s",
2568 (envelope & 0x80) ? ", ContId discarded" : "",
2569 (envelope & 0x40) ? ", Reass prohibited" : "",
2570 (envelope & 0x20) ? ", DLE prohibited" : "");
2571 proto_item_append_text (tf, ":%s", &env_flags[1]);
2573 proto_item_append_text (tf, " (none)");
2576 /* Recipient Count */
2577 no_rec = (envelope & 0x1F);
2578 tf = proto_tree_add_uint_format (envelope_tree, hf_envelope_recipients,
2579 tvb, offset, 1, envelope,
2580 "Recipient Count: %d", no_rec);
2582 field_tree = proto_item_add_subtree (tf, ett_envelope_recipients);
2583 proto_tree_add_item (field_tree, hf_envelope_recipients, tvb,
2588 /* Extended Recipient Count */
2589 value16 = tvb_get_ntohs (tvb, offset);
2590 no_rec = value16 & 0x7FFF;
2591 tf = proto_tree_add_uint_format (envelope_tree,hf_envelope_ext_recipients,
2592 tvb, offset, 2, value16,
2593 "Extended Recipient Count: %d%s", no_rec,
2595 " (incorrect, reserved value)" : ""));
2597 field_tree = proto_item_add_subtree (tf, ett_envelope_ext_recipients);
2598 en = proto_tree_add_item (field_tree, hf_reserved_0x8000, tvb,
2600 if (value16 & 0x8000) {
2601 expert_add_info_format (pinfo, en, PI_UNDECODED, PI_WARN,
2604 proto_tree_add_item (field_tree, hf_envelope_ext_recipients, tvb,
2609 if (dmp.msg_type != REPORT) {
2610 /* Originator - Not present for reports */
2611 offset = dissect_dmp_originator (tvb, pinfo, envelope_tree, offset);
2614 for (i = 1; i <= no_rec; i++) {
2616 offset = dissect_dmp_address (tvb, pinfo, envelope_tree, offset,
2617 &prev_rec_no, FALSE);
2619 proto_item_set_len (en, offset - boffset);
2624 static void dissect_dmp_structured_id (tvbuff_t *tvb, proto_tree *body_tree,
2627 proto_item *tf = NULL;
2632 guint8 *id_string = NULL;
2635 offset += dmp_struct_offset;
2636 switch (dmp_struct_format) {
2638 case STRUCT_ID_UINT8:
2639 id_byte = tvb_get_guint8 (tvb, offset);
2640 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%u", id_byte);
2641 tf = proto_tree_add_item (body_tree, hf_message_bodyid_uint8, tvb,
2645 case STRUCT_ID_UINT16:
2646 id_short = tvb_get_ntohs (tvb, offset);
2647 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%u", id_short);
2648 tf = proto_tree_add_item (body_tree, hf_message_bodyid_uint16, tvb,
2652 case STRUCT_ID_UINT32:
2653 id_int = tvb_get_ntohl (tvb, offset);
2654 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%u", id_int);
2655 tf = proto_tree_add_item (body_tree, hf_message_bodyid_uint32, tvb,
2659 case STRUCT_ID_UINT64:
2660 id_guint64 = tvb_get_ntoh64 (tvb, offset);
2661 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%" G_GINT64_MODIFIER "u",
2663 tf = proto_tree_add_item (body_tree, hf_message_bodyid_uint64, tvb,
2667 case STRUCT_ID_STRING:
2668 id_string = tvb_get_ephemeral_string (tvb, offset, (gint) dmp_struct_length);
2669 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%s", id_string);
2670 tf = proto_tree_add_item (body_tree, hf_message_bodyid_string, tvb,
2671 offset, dmp_struct_length, FALSE);
2674 case STRUCT_ID_ZSTRING:
2675 id_string = tvb_get_ephemeral_stringz (tvb, offset, &length);
2676 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%s", id_string);
2677 tf = proto_tree_add_item (body_tree, hf_message_bodyid_zstring, tvb,
2678 offset, length, FALSE);
2684 * Ref chapter 6.3.7.1 STANAG 4406 message structure
2685 * and chapter 6.3.8.1 IPM 88 message structure
2687 static gint dissect_dmp_message (tvbuff_t *tvb, packet_info *pinfo,
2688 proto_tree *dmp_tree, gint offset)
2690 tvbuff_t *next_tvb = NULL;
2691 proto_tree *message_tree = NULL;
2692 proto_tree *field_tree = NULL;
2693 proto_item *en = NULL, *tf = NULL;
2694 guint8 message, eit = 0, compr_alg = ALGORITHM_NONE;
2695 guint8 *subject = NULL;
2696 gint len, boffset = offset;
2698 en = proto_tree_add_item (dmp_tree, hf_message_body, tvb, offset, -1, FALSE);
2699 message_tree = proto_item_add_subtree (en, ett_message);
2701 if (dmp.body_format == FREE_TEXT_SUBJECT) {
2702 len = tvb_strsize (tvb, offset);
2703 if (dmp_subject_as_id) {
2704 subject = tvb_get_ephemeral_string (tvb, offset, len);
2705 g_snprintf (dmp.struct_id, MAX_STRUCT_ID_LEN, "%s", subject);
2707 proto_tree_add_item (message_tree, hf_message_subject, tvb, offset,
2712 if (dmp.body_format == FREE_TEXT || dmp.body_format == FREE_TEXT_SUBJECT) {
2713 message = tvb_get_guint8 (tvb, offset);
2714 eit = (message & 0xE0) >> 5;
2715 compr_alg = (message & 0x18) >> 3;
2716 /* Encoded Information Type */
2717 tf = proto_tree_add_uint_format (message_tree, hf_message_eit,
2718 tvb, offset, 1, message, "EIT: %s (%d)",
2719 val_to_str (eit, eit_vals, "Unknown"),
2721 field_tree = proto_item_add_subtree (tf, ett_message_eit);
2722 proto_tree_add_item (field_tree, hf_message_eit, tvb,
2724 proto_item_append_text (en, ", Type: %s",
2725 val_to_str (eit, eit_vals, "Unknown"));
2727 /* Compression Algorithm */
2728 tf = proto_tree_add_uint_format (message_tree, hf_message_compr,
2729 tvb, offset, 1, message,
2730 "Compression Algorithm: %s (%d)",
2731 val_to_str (compr_alg, compression_vals,
2732 "Unknown"), compr_alg);
2733 field_tree = proto_item_add_subtree (tf, ett_message_compr);
2734 proto_tree_add_item (field_tree, hf_message_compr, tvb,
2736 if (compr_alg == ALGORITHM_ZLIB) {
2737 proto_item_append_text (en, " (compressed)");
2740 if (message & 0x07) {
2742 tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x07,
2743 tvb, offset, 1, message,
2744 "Reserved: %d", message & 0x07);
2745 field_tree = proto_item_add_subtree (tf, ett_message_body_reserved);
2746 tf = proto_tree_add_item (field_tree, hf_reserved_0x07, tvb,
2748 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
2754 len = tvb_length_remaining (tvb, offset);
2759 tf = proto_tree_add_none_format (message_tree, hf_message_body_data, tvb,
2761 "%sUser data, Length: %d",
2762 (compr_alg == ALGORITHM_ZLIB) ?
2763 "Compressed " : "", len);
2764 field_tree = proto_item_add_subtree (tf, ett_message_body);
2766 if (dmp.body_format == STRUCTURED) {
2767 /* Structured Message ID */
2768 dissect_dmp_structured_id (tvb, field_tree, offset);
2769 proto_tree_add_item (field_tree, hf_message_body_structured, tvb, offset,
2771 } else if (len > 0 && (dmp.body_format == FREE_TEXT ||
2772 dmp.body_format == FREE_TEXT_SUBJECT)) {
2773 if (compr_alg == ALGORITHM_ZLIB) {
2774 if ((next_tvb = tvb_uncompress (tvb, offset, len)) != NULL) {
2775 gint zlen = tvb_length (next_tvb);
2776 add_new_data_source (pinfo, next_tvb, "Uncompressed User data");
2777 tf = proto_tree_add_none_format (message_tree,
2778 hf_message_body_uncompr,
2780 "Uncompressed User data, "
2781 "Length: %d", zlen);
2782 field_tree = proto_item_add_subtree (tf, ett_message_body_uncompr);
2783 proto_tree_add_item (field_tree, hf_message_body_uncompressed,
2784 next_tvb, 0, -1, FALSE);
2786 tf = proto_tree_add_text (message_tree, tvb, offset, -1,
2787 "Error: Unable to uncompress content");
2788 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
2789 "Unable to uncompress content");
2791 } else if (eit != EIT_BILATERAL) {
2792 proto_tree_add_item (field_tree, hf_message_body_plain, tvb,
2793 offset, len, FALSE);
2798 if (dmp.struct_id[0] != 0) {
2799 proto_item_append_text (en, ", Id: %s", dmp.struct_id);
2802 proto_item_set_len (en, offset - boffset);
2807 /* Ref chapter 6.3.9.1 Report structure */
2808 static gint dissect_dmp_report (tvbuff_t *tvb, packet_info *pinfo,
2809 proto_tree *dmp_tree, gint offset,
2810 guint *prev_rec_no, gint num)
2812 proto_tree *report_tree = NULL;
2813 proto_tree *field_tree = NULL;
2814 proto_item *en = NULL, *ei = NULL, *tf = NULL;
2816 gboolean info_present;
2818 gint len, boffset = offset;
2821 report = tvb_get_guint8 (tvb, offset);
2822 rep_type = (report & 0x80) >> 7;
2824 en = proto_tree_add_item (dmp_tree, hf_non_delivery_report, tvb,
2827 en = proto_tree_add_item (dmp_tree, hf_delivery_report, tvb,
2830 proto_item_append_text (en, " (#%d)", num);
2832 report_tree = proto_item_add_subtree (en, ett_report);
2835 tf = proto_tree_add_boolean_format (report_tree, hf_report_type,
2836 tvb, offset, 1, report,
2837 "Report Type: %s", rep_type ?
2838 report_type.true_string :
2839 report_type.false_string);
2840 field_tree = proto_item_add_subtree (tf, ett_report_type);
2841 proto_tree_add_item (field_tree, hf_report_type, tvb, offset,
2844 if (rep_type == DR) {
2847 info_present = (report & 0x40);
2848 tf = proto_tree_add_boolean_format (report_tree,hf_report_info_present_dr,
2849 tvb, offset, 1, report,
2850 "Info Present: %s", (report & 0x40) ?
2851 present_values.true_string :
2852 present_values.false_string);
2853 field_tree = proto_item_add_subtree (tf, ett_report_info_present_dr);
2854 proto_tree_add_item (field_tree, hf_report_info_present_dr, tvb,
2857 /* Address Encoding */
2858 dmp.addr_enc = ((report & 0x20) >> 5);
2859 tf = proto_tree_add_boolean_format (report_tree, hf_report_addr_enc_dr,
2860 tvb, offset, 1, report,
2861 "Address Encoding: %s",
2863 addr_enc.true_string :
2864 addr_enc.false_string);
2865 field_tree = proto_item_add_subtree (tf, ett_report_addr_enc_dr);
2866 proto_tree_add_item (field_tree, hf_report_addr_enc_dr, tvb,
2869 if (report & 0x1F) {
2871 tf = proto_tree_add_uint_format (report_tree, hf_reserved_0x1F,
2872 tvb, offset, 1, report,
2873 "Reserved: %d", report & 0x1F);
2874 field_tree = proto_item_add_subtree (tf, ett_report_reserved);
2875 tf = proto_tree_add_item (field_tree, hf_reserved_0x1F, tvb, offset,
2877 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
2884 report = tvb_get_guint8 (tvb, offset);
2885 secs = dmp_dec_del_time (report);
2886 tf = proto_tree_add_uint_format (report_tree, hf_report_del_time,
2887 tvb, offset, 1, report,
2889 field_tree = proto_item_add_subtree (tf, ett_report_del_time);
2890 ei = proto_tree_add_item (field_tree, hf_report_del_time, tvb,
2893 proto_item_append_text (tf, "Reserved (0x%2.2x)", report);
2894 proto_item_append_text (ei, ", (Reserved)");
2895 } else if (secs == 0) {
2896 proto_item_append_text (tf, "0 seconds");
2897 proto_item_append_text (ei, " (0 seconds)");
2899 proto_item_append_text (tf, "%s (offset from the original message"
2900 " submission time)",
2901 time_secs_to_str (secs));
2902 proto_item_append_text (ei, " (%s)", time_secs_to_str (secs));
2906 /* Address Encoding */
2907 dmp.addr_enc = ((report & 0x40) >> 6);
2908 tf = proto_tree_add_boolean_format (report_tree, hf_report_addr_enc_ndr,
2909 tvb, offset, 1, report,
2910 "Address Encoding: %s",
2912 addr_enc.true_string :
2913 addr_enc.false_string);
2914 field_tree = proto_item_add_subtree (tf, ett_report_addr_enc_ndr);
2915 proto_tree_add_item (field_tree, hf_report_addr_enc_ndr, tvb,
2919 tf = proto_tree_add_uint_format (report_tree, hf_report_reason,
2920 tvb, offset, 1, report,
2921 "Reason%s: %s (%d)",
2922 ((report & 0x3F) < 0x3D) ? " (X.411)":"",
2923 non_del_reason_str (report & 0x3F),
2925 field_tree = proto_item_add_subtree (tf, ett_report_reason);
2926 proto_tree_add_item (field_tree, hf_report_reason, tvb,
2931 report = tvb_get_guint8 (tvb, offset);
2932 info_present = (report & 0x80);
2933 tf = proto_tree_add_boolean_format (report_tree,
2934 hf_report_info_present_ndr,
2935 tvb, offset, 1, report,
2936 "Info Present: %s", (report & 0x80) ?
2937 present_values.true_string :
2938 present_values.false_string);
2939 field_tree = proto_item_add_subtree (tf, ett_report_info_present_ndr);
2940 proto_tree_add_item (field_tree, hf_report_info_present_ndr, tvb,
2944 tf = proto_tree_add_uint_format (report_tree, hf_report_diagn,
2945 tvb, offset, 1, report,
2946 "Diagnostic%s: %s (%d)",
2947 ((report & 0x7F) < 0x7C) ? " (X.411)":"",
2948 non_del_diagn_str (report & 0x7F),
2950 field_tree = proto_item_add_subtree (tf, ett_report_diagn);
2951 proto_tree_add_item (field_tree, hf_report_diagn, tvb,
2956 offset = dissect_dmp_address (tvb, pinfo, report_tree, offset,
2960 /* Supplementary Information */
2961 len = tvb_strsize (tvb, offset);
2962 tf = proto_tree_add_uint_format (report_tree, hf_report_suppl_info_len,
2963 tvb, offset, len, len,
2964 "Supplementary Information, Length: %d",
2967 if ((offset - boffset + len) > 128) {
2968 proto_item_append_text (tf, " (incorrect, should be less than %d)",
2969 128 - (offset - boffset));
2971 field_tree = proto_item_add_subtree (tf, ett_report_suppl_info);
2972 proto_tree_add_item (field_tree, hf_report_suppl_info, tvb,
2973 offset, len, FALSE);
2978 proto_item_set_len (en, offset - boffset);
2983 /* Ref chapter 6.3.10.1 Notification structure */
2984 static gint dissect_dmp_notification (tvbuff_t *tvb, packet_info *pinfo _U_,
2985 proto_tree *dmp_tree, gint offset)
2987 proto_tree *notif_tree = NULL;
2988 proto_tree *field_tree = NULL;
2989 proto_item *en = NULL, *tf = NULL;
2990 guint8 notif, rec_time, on_typex = 0xFF;
2991 gint len, boffset = offset;
2994 if (dmp.notif_type == RN) {
2995 en = proto_tree_add_item (dmp_tree, hf_receipt_notif, tvb, offset, 4, FALSE);
2996 } else if (dmp.notif_type == NRN) {
2997 en = proto_tree_add_item (dmp_tree, hf_non_receipt_notif, tvb, offset, 4, FALSE);
2998 } else if (dmp.notif_type == ON) {
2999 en = proto_tree_add_item (dmp_tree, hf_other_notif, tvb, offset, 4, FALSE);
3003 notif_tree = proto_item_add_subtree (en, ett_notif);
3005 if (dmp.notif_type == RN || dmp.notif_type == ON) {
3007 rec_time = tvb_get_guint8 (tvb, offset);
3008 tf = proto_tree_add_uint_format (notif_tree, hf_notif_rec_time,
3009 tvb, offset, 1, rec_time,
3011 field_tree = proto_item_add_subtree (tf, ett_notif_rec_time);
3012 proto_tree_add_item (field_tree, hf_notif_rec_time_val, tvb,
3014 secs = dmp_dec_exp_time (rec_time);
3015 if (rec_time == 0) {
3016 proto_item_append_text (tf, "Not present");
3017 } else if (secs == -1 || secs == -2) {
3018 proto_item_append_text (tf, "Reserved (0x%2.2x)", rec_time);
3020 proto_item_append_text (tf, "%s (offset from the original message"
3021 " submission time)", time_secs_to_str (secs));
3025 if (dmp.notif_type == ON) {
3027 on_typex = tvb_get_guint8 (tvb, offset);
3028 proto_tree_add_item (notif_tree, hf_notif_on_type, tvb, offset,
3033 /* Supplementary Information */
3034 len = tvb_strsize (tvb, offset);
3035 tf = proto_tree_add_uint_format (notif_tree, hf_notif_suppl_info_len,
3036 tvb, offset, len, len,
3037 "Supplementary Information, Length: %d",
3040 if ((offset - boffset + len) > 128) {
3041 proto_item_append_text (tf, " (incorrect, should be less than %d)",
3042 128 - (offset - boffset));
3044 field_tree = proto_item_add_subtree (tf, ett_notif_suppl_info);
3045 proto_tree_add_item (field_tree, hf_notif_suppl_info, tvb, offset,
3050 if ((dmp.notif_type == ON) && (on_typex < 0x03)) {
3051 /* ACP127 Receipient */
3052 len = tvb_strsize (tvb, offset);
3053 tf = proto_tree_add_uint_format (notif_tree, hf_notif_acp127,
3054 tvb, offset, len, len,
3055 "ACP127 Recipient, Length: %d",
3059 proto_item_append_text (tf, " (incorrect, must be less than 64)");
3061 field_tree = proto_item_add_subtree (tf, ett_notif_acp127recip);
3062 proto_tree_add_item (field_tree, hf_notif_acp127recip, tvb,
3063 offset, len, FALSE);
3067 } else if (dmp.notif_type == NRN) {
3068 /* Non-Recipient Reason */
3069 notif = tvb_get_guint8 (tvb, offset);
3070 proto_tree_add_uint_format (notif_tree, hf_notif_non_rec_reason,
3071 tvb, offset, 1, notif,
3072 "Non-Receipt Reason%s: %s (%d)",
3073 (notif < 0x10) ? " (X.420)" : "",
3074 nrn_reason_str (notif), notif);
3077 /* Discard Reason */
3078 notif = tvb_get_guint8 (tvb, offset);
3079 proto_tree_add_uint_format (notif_tree, hf_notif_discard_reason,
3080 tvb, offset, 1, notif,
3081 "Discard Reason%s: %s (%d)",
3082 (notif < 0x10) ? " (X.420)" : "",
3083 discard_reason_str (notif), notif);
3087 proto_item_set_len (en, offset - boffset);
3093 * Ref chapter 6.3.7.1 STANAG 4406 message structure
3094 * and chapter 6.3.8.1 IPM 88 message structure
3095 * and chapter 6.3.9.1 Report structure
3096 * and chapter 6.3.10.1 Notification structure
3098 static gint dissect_dmp_content (tvbuff_t *tvb, packet_info *pinfo,
3099 proto_tree *dmp_tree, gint offset)
3101 proto_tree *message_tree = NULL;
3102 proto_tree *field_tree = NULL;
3103 proto_item *en = NULL, *tf = NULL, *tr = NULL;
3104 proto_item *hidden_item;
3105 guint8 message, dmp_sec_pol, dmp_sec_class, exp_time, dtg;
3107 gchar *sec_cat = NULL;
3108 guint prev_rec_no = 0;
3109 gint rep_len, rep_no = 1;
3110 gint boffset = offset;
3112 if (dmp.msg_type == REPORT) {
3113 en = proto_tree_add_item (dmp_tree, hf_report_content, tvb, offset,
3115 } else if (dmp.msg_type == NOTIF) {
3116 en = proto_tree_add_item (dmp_tree, hf_notif_content, tvb, offset,
3119 en = proto_tree_add_item (dmp_tree, hf_message_content, tvb, offset, 7, FALSE);
3121 message_tree = proto_item_add_subtree (en, ett_content);
3123 if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3124 message = tvb_get_guint8 (tvb, offset);
3125 dmp.body_format = (message & 0x03);
3127 if (dmp.msg_type == STANAG) {
3129 dmp.st_type = (message & 0xC0) >> 6;
3130 tf = proto_tree_add_uint_format (message_tree, hf_message_st_type,
3131 tvb, offset, 1, message,
3132 "Message Type: %s (%d)",
3133 val_to_str (dmp.st_type,
3134 message_type_vals, ""),
3136 field_tree = proto_item_add_subtree (tf, ett_message_st_type);
3137 proto_tree_add_item (field_tree, hf_message_st_type, tvb, offset,
3140 if ((message & 0x20) >> 5) {
3142 tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x20,
3143 tvb, offset, 1, message,
3144 "Reserved: %d", (message & 0x20)>>5);
3145 field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3146 tf = proto_tree_add_item (field_tree, hf_reserved_0x20, tvb, offset,
3148 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
3153 dmp.prec = (message & 0x1C) >> 2;
3154 tf = proto_tree_add_uint_format (message_tree, hf_message_precedence,
3155 tvb, offset, 1, message,
3156 "Precedence: %s (%d)",
3157 val_to_str (dmp.prec, precedence, ""),
3159 field_tree = proto_item_add_subtree (tf, ett_message_precedence);
3160 proto_tree_add_item (field_tree, hf_message_precedence, tvb, offset,
3164 if ((message & 0xE0) >> 5) {
3166 tf = proto_tree_add_uint_format (message_tree, hf_reserved_0xE0,
3167 tvb, offset, 1, message,
3168 "Reserved: %d", (message & 0xE0)>>5);
3169 field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3170 tf = proto_tree_add_item (field_tree, hf_reserved_0xE0, tvb, offset,
3172 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
3177 dmp.prec = (message & 0x1C) >> 2;
3178 tf = proto_tree_add_uint_format (message_tree, hf_message_importance,
3179 tvb, offset, 1, message,
3180 "Importance: %s (%d)",
3181 val_to_str (dmp.prec, importance, ""),
3183 field_tree = proto_item_add_subtree (tf, ett_message_importance);
3184 proto_tree_add_item (field_tree, hf_message_importance, tvb, offset,
3189 tf = proto_tree_add_uint_format (message_tree, hf_message_body_format,
3190 tvb, offset, 1, message,
3191 "Body Format: %s (%d)",
3192 val_to_str (message & 0x03,
3193 body_format_vals, ""),
3195 field_tree = proto_item_add_subtree (tf, ett_message_body_format);
3196 proto_tree_add_item (field_tree, hf_message_body_format, tvb, offset,
3201 message = tvb_get_guint8 (tvb, offset);
3202 /* Security Classification */
3203 dmp_sec_class = (message & 0xE0) >> 5;
3204 dmp_sec_pol = (message & 0x1C) >> 2;
3206 if (dmp_sec_pol == NATO || dmp_sec_pol == NATIONAL) {
3207 /* NATO or National security policy */
3208 tf = proto_tree_add_uint_format (message_tree, hf_message_sec_class_nat,
3209 tvb, offset, 1, message,
3210 "Security Classification: %s (%d)",
3211 val_to_str (dmp_sec_class,
3212 sec_class, "Unknown"),
3214 field_tree = proto_item_add_subtree (tf, ett_message_sec_class);
3215 proto_tree_add_item (field_tree, hf_message_sec_class_nat, tvb, offset,
3218 proto_item_append_text (en, ", Security Label: %s",
3219 val_to_str (dmp_sec_class, sec_class, "Unknown"));
3221 tf = proto_tree_add_uint_format (message_tree, hf_message_sec_class_val,
3222 tvb, offset, 1, message,
3223 "Security Classification: %d",
3225 field_tree = proto_item_add_subtree (tf, ett_message_sec_class);
3226 proto_tree_add_item (field_tree, hf_message_sec_class_val, tvb, offset,
3230 /* Security Policy */
3231 tf = proto_tree_add_uint_format (message_tree, hf_message_sec_pol,
3232 tvb, offset, 1, message,
3233 "Security Policy: %s (%d)",
3234 val_to_str (dmp_sec_pol, sec_pol, ""),
3236 field_tree = proto_item_add_subtree (tf, ett_message_sec_pol);
3237 proto_tree_add_item (field_tree, hf_message_sec_pol, tvb, offset,
3240 if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3242 tf = proto_tree_add_item (message_tree, hf_message_heading_flags,
3243 tvb, offset, 1, FALSE);
3244 field_tree = proto_item_add_subtree (tf, ett_message_heading_flags);
3245 proto_tree_add_item (field_tree, hf_message_auth_users, tvb, offset,
3247 proto_tree_add_item (field_tree, hf_message_subject_disc, tvb, offset,
3249 if (message & 0x03) {
3250 proto_item_append_text (tf, ": %s%s%s discarded",
3251 (message & 0x02) ? "Authorizing users" : "",
3252 (message & 0x03) == 0x03 ? " and " : "",
3253 (message & 0x01) ? "Subject" : "");
3255 proto_item_append_text (tf, " (none)");
3257 } else if (dmp.msg_type == NOTIF) {
3258 /* Notification Type */
3259 dmp.notif_type = (message & 0x03);
3260 tf = proto_tree_add_uint_format (message_tree, hf_notif_type,
3261 tvb, offset, 1, message,
3262 "Notification Type: %s",
3263 val_to_str (dmp.notif_type, notif_type,
3265 field_tree = proto_item_add_subtree (tf, ett_notif_type);
3266 proto_tree_add_item (field_tree, hf_notif_type, tvb, offset,
3268 } else if (message & 0x02) {
3270 tf = proto_tree_add_uint_format (message_tree, hf_reserved_0x02,
3271 tvb, offset, 1, message,
3272 "Reserved: %d", message & 0x02);
3273 field_tree = proto_item_add_subtree (tf, ett_message_reserved);
3274 tf = proto_tree_add_item (field_tree, hf_reserved_0x02, tvb, offset,
3276 expert_add_info_format (pinfo, tf, PI_UNDECODED, PI_WARN,
3281 if (dmp_sec_pol == EXTENDED_NATIONAL) {
3282 /* National Policy Identifier */
3283 proto_tree_add_item (message_tree, hf_message_national_policy_id,
3284 tvb, offset, 1, FALSE);
3286 } else if (dmp_sec_pol == EXTENDED_MISSION) {
3287 /* Mission Policy Identifier */
3288 message = tvb_get_guint8 (tvb, offset);
3289 if (message == 0xFF) {
3290 proto_tree_add_uint_format (message_tree, hf_message_mission_policy_id,
3291 tvb, offset, 1, message,
3292 "Mission Policy Identifier: Reserved");
3294 proto_tree_add_item (message_tree, hf_message_mission_policy_id,
3295 tvb, offset, 1, FALSE);
3300 /* Security Categories */
3301 message = tvb_get_guint8 (tvb, offset);
3302 if (dmp_sec_pol == NATO || dmp_sec_pol == NATIONAL) {
3303 tf = proto_tree_add_uint_format (message_tree, hf_message_sec_cat_nat, tvb,
3304 offset, 1, message, "Security Categories");
3305 field_tree = proto_item_add_subtree (tf, ett_message_sec_cat);
3307 proto_tree_add_item (field_tree, hf_message_sec_cat_cl, tvb, offset,
3309 proto_tree_add_item (field_tree, hf_message_sec_cat_cs, tvb, offset,
3311 proto_tree_add_item (field_tree, hf_message_sec_cat_ex, tvb, offset,
3313 proto_tree_add_item (field_tree, hf_message_sec_cat_ne, tvb, offset,
3315 tr = proto_tree_add_item (field_tree, hf_reserved_0x08, tvb, offset,
3317 if (message & 0x08) {
3318 expert_add_info_format (pinfo, tr, PI_UNDECODED, PI_WARN,
3321 tr = proto_tree_add_item (field_tree, hf_reserved_0x04, tvb, offset,
3323 if (message & 0x04) {
3324 expert_add_info_format (pinfo, tr, PI_UNDECODED, PI_WARN,
3327 tr = proto_tree_add_item (field_tree, hf_reserved_0x02, tvb, offset,
3329 if (message & 0x02) {
3330 expert_add_info_format (pinfo, tr, PI_UNDECODED, PI_WARN,
3333 tr = proto_tree_add_item (field_tree, hf_reserved_0x01, tvb, offset,
3335 if (message & 0x01) {
3336 expert_add_info_format (pinfo, tr, PI_UNDECODED, PI_WARN,
3340 if (message & 0xF0) {
3341 sec_cat = ep_alloc (MAX_SEC_CAT_LEN);
3343 g_snprintf (sec_cat, MAX_SEC_CAT_LEN, "%s%s%s%s",
3344 (message & 0x80) ? ",cl" : "",
3345 (message & 0x40) ? ",cs" : "",
3346 (message & 0x20) ? ",ex" : "",
3347 (message & 0x10) ? ",ne" : "");
3348 proto_item_append_text (tf, ": %s", &sec_cat[1]);
3349 proto_item_append_text (en, "%s", sec_cat);
3351 proto_item_append_text (tf, " (0x%2.2x)", message);
3353 tf = proto_tree_add_item (message_tree, hf_message_sec_cat_val, tvb,
3355 field_tree = proto_item_add_subtree (tf, ett_message_sec_cat);
3357 proto_tree_add_item (field_tree, hf_message_sec_cat_bit7, tvb, offset,
3359 proto_tree_add_item (field_tree, hf_message_sec_cat_bit6, tvb, offset,
3361 proto_tree_add_item (field_tree, hf_message_sec_cat_bit5, tvb, offset,
3363 proto_tree_add_item (field_tree, hf_message_sec_cat_bit4, tvb, offset,
3365 proto_tree_add_item (field_tree, hf_message_sec_cat_bit3, tvb, offset,
3367 proto_tree_add_item (field_tree, hf_message_sec_cat_bit2, tvb, offset,
3369 proto_tree_add_item (field_tree, hf_message_sec_cat_bit1, tvb, offset,
3371 proto_tree_add_item (field_tree, hf_message_sec_cat_bit0, tvb, offset,
3376 if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3377 exp_time = tvb_get_guint8 (tvb, offset);
3378 tf = proto_tree_add_uint_format (message_tree, hf_message_exp_time,
3379 tvb, offset, 1, exp_time,
3381 field_tree = proto_item_add_subtree (tf, ett_message_exp_time);
3382 proto_tree_add_item (field_tree, hf_message_exp_time_val, tvb,
3384 secs = dmp_dec_exp_time (exp_time);
3385 if (exp_time == 0) {
3386 proto_item_append_text (tf, "Not present");
3387 } else if (secs == -1 || secs == -2) {
3388 proto_item_append_text (tf, "Reserved (0x%2.2x)", exp_time);
3390 proto_item_append_text (tf, "%s (%s)", time_secs_to_str (secs),
3391 abs_time_secs_to_str (dmp.subm_time + secs));
3396 if (dmp.msg_type == STANAG) {
3397 dtg = tvb_get_guint8 (tvb, offset);
3398 tf = proto_tree_add_uint_format (message_tree, hf_message_dtg, tvb,
3399 offset, 1, dtg, "DTG: ");
3400 field_tree = proto_item_add_subtree (tf, ett_message_dtg);
3401 proto_tree_add_item (field_tree, hf_message_dtg_sign, tvb, offset,
3403 proto_tree_add_item (field_tree, hf_message_dtg_val, tvb, offset,
3405 secs = dmp_dec_dtg (dtg & 0x7F);
3407 proto_item_append_text (tf, "Not present");
3408 } else if (secs == -1 || secs == -2) {
3409 proto_item_append_text (tf, "Reserved (0x%2.2x)", dtg & 0x7F);
3410 } else if (secs == 0) {
3411 proto_item_append_text (tf, "0 minutes in the %s (%s)",
3412 (dtg & 0x80) ? dtg_sign.true_string :
3413 dtg_sign.false_string,
3414 abs_time_secs_to_str (dmp.subm_time));
3416 proto_item_append_text (tf, "%s in the %s (%s)", time_secs_to_str(secs),
3417 (dtg & 0x80) ? dtg_sign.true_string :
3418 dtg_sign.false_string, (dtg & 0x80) ?
3419 abs_time_secs_to_str (dmp.subm_time + secs) :
3420 abs_time_secs_to_str (dmp.subm_time - secs));
3425 if (dmp.msg_type == STANAG) {
3427 offset = dissect_dmp_sic (tvb, pinfo, message_tree, offset);
3428 } else if (dmp.msg_type == REPORT || dmp.msg_type == NOTIF) {
3429 /* Subject Message Identifier */
3430 dmp.subj_id = tvb_get_ntohs (tvb, offset);
3431 proto_tree_add_item (message_tree, hf_message_subj_id, tvb, offset,
3433 hidden_item = proto_tree_add_item (message_tree, hf_dmp_id, tvb, offset,
3435 PROTO_ITEM_SET_HIDDEN(hidden_item);
3439 if (use_seq_ack_analysis) {
3440 register_dmp_id (pinfo, 0);
3443 proto_item_set_len (en, offset - boffset);
3445 if (dmp.msg_type == STANAG || dmp.msg_type == IPM) {
3447 offset = dissect_dmp_message (tvb, pinfo, dmp_tree, offset);
3448 } else if (dmp.msg_type == REPORT) {
3449 /* One or more Delivery Report or Non-Delivery Report Data */
3450 rep_len = tvb_length (tvb);
3454 while (offset < rep_len) {
3455 offset = dissect_dmp_report (tvb, pinfo, dmp_tree, offset,
3456 &prev_rec_no, rep_no++);
3458 } else if (dmp.msg_type == NOTIF) {
3459 /* Notification Data */
3460 offset = dissect_dmp_notification (tvb, pinfo, dmp_tree, offset);
3466 static void dissect_dmp (tvbuff_t *tvb, packet_info *pinfo,
3469 proto_tree *dmp_tree = NULL, *checksum_tree = NULL;
3470 proto_item *ti = NULL, *en = NULL;
3471 guint16 checksum1 = 0, checksum2 = 1;
3472 gint length, offset = 0;
3473 gboolean retrans_or_dup_ack = FALSE;
3475 if (check_col (pinfo->cinfo, COL_PROTOCOL))
3476 col_set_str (pinfo->cinfo, COL_PROTOCOL, "DMP");
3478 if (check_col (pinfo->cinfo, COL_INFO))
3479 col_clear (pinfo->cinfo, COL_INFO);
3481 /* Initialize global data structure */
3482 memset (&dmp, 0, sizeof (dmp));
3483 dmp.struct_id = ep_alloc (MAX_STRUCT_ID_LEN);
3484 dmp.struct_id[0] = 0;
3486 ti = proto_tree_add_item (tree, proto_dmp, tvb, offset, -1, FALSE);
3487 dmp_tree = proto_item_add_subtree (ti, ett_dmp);
3489 offset = dissect_dmp_envelope (tvb, pinfo, dmp_tree, offset);
3491 if (dmp.version > DMP_VERSION) {
3492 /* Unsupported DMP Version, no point to continue */
3493 if (check_col (pinfo->cinfo, COL_INFO)) {
3494 col_add_fstr (pinfo->cinfo, COL_INFO, "Unsupported Version: %d",
3500 if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3501 (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF))
3503 offset = dissect_dmp_content (tvb, pinfo, dmp_tree, offset);
3504 } else if (dmp.msg_type == ACK) {
3505 offset = dissect_dmp_ack (tvb, pinfo, dmp_tree, offset);
3509 length = tvb_length (tvb);
3510 checksum1 = crc16_x25_ccitt_tvb (tvb, length - 2);
3511 checksum2 = tvb_get_ntohs (tvb, offset);
3513 en = proto_tree_add_item (dmp_tree, hf_checksum, tvb, offset,
3515 checksum_tree = proto_item_add_subtree (en, ett_checksum);
3516 if (checksum1 == checksum2) {
3517 proto_item_append_text (en, " (correct)");
3518 en = proto_tree_add_boolean (checksum_tree, hf_checksum_good, tvb,
3520 PROTO_ITEM_SET_GENERATED (en);
3521 en = proto_tree_add_boolean (checksum_tree, hf_checksum_bad, tvb,
3523 PROTO_ITEM_SET_GENERATED (en);
3525 proto_item_append_text (en, " (incorrect, should be 0x%04x)",
3527 expert_add_info_format (pinfo, en, PI_CHECKSUM, PI_WARN, "Bad checksum");
3528 en = proto_tree_add_boolean (checksum_tree, hf_checksum_good, tvb,
3530 PROTO_ITEM_SET_GENERATED (en);
3531 en = proto_tree_add_boolean (checksum_tree, hf_checksum_bad, tvb,
3533 PROTO_ITEM_SET_GENERATED (en);
3537 if (use_seq_ack_analysis) {
3538 dmp_add_seq_ack_analysis (tvb, pinfo, dmp_tree, offset);
3541 if (check_col (pinfo->cinfo, COL_INFO)) {
3542 if (((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3543 (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF)) &&
3544 dmp.id_val && dmp.id_val->msg_resend_count)
3547 if (dmp.msg_type == REPORT) {
3548 retrans_num = dmp.id_val->rep_id;
3549 } else if (dmp.msg_type == NOTIF) {
3550 retrans_num = dmp.id_val->not_id;
3552 retrans_num = dmp.id_val->msg_id;
3554 col_append_fstr (pinfo->cinfo, COL_INFO, "[Retrans %d#%d] ",
3555 retrans_num, dmp.id_val->msg_resend_count);
3556 retrans_or_dup_ack = TRUE;
3557 } else if (dmp.msg_type == ACK && dmp.id_val && dmp.id_val->ack_resend_count) {
3558 col_append_fstr (pinfo->cinfo, COL_INFO, "[Dup ACK %d#%d] ",
3559 dmp.id_val->ack_id, dmp.id_val->ack_resend_count);
3560 retrans_or_dup_ack = TRUE;
3562 if (dmp_align && !retrans_or_dup_ack) {
3563 if (dmp.msg_type == ACK) {
3564 /* ACK does not have "Msg Id" */
3565 col_append_fstr (pinfo->cinfo, COL_INFO, "%-45.45s", msg_type_to_str ());
3567 col_append_fstr (pinfo->cinfo, COL_INFO, "%-31.31s", msg_type_to_str ());
3570 col_append_str (pinfo->cinfo, COL_INFO, msg_type_to_str ());
3572 if ((dmp.msg_type == STANAG) || (dmp.msg_type == IPM) ||
3573 (dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF))
3575 if (dmp_align && !retrans_or_dup_ack) {
3576 col_append_fstr (pinfo->cinfo, COL_INFO, " Msg Id: %5d", dmp.msg_id);
3578 col_append_fstr (pinfo->cinfo, COL_INFO, ", Msg Id: %d", dmp.msg_id);
3581 if ((dmp.msg_type == REPORT) || (dmp.msg_type == NOTIF) ||
3582 (dmp.msg_type == ACK))
3584 if (dmp_align && !retrans_or_dup_ack) {
3585 col_append_fstr (pinfo->cinfo, COL_INFO, " Subj Id: %5d",
3588 col_append_fstr (pinfo->cinfo, COL_INFO, ", Subj Id: %d",
3591 } else if (dmp.struct_id[0] != 0) {
3592 if (dmp_align && !retrans_or_dup_ack) {
3593 col_append_fstr (pinfo->cinfo, COL_INFO, " Body Id: %s",
3596 col_append_fstr (pinfo->cinfo, COL_INFO, ", Body Id: %s",
3600 if (dmp.checksum && (checksum1 != checksum2)) {
3601 col_append_str (pinfo->cinfo, COL_INFO, ", Checksum incorrect");
3605 proto_item_append_text (ti, ", Version: %d, %s", dmp.version,
3609 static void dmp_init_routine (void)
3611 if (dmp_id_hash_table) {
3612 g_hash_table_destroy (dmp_id_hash_table);
3615 dmp_id_hash_table = g_hash_table_new (dmp_id_hash, dmp_id_hash_equal);
3618 void proto_register_dmp (void)
3620 static hf_register_info hf[] = {
3625 { "DMP Identifier", "dmp.id", FT_UINT16, BASE_DEC,
3626 NULL, 0x0, "DMP identifier", HFILL}},
3632 { "Envelope", "dmp.envelope", FT_NONE, BASE_NONE,
3633 NULL, 0x0, "Envelope", HFILL}},
3636 { &hf_envelope_protocol_id,
3637 { "Protocol Identifier", "dmp.protocol_id", FT_UINT8,
3638 BASE_HEX, NULL, 0xF8, "Protocol Identifier", HFILL}},
3639 { &hf_envelope_version,
3640 { "Protocol Version", "dmp.version", FT_UINT8, BASE_DEC,
3641 VALS(version_vals), 0x07, "Protocol Version", HFILL } },
3643 /* Envelope elements (byte 1) */
3644 { &hf_envelope_hop_count,
3645 { "Hop Count", "dmp.hop_count", FT_UINT8, BASE_DEC,
3646 NULL, 0xE0, "Hop Count", HFILL } },
3647 { &hf_envelope_rec_present,
3648 { "Recipient Present", "dmp.rec_present", FT_BOOLEAN, 8,
3649 TFS (&present_values), 0x20, "Recipient Present", HFILL } },
3650 { &hf_envelope_addr_enc,
3651 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
3652 TFS (&addr_enc), 0x10, "Address Encoding", HFILL } },
3653 { &hf_envelope_checksum,
3654 { "Checksum", "dmp.checksum_used", FT_BOOLEAN, 8,
3655 TFS (&used_notused), 0x08, "Checksum Used", HFILL } },
3656 { &hf_envelope_type,
3657 { "Content Type", "dmp.content_type", FT_UINT8, BASE_DEC,
3658 VALS(type_vals), 0x07, "Content Type", HFILL } },
3660 /* Message identifier */
3661 { &hf_envelope_msg_id,
3662 { "Message Identifier", "dmp.msg_id", FT_UINT16, BASE_DEC,
3663 NULL, 0x0, "Message identifier", HFILL}},
3665 /* Submission time */
3666 { &hf_envelope_subm_time,
3667 { "Submission Time", "dmp.subm_time", FT_UINT16, BASE_HEX,
3668 NULL, 0x0, "Submission Time", HFILL } },
3669 { &hf_envelope_time_diff_present,
3670 { "Time Diff", "dmp.time_diff_present", FT_BOOLEAN, 16,
3671 TFS (&present_values), 0x8000, "Time Diff Present", HFILL } },
3672 { &hf_envelope_subm_time_value,
3673 { "Submission Time Value", "dmp.subm_time_value", FT_UINT16,
3674 BASE_HEX, NULL, 0x7FFF, "Submission Time Value", HFILL } },
3675 { &hf_envelope_time_diff,
3676 { "Time Difference", "dmp.time_diff", FT_UINT8, BASE_HEX,
3677 NULL, 0xFF, "Time Difference", HFILL } },
3678 { &hf_envelope_time_diff_value,
3679 { "Time Difference Value", "dmp.time_diff_value", FT_UINT8,
3680 BASE_HEX, NULL, 0xFF, "Time Difference Value", HFILL } },
3682 /* Envelope flags */
3683 { &hf_envelope_flags,
3684 { "Flags", "dmp.envelope_flags", FT_UINT8, BASE_DEC,
3685 NULL, 0x0, "Envelope Flags", HFILL}},
3686 { &hf_envelope_content_id_discarded,
3687 { "Content Identifier discarded", "dmp.cont_id_discarded",
3688 FT_BOOLEAN, 8, TFS(&yes_no), 0x80,
3689 "Content identifier discarded", HFILL } },
3690 { &hf_envelope_recip_reassign_prohib,
3691 { "Recipient reassign prohibited","dmp.recip_reassign_prohib",
3692 FT_BOOLEAN, 8, TFS(&yes_no), 0x40,
3693 "Recipient Reassign prohibited", HFILL }},
3694 { &hf_envelope_dl_expansion_prohib,
3695 { "DL expansion prohibited", "dmp.dl_expansion_prohib",
3696 FT_BOOLEAN, 8, TFS(&yes_no), 0x20, "DL expansion prohibited",
3699 /* Recipient Count */
3700 { &hf_envelope_recipients,
3701 { "Recipient Count", "dmp.rec_count", FT_UINT8, BASE_DEC,
3702 NULL, 0x1F, "Recipient Count", HFILL}},
3703 { &hf_envelope_ext_recipients,
3704 { "Extended Recipient Count", "dmp.ext_rec_count", FT_UINT16,
3705 BASE_DEC, NULL, 0x7FFF, "Extended Recipient Count", HFILL}},
3710 { &hf_addr_recipient,
3711 { "Recipient Number", "dmp.recipient", FT_NONE, BASE_NONE,
3712 NULL, 0x0, "Recipient", HFILL } },
3713 { &hf_addr_originator,
3714 { "Originator", "dmp.originator", FT_NONE, BASE_NONE,
3715 NULL, 0x0, "Originator", HFILL } },
3716 { &hf_addr_reporting_name,
3717 { "Reporting Name Number", "dmp.reporting_name", FT_NONE,
3718 BASE_NONE, NULL, 0x0, "Reporting Name", HFILL } },
3723 { &hf_addr_dir_addr_ext,
3724 { "Address Extended", "dmp.addr_ext", FT_BOOLEAN, 8,
3725 NULL, 0x80, "Address Extended", HFILL } },
3726 { &hf_addr_dir_rec_no,
3727 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8,
3728 BASE_DEC, NULL, 0xF0, "Recipient Number Offset", HFILL } },
3729 { &hf_addr_dir_rec_no_generated,
3730 { "Recipient Number", "dmp.rec_no", FT_UINT32,
3731 BASE_DEC, NULL, 0x0, "Recipient Number Offset", HFILL } },
3732 { &hf_addr_dir_rec_no1,
3733 { "Recipient Number (bits 3-0)", "dmp.rec_no_offset1", FT_UINT8,
3734 BASE_DEC, NULL, 0xF0, "Recipient Number (bits 3-0) Offset", HFILL } },
3735 { &hf_addr_dir_rec_no2,
3736 { "Recipient Number (bits 9-4)", "dmp.rec_no_offset2", FT_UINT8,
3737 BASE_DEC, NULL, 0x3F, "Recipient Number (bits 9-4) Offset", HFILL } },
3738 { &hf_addr_dir_rec_no3,
3739 { "Recipient Number (bits 14-10)", "dmp.rec_no_offset3", FT_UINT8,
3740 BASE_DEC, NULL, 0x1F, "Recipient Number (bits 14-10) Offset",HFILL } },
3741 { &hf_addr_dir_rep_req1,
3742 { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
3743 VALS (report_vals_ext), 0x0C, "Report Request", HFILL } },
3744 { &hf_addr_dir_rep_req2,
3745 { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
3746 VALS (report_vals_ext), 0xC0, "Report Request", HFILL } },
3747 { &hf_addr_dir_rep_req3,
3748 { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
3749 VALS (report_vals), 0xC0, "Report Request", HFILL } },
3750 { &hf_addr_dir_not_req1,
3751 { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
3752 VALS (notif_vals_ext), 0x03, "Notification Request", HFILL } },
3753 { &hf_addr_dir_not_req2,
3754 { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
3755 VALS (notif_vals_ext), 0xC0, "Notification Request", HFILL } },
3756 { &hf_addr_dir_not_req3,
3757 { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
3758 VALS (notif_vals), 0xC0, "Notification Request", HFILL } },
3759 { &hf_addr_dir_action,
3760 { "Action", "dmp.action", FT_BOOLEAN, 8,
3761 TFS (&yes_no), 0x80, "Action", HFILL } },
3762 { &hf_addr_dir_address,
3763 { "Direct Address", "dmp.direct_addr", FT_UINT8,
3764 BASE_DEC, NULL, 0x7F, "Direct Address", HFILL } },
3765 { &hf_addr_dir_address_generated,
3766 { "Direct Address", "dmp.direct_addr", FT_UINT32,
3767 BASE_DEC, NULL, 0x0, "Direct Address", HFILL } },
3768 { &hf_addr_dir_address1,
3769 { "Direct Address (bits 6-0)", "dmp.direct_addr1", FT_UINT8,
3770 BASE_DEC, NULL, 0x7F, "Direct Address (bits 6-0)", HFILL } },
3771 { &hf_addr_dir_address2,
3772 { "Direct Address (bits 12-7)", "dmp.direct_addr2", FT_UINT8,
3773 BASE_DEC, NULL, 0x3F, "Direct Address (bits 12-7)", HFILL } },
3774 { &hf_addr_dir_address3,
3775 { "Direct Address (bits 18-13)", "dmp.direct_addr3", FT_UINT8,
3776 BASE_DEC, NULL, 0x3F, "Direct Address (bits 18-13)", HFILL } },
3781 { &hf_addr_ext_form,
3782 { "Address Form", "dmp.addr_form", FT_UINT8, BASE_DEC,
3783 VALS (&addr_form), 0xE0, "Address Form", HFILL } },
3784 { &hf_addr_ext_action,
3785 { "Action", "dmp.action", FT_BOOLEAN, 8,
3786 TFS (&yes_no), 0x10, "Action", HFILL } },
3787 { &hf_addr_ext_rep_req,
3788 { "Report Request", "dmp.rep_rec", FT_UINT8, BASE_HEX,
3789 VALS (report_vals), 0x0C, "Report Request", HFILL } },
3790 { &hf_addr_ext_not_req,
3791 { "Notification Request", "dmp.not_req", FT_UINT8, BASE_HEX,
3792 VALS (notif_vals), 0x03, "Notification Request", HFILL } },
3793 { &hf_addr_ext_rec_ext,
3794 { "Recipient Number Extended", "dmp.rec_no_ext", FT_BOOLEAN, 8,
3795 NULL, 0x80, "Recipient Number Extended", HFILL } },
3796 { &hf_addr_ext_rec_no,
3797 { "Recipient Number Offset", "dmp.rec_no_offset", FT_UINT8,
3798 BASE_DEC, NULL, 0x7F, "Recipient Number Offset", HFILL } },
3799 { &hf_addr_ext_rec_no_generated,
3800 { "Recipient Number", "dmp.rec_no", FT_UINT32,
3801 BASE_DEC, NULL, 0x0, "Recipient Number", HFILL } },
3802 { &hf_addr_ext_rec_no1,
3803 { "Recipient Number (bits 6-0)", "dmp.rec_no_offset1", FT_UINT8,
3804 BASE_DEC, NULL, 0x7F, "Recipient Number (bits 6-0) Offset", HFILL } },
3805 { &hf_addr_ext_rec_no2,
3806 { "Recipient Number (bits 14-7)", "dmp.rec_no_offset2", FT_UINT8,
3807 BASE_DEC, NULL, 0xFF, "Recipient Number (bits 14-7) Offset", HFILL } },
3808 { &hf_addr_ext_address,
3809 { "Extended Address", "dmp.addr_form", FT_NONE, BASE_NONE,
3810 NULL, 0x0, "Extended Address", HFILL } },
3811 { &hf_addr_ext_type,
3812 { "Address Type", "dmp.addr_type", FT_UINT8, BASE_DEC,
3813 VALS (&ext_addr_type), 0xE0, "Address Type", HFILL } },
3814 { &hf_addr_ext_type_ext,
3815 { "Address Type Extended", "dmp.addr_type_ext", FT_UINT8,
3816 BASE_DEC, VALS (&ext_addr_type_ext), 0xE0, "Address Type Extended",
3818 { &hf_addr_ext_length,
3819 { "Address Length", "dmp.addr_length", FT_UINT8,
3820 BASE_DEC, NULL, 0x1F, "Address Length", HFILL } },
3821 { &hf_addr_ext_length_generated,
3822 { "Address Length", "dmp.addr_length", FT_UINT32,
3823 BASE_DEC, NULL, 0x0, "Address Length", HFILL } },
3824 { &hf_addr_ext_length1,
3825 { "Address Length (bits 4-0)", "dmp.addr_length1", FT_UINT8,
3826 BASE_DEC, NULL, 0x1F, "Address Length (bits 4-0)", HFILL } },
3827 { &hf_addr_ext_length2,
3828 { "Address Length (bits 9-5)", "dmp.addr_length2", FT_UINT8,
3829 BASE_DEC, NULL, 0x1F, "Address Length (bits 9-5)", HFILL } },
3830 { &hf_addr_ext_asn1_ber,
3831 { "ASN.1 BER-encoded OR-name", "dmp.or_name", FT_NONE,
3832 BASE_NONE, NULL, 0x0, "ASN.1 BER-encoded OR-name", HFILL } },
3833 { &hf_addr_ext_asn1_per,
3834 { "ASN.1 PER-encoded OR-name", "dmp.asn1_per", FT_BYTES,
3835 BASE_DEC, NULL, 0x0, "ASN.1 PER-encoded OR-name", HFILL } },
3836 { &hf_addr_ext_unknown,
3837 { "Unknown encoded address", "dmp.addr_unknown", FT_BYTES,
3838 BASE_DEC, NULL, 0x0, "Unknown encoded address", HFILL } },
3843 { &hf_message_content,
3844 { "Message Content", "dmp.message", FT_NONE, BASE_NONE,
3845 NULL, 0x0, "Message Content", HFILL } },
3846 { &hf_report_content,
3847 { "Report Content", "dmp.report", FT_NONE, BASE_NONE,
3848 NULL, 0x0, "Report Content", HFILL } },
3849 { &hf_notif_content,
3850 { "Notification Content", "dmp.notification", FT_NONE, BASE_NONE,
3851 NULL, 0x0, "Notification Content", HFILL } },
3853 { &hf_message_st_type,
3854 { "Message type", "dmp.msg_type", FT_UINT8, BASE_DEC,
3855 VALS (message_type_vals), 0xC0, "Message type", HFILL } },
3856 { &hf_message_precedence,
3857 { "Precedence", "dmp.precedence", FT_UINT8, BASE_DEC,
3858 VALS (precedence), 0x1C, "Precedence", HFILL } },
3859 { &hf_message_importance,
3860 { "Importance", "dmp.importance", FT_UINT8, BASE_DEC,
3861 VALS (importance), 0x1C, "Importance", HFILL } },
3862 { &hf_message_body_format,
3863 { "Body format", "dmp.body_format", FT_UINT8, BASE_DEC,
3864 VALS (body_format_vals), 0x03, "Body format", HFILL } },
3866 /* Security Values */
3867 { &hf_message_sec_class_nat,
3868 { "Security Classification", "dmp.sec_class", FT_UINT8,
3869 BASE_DEC, VALS (sec_class), 0xE0, "Security Classification", HFILL}},
3870 { &hf_message_sec_class_val,
3871 { "Security Classification", "dmp.sec_class", FT_UINT8,
3872 BASE_DEC, NULL, 0xE0, "Security Classification", HFILL}},
3873 { &hf_message_sec_pol,
3874 { "Security Policy", "dmp.sec_pol", FT_UINT8, BASE_DEC,
3875 VALS (sec_pol), 0x1C, "Security Policy", HFILL } },
3876 { &hf_message_heading_flags,
3877 { "Heading Flags", "dmp.heading_flags", FT_NONE, BASE_NONE,
3878 NULL, 0x0, "Heading Flags", HFILL } },
3879 { &hf_message_auth_users,
3880 { "Authorizing users discarded", "dmp.auth_discarded",
3881 FT_BOOLEAN, 8, TFS (&yes_no), 0x02,
3882 "Authorizing users discarded", HFILL }},
3883 { &hf_message_subject_disc,
3884 { "Subject discarded", "dmp.subject_discarded", FT_BOOLEAN, 8,
3885 TFS (&yes_no), 0x01, "Subject discarded", HFILL } },
3887 /* National Policy Identifier */
3888 { &hf_message_national_policy_id,
3889 { "National Policy Identifier", "dmp.nat_pol_id", FT_UINT8,
3890 BASE_DEC, VALS(nat_pol_id), 0x0, "National Policy Identifier",
3893 /* Mission Policy Identifier */
3894 { &hf_message_mission_policy_id,
3895 { "Mission Policy Identifier", "dmp.mission_pol_id", FT_UINT8,
3896 BASE_DEC, NULL, 0x0, "Mission Policy Identifier",
3899 /* Security Categories */
3900 { &hf_message_sec_cat_nat,
3901 { "Security Categories", "dmp.sec_cat", FT_UINT8, BASE_HEX,
3902 NULL, 0x0, "Security Categories", HFILL } },
3903 { &hf_message_sec_cat_val,
3904 { "Security Categories", "dmp.sec_cat", FT_UINT8, BASE_HEX,
3905 NULL, 0x0, "Security Categories", HFILL } },
3906 { &hf_message_sec_cat_cl,
3907 { "Clear", "dmp.sec_cat.cl", FT_BOOLEAN, 8,
3908 TFS (&set_notset), 0x80, "Clear", HFILL } },
3909 { &hf_message_sec_cat_cs,
3910 { "Crypto Security", "dmp.sec_cat.cs", FT_BOOLEAN, 8,
3911 TFS (&set_notset), 0x40, "Crypto Security", HFILL } },
3912 { &hf_message_sec_cat_ex,
3913 { "Exclusive", "dmp.sec_cat.ex", FT_BOOLEAN, 8,
3914 TFS (&set_notset), 0x20, "Exclusive", HFILL } },
3915 { &hf_message_sec_cat_ne,
3916 { "National Eyes Only", "dmp.sec_cat.ne", FT_BOOLEAN, 8,
3917 TFS (&set_notset), 0x10, "National Eyes Only", HFILL } },
3918 { &hf_message_sec_cat_bit0,
3919 { "Bit 0", "dmp.sec_cat.bit0", FT_BOOLEAN, 8,
3920 TFS (&set_notset), 0x01, "Bit 0", HFILL } },
3921 { &hf_message_sec_cat_bit1,
3922 { "Bit 1", "dmp.sec_cat.bit1", FT_BOOLEAN, 8,
3923 TFS (&set_notset), 0x02, "Bit 1", HFILL } },
3924 { &hf_message_sec_cat_bit2,
3925 { "Bit 2", "dmp.sec_cat.bit2", FT_BOOLEAN, 8,
3926 TFS (&set_notset), 0x04, "Bit 2", HFILL } },
3927 { &hf_message_sec_cat_bit3,
3928 { "Bit 3", "dmp.sec_cat.bit3", FT_BOOLEAN, 8,
3929 TFS (&set_notset), 0x08, "Bit 3", HFILL } },
3930 { &hf_message_sec_cat_bit4,
3931 { "Bit 4", "dmp.sec_cat.bit4", FT_BOOLEAN, 8,
3932 TFS (&set_notset), 0x10, "Bit 4", HFILL } },
3933 { &hf_message_sec_cat_bit5,
3934 { "Bit 5", "dmp.sec_cat.bit5", FT_BOOLEAN, 8,
3935 TFS (&set_notset), 0x20, "Bit 5", HFILL } },
3936 { &hf_message_sec_cat_bit6,
3937 { "Bit 6", "dmp.sec_cat.bit6", FT_BOOLEAN, 8,
3938 TFS (&set_notset), 0x40, "Bit 6", HFILL } },
3939 { &hf_message_sec_cat_bit7,
3940 { "Bit 7", "dmp.sec_cat.bit7", FT_BOOLEAN, 8,
3941 TFS (&set_notset), 0x80, "Bit 7", HFILL } },
3944 { &hf_message_exp_time,
3945 { "Expiry Time", "dmp.expiry_time", FT_UINT8, BASE_HEX,
3946 NULL, 0x0, "Expiry Time", HFILL } },
3947 { &hf_message_exp_time_val,
3948 { "Expiry Time Value", "dmp.expiry_time_val", FT_UINT8, BASE_HEX,
3949 NULL, 0xFF, "Expiry Time Value", HFILL } },
3953 { "DTG", "dmp.dtg", FT_UINT8, BASE_HEX,
3954 NULL, 0xFF, "DTG", HFILL } },
3955 { &hf_message_dtg_sign,
3956 { "DTG in the", "dmp.dtg.sign", FT_BOOLEAN, 8, TFS (&dtg_sign),
3957 0x80, "Sign", HFILL } },
3958 { &hf_message_dtg_val,
3959 { "DTG Value", "dmp.dtg.val", FT_UINT8, BASE_HEX, NULL,
3960 0x7F, "DTG Value", HFILL } },
3964 { "SIC", "dmp.sic", FT_STRING, BASE_DEC,
3965 NULL, 0x0, "SIC", HFILL } },
3966 { &hf_message_sic_key,
3967 { "SICs", "dmp.sic_key", FT_NONE, BASE_NONE,
3968 NULL, 0x0, "SIC Content", HFILL } },
3969 { &hf_message_sic_key_values,
3970 { "Content Byte", "dmp.sic_key.values", FT_UINT8, BASE_HEX,
3971 NULL, 0x0, "SIC Content Byte", HFILL } },
3972 { &hf_message_sic_key_type,
3973 { "Type", "dmp.sic_key.type", FT_UINT8, BASE_HEX,
3974 VALS (sic_key_type), 0xF0, "SIC Content Type", HFILL } },
3975 { &hf_message_sic_key_chars,
3976 { "Valid Characters", "dmp.sic_key.chars", FT_BOOLEAN, 8,
3977 TFS (&sic_key_chars), 0x08, "SIC Valid Characters", HFILL } },
3978 { &hf_message_sic_key_num,
3979 { "Number of SICs", "dmp.sic_key.num", FT_UINT8, BASE_HEX,
3980 VALS (sic_key_num), 0x07, "Number of SICs", HFILL } },
3981 { &hf_message_sic_bitmap,
3982 { "Length Bitmap (0 = 3 bytes, 1 = 4-8 bytes)", "dmp.sic_bitmap",
3983 FT_UINT8, BASE_HEX, NULL, 0xFF, "SIC Length Bitmap", HFILL } },
3984 { &hf_message_sic_bits,
3985 { "Bit 7-4", "dmp.sic_bits", FT_UINT8, BASE_HEX,
3986 VALS(sic_bit_vals), 0xF0, "SIC Bit 7-4, Characters [A-Z0-9] only",
3988 { &hf_message_sic_bits_any,
3989 { "Bit 7-4", "dmp.sic_bits_any", FT_UINT8, BASE_HEX,
3990 VALS(sic_bit_any_vals), 0xF0, "SIC Bit 7-4, Any valid characters",
3993 /* Subject Message Id */
3994 { &hf_message_subj_id,
3995 { "Subject Message Identifier", "dmp.subj_id", FT_UINT16,
3996 BASE_DEC, NULL, 0x0, "Subject Message Identifier", HFILL } },
4002 { "Message Body", "dmp.body", FT_NONE, BASE_NONE, NULL,
4003 0x0, "Message Body", HFILL}},
4007 { "EIT", "dmp.body.eit", FT_UINT8, BASE_DEC,
4008 VALS(eit_vals), 0xE0, "Encoded Information Type", HFILL } },
4009 { &hf_message_compr,
4010 { "Compression", "dmp.body.compression", FT_UINT8, BASE_DEC,
4011 VALS(compression_vals), 0x18, "Compression", HFILL } },
4014 { &hf_message_subject,
4015 { "Subject", "dmp.subject", FT_STRINGZ, BASE_DEC,
4016 NULL, 0x0, "Subject", HFILL } },
4019 { &hf_message_body_data,
4020 { "User data", "dmp.body.data", FT_NONE, BASE_NONE,
4021 NULL, 0x0, "User data", HFILL } },
4022 { &hf_message_body_plain,
4023 { "Message Body", "dmp.body.plain", FT_STRING, BASE_DEC,
4024 NULL, 0x0, "Message Body", HFILL } },
4025 { &hf_message_bodyid_uint8,
4026 { "Structured Id", "dmp.body.id", FT_UINT8, BASE_DEC,
4027 NULL, 0x0, "Structured Body Id (1 byte)", HFILL } },
4028 { &hf_message_bodyid_uint16,
4029 { "Structured Id", "dmp.body.id", FT_UINT16, BASE_DEC,
4030 NULL, 0x0, "Structured Body Id (2 bytes)", HFILL } },
4031 { &hf_message_bodyid_uint32,
4032 { "Structured Id", "dmp.body.id", FT_UINT32, BASE_DEC,
4033 NULL, 0x0, "Structured Body Id (4 bytes)", HFILL } },
4034 { &hf_message_bodyid_uint64,
4035 { "Structured Id", "dmp.body.id", FT_UINT64, BASE_DEC,
4036 NULL, 0x0, "Structured Body Id (8 bytes)", HFILL } },
4037 { &hf_message_bodyid_string,
4038 { "Structured Id", "dmp.body.id", FT_STRING, BASE_DEC,
4039 NULL, 0x0, "Structured Body Id (fixed text string)", HFILL } },
4040 { &hf_message_bodyid_zstring,
4041 { "Structured Id", "dmp.body.id", FT_STRINGZ, BASE_DEC,
4042 NULL, 0x0, "Structured Body Id (zero terminated text string)",
4044 { &hf_message_body_structured,
4045 { "Structured Body", "dmp.body.structured", FT_BYTES, BASE_DEC,
4046 NULL, 0x0, "Structured Body", HFILL } },
4047 { &hf_message_body_uncompr,
4048 { "Uncompressed User data", "dmp.body.uncompressed", FT_NONE,
4049 BASE_NONE, NULL, 0x0, "Uncompressed User data", HFILL } },
4050 { &hf_message_body_uncompressed,
4051 { "Uncompressed Message Body", "dmp.body.uncompressed",
4052 FT_STRING, BASE_DEC, NULL, 0x0, "Uncompressed Message Body",
4058 { &hf_delivery_report,
4059 { "Delivery Report", "dmp.dr", FT_NONE, BASE_NONE, NULL,
4060 0x0, "Delivery Report", HFILL}},
4061 { &hf_non_delivery_report,
4062 { "Non-Delivery Report", "dmp.ndr", FT_NONE, BASE_NONE, NULL,
4063 0x0, "Non-Delivery Report", HFILL}},
4066 { "Report Type", "dmp.report_type", FT_BOOLEAN, 8,
4067 TFS (&report_type), 0x80, "Report Type", HFILL } },
4068 { &hf_report_info_present_dr,
4069 { "Info Present", "dmp.info_present", FT_BOOLEAN, 8,
4070 TFS (&present_values), 0x40, "Info Present", HFILL } },
4071 { &hf_report_addr_enc_dr,
4072 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
4073 TFS (&addr_enc), 0x20, "Address Encoding", HFILL } },
4074 { &hf_report_del_time,
4075 { "Delivery Time", "dmp.delivery_time", FT_UINT8, BASE_DEC,
4076 NULL, 0x0, "Delivery Time", HFILL } },
4077 { &hf_report_addr_enc_ndr,
4078 { "Address Encoding", "dmp.addr_encoding", FT_BOOLEAN, 8,
4079 TFS (&addr_enc), 0x40, "Address Encoding", HFILL } },
4080 { &hf_report_reason,
4081 { "Reason (X.411)", "dmp.report_reason", FT_UINT8, BASE_DEC,
4082 VALS (x411_NonDeliveryReasonCode_vals), 0x3F,
4083 "Reason", HFILL } },
4084 { &hf_report_info_present_ndr,
4085 { "Info Present", "dmp.info_present", FT_BOOLEAN, 8,
4086 TFS (&present_values), 0x80, "Info Present", HFILL } },
4088 { "Diagnostic (X.411)", "dmp.report_diagnostic", FT_UINT8, BASE_DEC,
4089 VALS (x411_NonDeliveryDiagnosticCode_vals), 0x7F,
4090 "Diagnostic", HFILL } },
4091 { &hf_report_suppl_info_len,
4092 { "Supplementary Information", "dmp.suppl_info_len", FT_UINT8,
4093 BASE_DEC, NULL, 0x0, "Supplementary Information Length", HFILL } },
4094 { &hf_report_suppl_info,
4095 { "Supplementary Information", "dmp.suppl_info", FT_STRINGZ,
4096 BASE_DEC, NULL, 0x0, "Supplementary Information", HFILL } },
4101 { &hf_receipt_notif,
4102 { "Receipt Notification (RN)", "dmp.rn", FT_NONE, BASE_NONE,
4103 NULL, 0x0, "Receipt Notification (RN)", HFILL} },
4104 { &hf_non_receipt_notif,
4105 { "Non-Receipt Notification (NRN)", "dmp.nrn", FT_NONE, BASE_NONE,
4106 NULL, 0x0, "Non-Receipt Notification (NRN)", HFILL} },
4108 { "Other Notification (ON)", "dmp.on", FT_NONE, BASE_NONE,
4109 NULL, 0x0, "Other Notification (ON)", HFILL} },
4112 { "Notification Type", "dmp.notif_type", FT_UINT8, BASE_DEC,
4113 VALS (notif_type), 0x03, "Notification Type", HFILL } },
4114 { &hf_notif_rec_time,
4115 { "Receipt Time", "dmp.receipt_time", FT_UINT8, BASE_HEX,
4116 NULL, 0x0, "Receipt time", HFILL } },
4117 { &hf_notif_rec_time_val,
4118 { "Receipt Time Value", "dmp.receipt_time_val", FT_UINT8,
4119 BASE_HEX, NULL, 0xFF, "Receipt Time Value", HFILL } },
4120 { &hf_notif_suppl_info_len,
4121 { "Supplementary Information", "dmp.suppl_info_len",
4122 FT_UINT8, BASE_DEC, NULL, 0x0, "Supplementary Information Length",
4124 { &hf_notif_suppl_info,
4125 { "Supplementary Information", "dmp.suppl_info",
4126 FT_STRINGZ, BASE_DEC, NULL, 0x0, "Supplementary Information",
4128 { &hf_notif_non_rec_reason,
4129 { "Non-Receipt Reason", "dmp.notif_non_rec_reason",
4130 FT_UINT8, BASE_DEC, VALS (x420_NonReceiptReasonField_vals), 0x0,
4131 "Non-Receipt Reason", HFILL } },
4132 { &hf_notif_discard_reason,
4133 { "Discard Reason", "dmp.notif_discard_reason", FT_UINT8,
4134 BASE_DEC, VALS (x420_DiscardReasonField_vals), 0x0,
4135 "Discard Reason", HFILL } },
4136 { &hf_notif_on_type,
4137 { "ON Type", "dmp.notif_on_type", FT_UINT8, BASE_DEC,
4138 VALS (on_type), 0x0, "ON Type", HFILL } },
4140 { "ACP127 Recipient", "dmp.acp127recip_len", FT_UINT8,
4141 BASE_DEC, NULL, 0x0, "ACP 127 Recipient Length", HFILL } },
4142 { &hf_notif_acp127recip,
4143 { "ACP127 Recipient", "dmp.acp127recip", FT_STRINGZ,
4144 BASE_DEC, NULL, 0x0, "ACP 127 Recipient", HFILL } },
4150 { "Acknowledgement", "dmp.ack", FT_NONE, BASE_NONE,
4151 NULL, 0x0, "Acknowledgement", HFILL } },
4153 { "Ack Reason", "dmp.ack_reason", FT_UINT8, BASE_DEC,
4154 VALS (&ack_reason), 0x0, "Reason", HFILL } },
4155 { &hf_ack_diagnostic,
4156 { "Ack Diagnostic", "dmp.ack_diagnostic", FT_UINT8, BASE_DEC,
4157 NULL, 0x0, "Diagnostic", HFILL } },
4159 { "Recipient List", "dmp.ack_rec_list", FT_NONE, BASE_NONE,
4160 NULL, 0x0, "Recipient List", HFILL } },
4166 { "Checksum", "dmp.checksum", FT_UINT16, BASE_HEX,
4167 NULL, 0x0, "Checksum", HFILL } },
4168 { &hf_checksum_good,
4169 { "Good", "dmp.checksum_good", FT_BOOLEAN, BASE_NONE,
4170 NULL, 0x0, "True: checksum matches packet content; "
4171 "False: doesn't match content or not checked", HFILL } },
4173 { "Bad", "dmp.checksum_bad", FT_BOOLEAN, BASE_NONE,
4174 NULL, 0x0, "True: checksum doesn't match packet content; "
4175 "False: matches content or not checked", HFILL } },
4178 ** Ack matching / Resend
4180 { &hf_analysis_ack_time,
4181 { "Acknowledgement Time", "dmp.analysis.ack_time", FT_RELATIVE_TIME, BASE_NONE,
4182 NULL, 0x0, "The time between the Message and the Acknowledge", HFILL } },
4183 { &hf_analysis_rep_time,
4184 { "Report Reply Time", "dmp.analysis.report_time", FT_RELATIVE_TIME, BASE_NONE,
4185 NULL, 0x0, "The time between the Message and the Report", HFILL } },
4186 { &hf_analysis_not_time,
4187 { "Notification Reply Time", "dmp.analysis.notif_time", FT_RELATIVE_TIME, BASE_NONE,
4188 NULL, 0x0, "The time between the Message and the Notification", HFILL } },
4189 { &hf_analysis_total_time,
4190 { "Total Time", "dmp.analysis.total_time", FT_RELATIVE_TIME, BASE_NONE,
4191 NULL, 0x0, "The time between the first Message and the Acknowledge", HFILL } },
4192 { &hf_analysis_retrans_time,
4193 { "Retransmission Time", "dmp.analysis.retrans_time", FT_RELATIVE_TIME, BASE_NONE,
4194 NULL, 0x0, "The time between the last Message and this Message", HFILL } },
4195 { &hf_analysis_total_retrans_time,
4196 { "Total Retransmission Time", "dmp.analysis.total_retrans_time", FT_RELATIVE_TIME, BASE_NONE,
4197 NULL, 0x0, "The time between the first Message and this Message", HFILL } },
4198 { &hf_analysis_msg_num,
4199 { "Message in", "dmp.analysis.msg_in", FT_FRAMENUM, BASE_NONE,
4200 NULL, 0x0, "This packet has a Message in this frame", HFILL } },
4201 { &hf_analysis_ack_num,
4202 { "Acknowledgement in", "dmp.analysis.ack_in", FT_FRAMENUM, BASE_NONE,
4203 NULL, 0x0, "This packet has an Acknowledgement in this frame", HFILL } },
4204 { &hf_analysis_rep_num,
4205 { "Report in", "dmp.analysis.report_in", FT_FRAMENUM, BASE_NONE,
4206 NULL, 0x0, "This packet has a Report in this frame", HFILL } },
4207 { &hf_analysis_not_num,
4208 { "Notification in", "dmp.analysis.notif_in", FT_FRAMENUM, BASE_NONE,
4209 NULL, 0x0, "This packet has a Notification in this frame", HFILL } },
4210 { &hf_analysis_msg_missing,
4211 { "Message missing", "dmp.analysis.msg_missing", FT_NONE, BASE_NONE,
4212 NULL, 0x0, "The Message for this packet is missing", HFILL } },
4213 { &hf_analysis_ack_missing,
4214 { "Acknowledgement missing", "dmp.analysis.ack_missing", FT_NONE, BASE_NONE,
4215 NULL, 0x0, "The acknowledgement for this packet is missing", HFILL } },
4216 { &hf_analysis_retrans_no,
4217 { "Retransmission #", "dmp.analysis.retrans_no", FT_UINT32, BASE_DEC,
4218 NULL, 0x0, "Retransmission count", HFILL } },
4219 { &hf_analysis_ack_dup_no,
4220 { "Duplicate ACK #", "dmp.analysis.dup_ack_no", FT_UINT32, BASE_DEC,
4221 NULL, 0x0, "Duplicate Acknowledgement count", HFILL } },
4222 { &hf_analysis_msg_resend_from,
4223 { "Retransmission of Message sent in", "dmp.analysis.msg_first_sent_in",
4224 FT_FRAMENUM, BASE_NONE,
4225 NULL, 0x0, "This Message was first sent in this frame", HFILL } },
4226 { &hf_analysis_rep_resend_from,
4227 { "Retransmission of Report sent in", "dmp.analysis.report_first_sent_in",
4228 FT_FRAMENUM, BASE_NONE,
4229 NULL, 0x0, "This Report was first sent in this frame", HFILL } },
4230 { &hf_analysis_not_resend_from,
4231 { "Retransmission of Notification sent in", "dmp.analysis.notif_first_sent_in",
4232 FT_FRAMENUM, BASE_NONE,
4233 NULL, 0x0, "This Notification was first sent in this frame", HFILL } },
4234 { &hf_analysis_ack_resend_from,
4235 { "Retransmission of Acknowledgement sent in", "dmp.analysis.ack_first_sent_in",
4236 FT_FRAMENUM, BASE_NONE,
4237 NULL, 0x0, "This Acknowledgement was first sent in this frame", HFILL } },
4242 { &hf_reserved_0x01,
4243 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4244 NULL, 0x01, "Reserved", HFILL } },
4245 { &hf_reserved_0x02,
4246 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4247 NULL, 0x02, "Reserved", HFILL } },
4248 { &hf_reserved_0x04,
4249 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4250 NULL, 0x04, "Reserved", HFILL } },
4251 { &hf_reserved_0x07,
4252 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4253 NULL, 0x07, "Reserved", HFILL } },
4254 { &hf_reserved_0x08,
4255 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4256 NULL, 0x08, "Reserved", HFILL } },
4257 { &hf_reserved_0x1F,
4258 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4259 NULL, 0x1F, "Reserved", HFILL } },
4260 { &hf_reserved_0x20,
4261 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4262 NULL, 0x20, "Reserved", HFILL } },
4263 { &hf_reserved_0x40,
4264 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4265 NULL, 0x40, "Reserved", HFILL } },
4266 { &hf_reserved_0xC0,
4267 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4268 NULL, 0xC0, "Reserved", HFILL } },
4269 { &hf_reserved_0xE0,
4270 { "Reserved", "dmp.reserved", FT_UINT8, BASE_DEC,
4271 NULL, 0xE0, "Reserved", HFILL } },
4272 { &hf_reserved_0x8000,
4273 { "Reserved", "dmp.reserved", FT_UINT16, BASE_DEC,
4274 NULL, 0x8000, "Reserved", HFILL } },
4277 static gint *ett[] = {
4280 &ett_envelope_version,
4281 &ett_envelope_hop_count,
4282 &ett_envelope_rec_present,
4283 &ett_envelope_addr_enc,
4284 &ett_envelope_checksum,
4285 &ett_envelope_cont_type,
4286 &ett_envelope_subm_time,
4287 &ett_envelope_time_diff,
4288 &ett_envelope_flags,
4289 &ett_envelope_recipients,
4290 &ett_envelope_ext_recipients,
4291 &ett_envelope_addresses,
4293 &ett_address_direct,
4294 &ett_address_rec_no,
4295 &ett_address_extended,
4296 &ett_address_ext_form,
4297 &ett_address_ext_rec_no,
4298 &ett_address_ext_action,
4299 &ett_address_ext_rep_req,
4300 &ett_address_ext_not_req,
4301 &ett_address_ext_type,
4302 &ett_address_ext_length,
4305 &ett_message_st_type,
4306 &ett_message_reserved,
4307 &ett_message_precedence,
4308 &ett_message_importance,
4309 &ett_message_body_format,
4310 &ett_message_sec_class,
4311 &ett_message_sec_pol,
4312 &ett_message_sec_cat,
4313 &ett_message_heading_flags,
4314 &ett_message_exp_time,
4317 &ett_message_sic_key,
4318 &ett_message_sic_bitmap,
4319 &ett_message_sic_bits,
4322 &ett_message_body_reserved,
4324 &ett_message_body_uncompr,
4327 &ett_report_info_present_dr,
4328 &ett_report_info_present_ndr,
4329 &ett_report_addr_enc_dr,
4330 &ett_report_addr_enc_ndr,
4331 &ett_report_reserved,
4332 &ett_report_del_time,
4334 &ett_report_suppl_info,
4338 &ett_notif_rec_time,
4339 &ett_notif_suppl_info,
4340 &ett_notif_acp127recip,
4347 module_t *dmp_module;
4349 proto_dmp = proto_register_protocol (PNAME, PSNAME, PFNAME);
4350 register_dissector(PFNAME, dissect_dmp, proto_dmp);
4352 proto_register_field_array (proto_dmp, hf, array_length (hf));
4353 proto_register_subtree_array (ett, array_length (ett));
4354 register_init_routine (&dmp_init_routine);
4356 /* Set default UDP ports */
4357 range_convert_str (&global_dmp_port_range, DEFAULT_DMP_PORT_RANGE,
4360 /* Register our configuration options */
4361 dmp_module = prefs_register_protocol (proto_dmp, proto_reg_handoff_dmp);
4363 prefs_register_obsolete_preference (dmp_module, "udp_port");
4364 prefs_register_obsolete_preference (dmp_module, "udp_port_second");
4366 prefs_register_range_preference (dmp_module, "udp_ports",
4368 "Port numbers used for DMP traffic",
4369 &global_dmp_port_range, MAX_UDP_PORT);
4370 prefs_register_bool_preference (dmp_module, "seq_ack_analysis",
4372 "Calculate sequence/acknowledgement analysis",
4373 &use_seq_ack_analysis);
4374 prefs_register_bool_preference (dmp_module, "align_ids",
4375 "Align identifiers in info list",
4376 "Align identifiers in info list"
4377 " (does not align when retransmission or"
4378 " duplicate acknowledgement indication)",
4380 prefs_register_bool_preference (dmp_module, "subject_as_id",
4381 "Print subject as body id",
4382 "Print subject as body id in free text "
4383 "messages with subject",
4384 &dmp_subject_as_id);
4385 prefs_register_enum_preference (dmp_module, "struct_print",
4386 "Structured message id format",
4387 "Format of the structured message id",
4388 &dmp_struct_format, struct_id_options,
4390 prefs_register_uint_preference (dmp_module, "struct_offset",
4391 "Offset to structured message id",
4392 "Used to set where the structured message "
4393 "id starts in the User Data",
4394 10, &dmp_struct_offset);
4396 prefs_register_uint_preference (dmp_module, "struct_length",
4397 "Fixed text string length",
4398 "Used to set length of fixed text string "
4399 "in the structured message id format "
4400 "(maximum 128 characters)",
4401 10, &dmp_struct_length);
4404 static void range_delete_callback (guint32 port)
4406 dissector_delete ("udp.port", port, dmp_handle);
4409 static void range_add_callback (guint32 port)
4411 dissector_add ("udp.port", port, dmp_handle);
4414 void proto_reg_handoff_dmp (void)
4416 static range_t *dmp_port_range;
4417 static gboolean dmp_prefs_initialized = FALSE;
4419 if (!dmp_prefs_initialized) {
4420 dmp_handle = find_dissector(PFNAME);
4421 dmp_prefs_initialized = TRUE;
4423 range_foreach (dmp_port_range, range_delete_callback);
4424 g_free (dmp_port_range);
4427 /* Save port number for later deletion */
4428 dmp_port_range = range_copy (global_dmp_port_range);
4430 range_foreach (dmp_port_range, range_add_callback);
4439 * indent-tabs-mode: t
4442 * ex: set shiftwidth=2 tabstop=8 noexpandtab
4443 * :indentSize=2:tabSize=8:noTabs=false: