Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-s5066dts.c
blob522820c144dc4cf248d61e815b1a1e2676462cfb
1 /*
2 * packet-s5066dts.c
3 * Routines for STANAG 5066 DTS layer packet dissection
5 * Copyright (c) 2013
6 * by Ibrahim Can Yuce <canyuce [at] gmail [dot] com>
7 * by M. Baris Demiray <baris.demiray [at] gmail [dot] com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
20 #include <epan/expert.h>
21 #include "packet-tcp.h" /* For tcp_dissect_pdus() */
22 #include <epan/crc16-tvb.h>
23 #include <epan/crc32-tvb.h>
24 #include <wiretap/wtap.h>
26 #define DISSECTOR_NAME "s5066dts"
27 /* STANAG 5066 DPDU properties */
28 #define S5066_DPDU_MAX_DPDU_SIZE 1070
29 #define S5066_DPDU_FRAME_HEADER_LEN 15
30 /* Header field index (in bytes) and size (in bits) constants */
31 #define S5066_DPDU_EOW_TYPE_INDEX 2
32 #define S5066_DPDU_EOW_CONTENT_INDEX 3
33 #define S5066_DPDU_EOT_INDEX 4
34 #define S5066_DPDU_SIZE_OF_ADDRESS_INDEX 5
35 #define S5066_DPDU_SIZE_OF_HEADER_INDEX 5
36 #define S5066_DPDU_SYNC_SEQUENCE_SIZE 2 /*bytes*/
37 /* D_PDU message types */
38 #define S5066_DPDU_DATA_ONLY 0
39 #define S5066_DPDU_ACK_ONLY 1
40 #define S5066_DPDU_DATA_ACK 2
41 #define S5066_DPDU_RESET_WIN_RESYNC 3
42 #define S5066_DPDU_EXP_DATA_ONLY 4
43 #define S5066_DPDU_EXP_ACK_ONLY 5
44 #define S5066_DPDU_MANAGEMENT 6
45 #define S5066_DPDU_NON_ARQ_DATA 7
46 #define S5066_DPDU_EXP_NON_ARQ_DATA 8
47 #define S5066_DPDU_WARNING 15
48 /* EOW message types */
49 #define S5066_EOW_RESERVED 0
50 #define S5066_EOW_DRC_REQUEST 1
51 #define S5066_EOW_DRC_RESPONSE 2
52 #define S5066_EOW_UNRECOGNIZED_TYPE 3
53 #define S5066_EOW_CAPABILITY 4
54 #define S5066_EOW_ALM_REQUEST 5
55 #define S5066_EOW_ALM_RESPONSE 6
56 #define S5066_EOW_HDR_DRC_REQUEST 7
57 #define S5066_EOW_HFTRP_TOKEN 15
59 void proto_register_s5066dts(void);
61 static int proto_s5066dts;
63 static dissector_handle_t s5066dts_handle;
64 static dissector_handle_t s5066dts_over_tcp_handle;
66 /* Configuration parameters */
67 static bool config_proto_desegment = true;
69 /* Initialize expert fields */
70 static expert_field ei_s5066dts_eow_hdr_drc_request_invalid;
71 static expert_field ei_s5066dts_eow_hftrp_invalid;
73 /* TCP port that will be listened by the application that peer
74 * dts layers will be connected through
76 static range_t *config_s5066dts_ports;
78 static int hf_s5066dts_sync_word;
79 static int hf_s5066dts_dpdu_type;
80 static int hf_s5066dts_eow_type;
81 static int hf_s5066dts_eow_data;
82 static int hf_s5066dts_eot;
83 static int hf_s5066dts_address_size;
84 static int hf_s5066dts_header_size;
85 static int hf_s5066dts_header_crc;
86 static int hf_s5066dts_cpdu_crc;
87 static int hf_s5066dts_segmented_cpdu;
88 static int hf_s5066dts_dest_addr;
89 static int hf_s5066dts_src_addr;
91 /* EOW TYPES */
92 /* { 1, "DRC_REQUEST"}, */
93 static int hf_s5066dts_eow_drc_request_data_rate;
94 static int hf_s5066dts_eow_drc_request_interleaving;
95 static int hf_s5066dts_eow_drc_request_others;
96 /* { 2, "DRC_RESPONSE"}, */
97 static int hf_s5066dts_eow_drc_response_response;
98 static int hf_s5066dts_eow_drc_response_reason;
99 /* { 3, "UNRECOGNIZED_TYPE"}, */
100 static int hf_s5066dts_eow_unrec_type_response;
101 static int hf_s5066dts_eow_unrec_type_reason;
102 /* { 4, "CAPABILITY"}, */
103 static int hf_s5066dts_eow_capability_adaptive;
104 static int hf_s5066dts_eow_capability_stanag_4529;
105 static int hf_s5066dts_eow_capability_mil_std_188_110a;
106 static int hf_s5066dts_eow_capability_extended;
107 static int hf_s5066dts_eow_capability_full_duplex;
108 static int hf_s5066dts_eow_capability_split_frequency;
109 static int hf_s5066dts_eow_capability_non_arcs_ale;
110 static int hf_s5066dts_eow_capability_arcs;
111 /* { 5, "ALM_REQUEST"}, */
112 static int hf_s5066dts_eow_alm_request_data_rate;
113 static int hf_s5066dts_eow_alm_request_interleaving;
114 static int hf_s5066dts_eow_alm_request_others;
115 /* { 6, "ALM_RESPONSE"}, */
116 static int hf_s5066dts_eow_alm_response_response;
117 static int hf_s5066dts_eow_alm_response_reason;
118 /* { 7, "HDR_DRC_REQUEST"}, */
119 static int hf_s5066dts_eow_hdr_drc_request_waveform;
120 static int hf_s5066dts_eow_hdr_drc_request_num_channels;
121 static int hf_s5066dts_eow_hdr_drc_request_data_rate;
122 static int hf_s5066dts_eow_hdr_drc_request_interleaver_length;
123 /* {15, "HFTRP FRAME CONTROL"}, */
124 static int hf_s5066dts_eow_hftrp_hftrp_token;
126 /* DPDU TYPES */
127 /* { 0, "DATA_ONLY"}, */
128 static int hf_s5066dts_data_only_cpdu_start;
129 static int hf_s5066dts_data_only_cpdu_end;
130 static int hf_s5066dts_data_only_deliver_in_order;
131 static int hf_s5066dts_data_only_drop_cpdu;
132 static int hf_s5066dts_data_only_tx_win_uwe;
133 static int hf_s5066dts_data_only_tx_win_lwe;
134 static int hf_s5066dts_data_only_segmented_cpdu_size;
135 static int hf_s5066dts_data_only_transmit_sequence_number;
136 /* { 1, "ACK_ONLY"}, */
137 static int hf_s5066dts_ack_only_rx_lwe;
138 static int hf_s5066dts_ack_only_acks;
139 /* { 2, "DATA_ACK"}, */
140 static int hf_s5066dts_data_ack_cpdu_start;
141 static int hf_s5066dts_data_ack_cpdu_end;
142 static int hf_s5066dts_data_ack_deliver_in_order;
143 static int hf_s5066dts_data_ack_drop_cpdu;
144 static int hf_s5066dts_data_ack_tx_win_uwe;
145 static int hf_s5066dts_data_ack_tx_win_lwe;
146 static int hf_s5066dts_data_ack_segmented_cpdu_size;
147 static int hf_s5066dts_data_ack_transmit_sequence_number;
148 static int hf_s5066dts_data_ack_rx_lwe;
149 static int hf_s5066dts_data_ack_acks;
150 /* { 3, "RESET_WIN_RESYNC"}, */
151 static int hf_s5066dts_reset_win_resync_unused;
152 static int hf_s5066dts_reset_win_resync_full_reset_command;
153 static int hf_s5066dts_reset_win_resync_reset_tx_win_rqst;
154 static int hf_s5066dts_reset_win_resync_reset_rx_win_cmnd;
155 static int hf_s5066dts_reset_win_resync_reset_ack;
156 static int hf_s5066dts_reset_win_resync_new_rx_lwe;
157 static int hf_s5066dts_reset_win_resync_reset_frame_id_number;
158 /* { 4, "EXP_DATA_ONLY"}, */
159 static int hf_s5066dts_exp_data_only_cpdu_start;
160 static int hf_s5066dts_exp_data_only_cpdu_end;
161 static int hf_s5066dts_exp_data_only_cpdu_id;
162 static int hf_s5066dts_exp_data_only_segmented_cpdu_size;
163 static int hf_s5066dts_exp_data_only_transmit_sequence_number;
164 /* { 5, "EXP_ACK_ONLY"}, */
165 static int hf_s5066dts_exp_ack_only_rx_lwe;
166 static int hf_s5066dts_exp_ack_only_acks;
167 /* { 6, "MANAGEMENT"}, */
168 static int hf_s5066dts_management_unused;
169 static int hf_s5066dts_management_extended_message_flag;
170 static int hf_s5066dts_management_message;
171 static int hf_s5066dts_management_ack;
172 static int hf_s5066dts_management_management_frame_id;
173 static int hf_s5066dts_management_extended_message;
174 static int hf_s5066dts_management_extended_message_hftrp_payload_size;
175 static int hf_s5066dts_management_extended_message_hftrp_ra;
176 static int hf_s5066dts_management_extended_message_hftrp_seq_id;
177 static int hf_s5066dts_management_extended_message_hftrp_gen_seq_id;
178 static int hf_s5066dts_management_extended_message_hftrp_new_successor_id;
179 static int hf_s5066dts_management_extended_message_hftrp_number_of_nodes;
180 /* { 7, "NON_ARQ_DATA"}, */
181 static int hf_s5066dts_non_arq_data_cpdu_id_1;
182 static int hf_s5066dts_non_arq_data_deliver_in_order;
183 static int hf_s5066dts_non_arq_data_group_address;
184 static int hf_s5066dts_non_arq_data_cpdu_id_2;
185 static int hf_s5066dts_non_arq_data_cpdu_size;
186 static int hf_s5066dts_non_arq_data_cpdu_segment_offset;
187 static int hf_s5066dts_non_arq_data_cpdu_reception_window;
188 static int hf_s5066dts_non_arq_data_segmented_cpdu_size;
189 /* { 8, "EXP_NON_ARQ_DATA"}, */
190 static int hf_s5066dts_exp_non_arq_data_cpdu_id_1;
191 static int hf_s5066dts_exp_non_arq_data_deliver_in_order;
192 static int hf_s5066dts_exp_non_arq_data_group_address;
193 static int hf_s5066dts_exp_non_arq_data_cpdu_id_2;
194 static int hf_s5066dts_exp_non_arq_data_cpdu_size;
195 static int hf_s5066dts_exp_non_arq_data_cpdu_segment_offset;
196 static int hf_s5066dts_exp_non_arq_data_cpdu_reception_window;
197 static int hf_s5066dts_exp_non_arq_data_segmented_cpdu_size;
198 /* {15, "WARNING"}, */
199 static int hf_s5066dts_warning_frame_type;
200 static int hf_s5066dts_warning_reason;
202 static int ett_s5066dts;
203 static int ett_s5066dts_eow;
204 static int ett_s5066dts_address;
205 static int ett_s5066dts_pdu;
206 static int ett_s5066dts_hftrp_token;
208 static const value_string s5066dts_dpdu_type[] = {
209 { 0, "DATA_ONLY"},
210 { 1, "ACK_ONLY"},
211 { 2, "DATA_ACK"},
212 { 3, "RESET_WIN_RESYNC"},
213 { 4, "EXP_DATA_ONLY"},
214 { 5, "EXP_ACK_ONLY"},
215 { 6, "MANAGEMENT"},
216 { 7, "NON_ARQ_DATA"},
217 { 8, "EXP_NON_ARQ_DATA"},
218 {15, "WARNING"},
219 { 0, NULL},
222 static const value_string s5066dts_eow_type[] = {
223 { 0, "RESERVED"},
224 { 1, "DRC_REQUEST"},
225 { 2, "DRC_RESPONSE"},
226 { 3, "UNRECOGNIZED_TYPE"},
227 { 4, "CAPABILITY"},
228 { 5, "ALM_REQUEST"},
229 { 6, "ALM_RESPONSE"},
230 { 7, "HDR_DRC_REQUEST"},
231 { 15, "HFTRP_TOKEN"},
232 { 0, NULL},
235 static const value_string s5066dts_eow_data_rate[] = {
236 { 0, "75 bps"},
237 { 1, "150 bps"},
238 { 2, "300 bps"},
239 { 3, "600 bps"},
240 { 4, "1200 bps"},
241 { 5, "2400 bps"},
242 { 6, "3200 bps"},
243 { 7, "3600 bps"},
244 { 8, "4800 bps"},
245 { 9, "6400 bps"},
246 { 10, "8000 bps"},
247 { 11, "9600 bps"},
248 { 0, NULL},
251 static const value_string s5066dts_eow_interleaving[] = {
252 { 0, "No interleaving"},
253 { 1, "Short interleaving"},
254 { 2, "Long interleaving"},
255 { 3, "Reserved"},
256 { 0, NULL},
259 static const value_string s5066dts_eow_others[] = {
260 { 0, "Request: Master has independent data rate"},
261 { 1, "Request: Tx=Rx at master"},
262 { 2, "Advisory: Advising node has independent data rate"},
263 { 3, "Advisory: Tx=Rx at advising node"},
264 { 0, NULL},
267 static const value_string s5066dts_eow_response[] = {
268 { 0, "Accept"},
269 { 1, "Refuse"},
270 { 2, "Cancel"},
271 { 3, "Confirm"},
272 { 0, NULL},
275 static const value_string s5066dts_eow_reason[] = {
276 { 0, "No reason"},
277 { 1, "Tx and Rx parameters must be the same"},
278 { 2, "Not possible to change modem data rate"},
279 { 3, "Not possible to change modem interleaving"},
280 { 4, "Not possible to change modem data rate or interleaving"},
281 { 5, "Not consistent with local conditions"},
282 { 0, NULL},
285 static const value_string s5066dts_eow_waveform[] = {
286 { 0, "MS110A"},
287 { 1, "MS110B"},
288 { 2, "STANAG_4285"},
289 { 3, "STANAG_4539"},
290 { 4, "STANAG_4529"},
291 { 5, "STANAG_4415"},
292 { 6, "STANAG_4481_FSK"},
293 { 7, "USER_CONFIGURATION_OPTION_1"},
294 { 8, "USER_CONFIGURATION_OPTION_2"},
295 { 9, "USER_CONFIGURATION_OPTION_3"},
296 { 0, NULL},
299 /* Used in Packet List pane */
300 static const value_string s5066dts_eow_hftrp_frame_control_abbr[] = {
301 { 1, "RTT"},
302 { 2, "ACK"},
303 { 3, "SLS"},
304 { 4, "SET"},
305 { 5, "REL"},
306 { 6, "DEL"},
307 { 0, NULL},
310 /* Used in Packet Details pane */
311 static const value_string s5066dts_eow_hftrp_frame_control[] = {
312 { 1, "RTT - Right-to-transmit Token"},
313 { 2, "ACK - Acknowledgment Token"},
314 { 3, "SLS - Solicit Successor Token"},
315 { 4, "SET - Set Successor Token"},
316 { 5, "REL - Relayed Token"},
317 { 6, "DEL - Delete Token"},
318 { 0, NULL},
321 static const value_string s5066dts_alm_reason[] = {
322 { 0, "No reason"},
323 { 1, "Tx and Rx parameters must be the same"},
324 { 2, "Not possible to change modem data rate"},
325 { 3, "Not possible to change modem interleaving"},
326 { 4, "Not possible to change modem data rate or interleaving"},
327 { 5, "Not consistent with local conditions"},
328 { 6, "Not possible to change frequency"},
329 { 0, NULL},
332 /* Register functions' forward references */
333 void proto_reg_handoff_s5066dts(void);
335 /* { 1, "DRC_REQUEST"}, */
336 static void dissect_s5066dts_eow_drc_request(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
338 proto_tree_add_item(tree, hf_s5066dts_eow_drc_request_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
339 proto_tree_add_item(tree, hf_s5066dts_eow_drc_request_interleaving, tvb, offset, 1, ENC_BIG_ENDIAN);
340 proto_tree_add_item(tree, hf_s5066dts_eow_drc_request_others, tvb, offset, 1, ENC_BIG_ENDIAN);
343 /* { 2, "DRC_RESPONSE"}, */
344 static void dissect_s5066dts_eow_drc_response(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
346 proto_tree_add_item(tree, hf_s5066dts_eow_drc_response_response, tvb, offset, 1, ENC_BIG_ENDIAN);
347 proto_tree_add_item(tree, hf_s5066dts_eow_drc_response_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
350 /* { 3, "UNRECOGNIZED_TYPE"}, */
351 static void dissect_s5066dts_eow_unrec_type(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
353 proto_tree_add_item(tree, hf_s5066dts_eow_unrec_type_response, tvb, offset, 1, ENC_BIG_ENDIAN);
354 proto_tree_add_item(tree, hf_s5066dts_eow_unrec_type_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
357 /* { 4, "CAPABILITY"}, */
358 static void dissect_s5066dts_eow_capability(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
360 proto_tree_add_item(tree, hf_s5066dts_eow_capability_adaptive, tvb, offset, 1, ENC_BIG_ENDIAN);
361 proto_tree_add_item(tree, hf_s5066dts_eow_capability_stanag_4529, tvb, offset, 1, ENC_BIG_ENDIAN);
362 proto_tree_add_item(tree, hf_s5066dts_eow_capability_mil_std_188_110a, tvb, offset, 1, ENC_BIG_ENDIAN);
363 proto_tree_add_item(tree, hf_s5066dts_eow_capability_extended, tvb, offset, 1, ENC_BIG_ENDIAN);
364 proto_tree_add_item(tree, hf_s5066dts_eow_capability_full_duplex, tvb, offset, 1, ENC_BIG_ENDIAN);
365 proto_tree_add_item(tree, hf_s5066dts_eow_capability_split_frequency, tvb, offset, 1, ENC_BIG_ENDIAN);
366 proto_tree_add_item(tree, hf_s5066dts_eow_capability_non_arcs_ale, tvb, offset, 1, ENC_BIG_ENDIAN);
367 proto_tree_add_item(tree, hf_s5066dts_eow_capability_arcs, tvb, offset, 1, ENC_BIG_ENDIAN);
370 /* { 5, "ALM_REQUEST"}, */
371 static void dissect_s5066dts_eow_alm_request(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
373 proto_tree_add_item(tree, hf_s5066dts_eow_alm_request_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
374 proto_tree_add_item(tree, hf_s5066dts_eow_alm_request_interleaving, tvb, offset, 1, ENC_BIG_ENDIAN);
375 proto_tree_add_item(tree, hf_s5066dts_eow_alm_request_others, tvb, offset, 1, ENC_BIG_ENDIAN);
378 /* { 6, "ALM_RESPONSE"}, */
379 static void dissect_s5066dts_eow_alm_response(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
381 proto_tree_add_item(tree, hf_s5066dts_eow_alm_response_response, tvb, offset, 1, ENC_BIG_ENDIAN);
382 proto_tree_add_item(tree, hf_s5066dts_eow_alm_response_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
385 /* { 7, "HDR_DRC_REQUEST"}, */
386 static void dissect_s5066dts_eow_hdr_drc_request(tvbuff_t *tvb, packet_info * pinfo, unsigned offset,
387 proto_tree *tree, unsigned pdu_type)
390 if (pdu_type != S5066_DPDU_MANAGEMENT)
392 expert_add_info(pinfo, tree, &ei_s5066dts_eow_hdr_drc_request_invalid);
393 return;
396 proto_tree_add_item(tree, hf_s5066dts_eow_hdr_drc_request_waveform, tvb, offset, 1, ENC_BIG_ENDIAN);
397 proto_tree_add_item(tree, hf_s5066dts_eow_hdr_drc_request_num_channels, tvb, offset, 1, ENC_BIG_ENDIAN);
401 /* {15, "HFTRP FRAME CONTROL"}, */
402 static void dissect_s5066dts_eow_hftrp(tvbuff_t *tvb, packet_info * pinfo, unsigned offset,
403 proto_tree *tree, unsigned pdu_type)
405 if (pdu_type != S5066_DPDU_MANAGEMENT)
407 expert_add_info(pinfo, tree, &ei_s5066dts_eow_hftrp_invalid);
408 return;
411 proto_tree_add_item(tree, hf_s5066dts_eow_hftrp_hftrp_token, tvb, offset, 1, ENC_BIG_ENDIAN);
415 * Dissect EOW type according to C.5 EOW and Management Message Types
417 static unsigned dissect_s5066dts_eow(tvbuff_t *tvb, packet_info * pinfo, unsigned offset, proto_tree *tree,
418 unsigned pdu_type)
420 proto_tree *eow_tree;
421 unsigned eow_type;
423 eow_type = tvb_get_uint8(tvb, offset) & 0x0F;
424 eow_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_s5066dts_eow, NULL, "EOW Field");
425 proto_tree_add_item(eow_tree, hf_s5066dts_eow_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
427 switch (eow_type)
429 case S5066_EOW_RESERVED:
430 proto_tree_add_item(eow_tree, hf_s5066dts_eow_data, tvb, offset, 1, ENC_BIG_ENDIAN); break;
431 case S5066_EOW_DRC_REQUEST:
432 dissect_s5066dts_eow_drc_request(tvb, offset, eow_tree); break;
433 case S5066_EOW_DRC_RESPONSE:
434 dissect_s5066dts_eow_drc_response(tvb, offset, eow_tree); break;
435 case S5066_EOW_UNRECOGNIZED_TYPE:
436 dissect_s5066dts_eow_unrec_type(tvb, offset, eow_tree); break;
437 case S5066_EOW_CAPABILITY:
438 dissect_s5066dts_eow_capability(tvb, offset, eow_tree); break;
439 case S5066_EOW_ALM_REQUEST:
440 dissect_s5066dts_eow_alm_request(tvb, offset, eow_tree); break;
441 case S5066_EOW_ALM_RESPONSE:
442 dissect_s5066dts_eow_alm_response(tvb, offset, eow_tree); break;
443 case S5066_EOW_HDR_DRC_REQUEST:
444 dissect_s5066dts_eow_hdr_drc_request(tvb, pinfo, offset, eow_tree, pdu_type); break;
445 case S5066_EOW_HFTRP_TOKEN:
446 dissect_s5066dts_eow_hftrp(tvb, pinfo, offset, eow_tree, pdu_type); break;
448 return ++offset;
451 static void
452 s5066dts_address_format( char *result, uint32_t address_value )
454 snprintf( result, ITEM_LABEL_LENGTH, "%d.%d.%d.%d",
455 address_value >> 24,
456 (address_value >> 16) & 0xFF,
457 (address_value >> 8) & 0xFF,
458 address_value & 0xFF);
461 static unsigned dissect_s5066dts_address(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
462 unsigned addr_size)
464 uint32_t source_address = 0, destination_address = 0;
465 proto_tree *address_tree;
466 unsigned int i;
468 for ( i = 0; i < addr_size; i++)
470 destination_address = (destination_address << 4) | ((!(i % 2)
471 ? (tvb_get_uint8(tvb, offset + i / 2) >> 4)
472 : (tvb_get_uint8(tvb, offset + i / 2))) & 0x0F);
473 source_address = (source_address << 4) | ((!((i + addr_size) % 2)
474 ? (tvb_get_uint8(tvb, offset + (i + addr_size) / 2) >> 4)
475 : (tvb_get_uint8(tvb, offset + (i + addr_size) / 2))) & 0x0F);
478 address_tree = proto_tree_add_subtree(tree, tvb, offset, addr_size, ett_s5066dts_address, NULL, "Destination & Source Addresses");
480 proto_tree_add_uint(address_tree, hf_s5066dts_dest_addr, tvb, offset, addr_size - addr_size / 2, destination_address);
481 proto_tree_add_uint(address_tree, hf_s5066dts_src_addr, tvb, offset + addr_size / 2, addr_size - addr_size / 2, source_address);
483 col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d.%d.%d.%d",
484 source_address >> 24,
485 (source_address >> 16) & 0xFF,
486 (source_address >> 8) & 0xFF,
487 source_address & 0xFF);
489 col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d.%d.%d.%d",
490 destination_address >> 24,
491 (destination_address >> 16) & 0xFF,
492 (destination_address >> 8) & 0xFF,
493 destination_address & 0xFF);
495 offset += addr_size;
496 return offset;
499 static unsigned dissect_s5066dts_header_crc(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
500 unsigned address_size, unsigned header_size)
502 uint16_t header_crc;
503 proto_item *ti;
505 header_crc = crc16_0x9949_tvb_offset_seed(tvb, S5066_DPDU_SYNC_SEQUENCE_SIZE,
506 header_size + address_size - S5066_DPDU_SYNC_SEQUENCE_SIZE, 0);
508 ti = proto_tree_add_item(tree, hf_s5066dts_header_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
509 if (header_crc == tvb_get_letohs(tvb, offset))
510 proto_item_append_text(ti, " (Correct)");
511 else
512 proto_item_append_text(ti, " (Incorrect, should be %x)", header_crc);
514 offset += 2;
515 return offset;
518 static unsigned dissect_s5066dts_cpdu_crc(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
519 unsigned address_size, unsigned header_size, unsigned segmented_cpdu_size)
521 uint32_t cpdu_crc;
522 proto_item *ti;
524 cpdu_crc = crc32_0x0AA725CF_tvb_offset_seed(tvb, header_size + address_size + S5066_DPDU_SYNC_SEQUENCE_SIZE,
525 segmented_cpdu_size, 0);
527 ti = proto_tree_add_item(tree, hf_s5066dts_cpdu_crc, tvb, offset, 4, ENC_BIG_ENDIAN);
528 if (cpdu_crc == tvb_get_letohl(tvb, offset))
529 proto_item_append_text(ti, " (Correct)");
530 else
531 proto_item_append_text(ti, " (Incorrect, should be %x)", cpdu_crc);
533 offset +=4;
534 return offset;
537 /* { 0, "DATA_ONLY"}, */
538 static unsigned dissect_s5066dts_data_only(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
540 proto_tree_add_item(tree, hf_s5066dts_data_only_cpdu_start, tvb, offset, 1, ENC_BIG_ENDIAN);
541 proto_tree_add_item(tree, hf_s5066dts_data_only_cpdu_end, tvb, offset, 1, ENC_BIG_ENDIAN);
542 proto_tree_add_item(tree, hf_s5066dts_data_only_deliver_in_order, tvb, offset, 1, ENC_BIG_ENDIAN);
543 proto_tree_add_item(tree, hf_s5066dts_data_only_drop_cpdu, tvb, offset, 1, ENC_BIG_ENDIAN);
544 proto_tree_add_item(tree, hf_s5066dts_data_only_tx_win_uwe, tvb, offset, 1, ENC_BIG_ENDIAN);
545 proto_tree_add_item(tree, hf_s5066dts_data_only_tx_win_lwe, tvb, offset, 1, ENC_BIG_ENDIAN);
546 proto_tree_add_item(tree, hf_s5066dts_data_only_segmented_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
547 proto_tree_add_item(tree, hf_s5066dts_data_only_transmit_sequence_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
549 return offset;
552 /* { 1, "ACK_ONLY"}, */
553 static unsigned dissect_s5066dts_ack_only(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
554 unsigned header_size)
556 unsigned ack_size;
557 ack_size = header_size - 7;
559 proto_tree_add_item(tree, hf_s5066dts_ack_only_rx_lwe, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
560 if (ack_size > 0){
561 proto_tree_add_item(tree, hf_s5066dts_ack_only_acks, tvb, offset, ack_size, ENC_NA); offset += ack_size;
564 return offset;
567 /* { 2, "DATA_ACK"}, */
568 static unsigned dissect_s5066dts_data_ack(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
569 unsigned header_size)
571 unsigned ack_size;
572 ack_size = header_size - 10;
574 proto_tree_add_item(tree, hf_s5066dts_data_ack_cpdu_start, tvb, offset, 1, ENC_BIG_ENDIAN);
575 proto_tree_add_item(tree, hf_s5066dts_data_ack_cpdu_end, tvb, offset, 1, ENC_BIG_ENDIAN);
576 proto_tree_add_item(tree, hf_s5066dts_data_ack_deliver_in_order, tvb, offset, 1, ENC_BIG_ENDIAN);
577 proto_tree_add_item(tree, hf_s5066dts_data_ack_drop_cpdu, tvb, offset, 1, ENC_BIG_ENDIAN);
578 proto_tree_add_item(tree, hf_s5066dts_data_ack_tx_win_uwe, tvb, offset, 1, ENC_BIG_ENDIAN);
579 proto_tree_add_item(tree, hf_s5066dts_data_ack_tx_win_lwe, tvb, offset, 1, ENC_BIG_ENDIAN);
580 proto_tree_add_item(tree, hf_s5066dts_data_ack_segmented_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
581 proto_tree_add_item(tree, hf_s5066dts_data_ack_transmit_sequence_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
582 proto_tree_add_item(tree, hf_s5066dts_data_ack_rx_lwe, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
583 if (ack_size > 0){
584 proto_tree_add_item(tree, hf_s5066dts_data_ack_acks, tvb, offset, ack_size, ENC_NA); offset += ack_size;
587 return offset;
590 /* { 3, "RESET_WIN_RESYNC"}, */
591 static unsigned dissect_s5066dts_reset_win_resync(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
593 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
594 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_full_reset_command, tvb, offset, 1, ENC_BIG_ENDIAN);
595 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_reset_tx_win_rqst, tvb, offset, 1, ENC_BIG_ENDIAN);
596 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_reset_rx_win_cmnd, tvb, offset, 1, ENC_BIG_ENDIAN);
597 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_reset_ack, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
598 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_new_rx_lwe, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
599 proto_tree_add_item(tree, hf_s5066dts_reset_win_resync_reset_frame_id_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
601 return offset;
604 /* { 4, "EXP_DATA_ONLY"}, */
605 static unsigned dissect_s5066dts_exp_data_only(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
607 proto_tree_add_item(tree, hf_s5066dts_exp_data_only_cpdu_start, tvb, offset, 1, ENC_BIG_ENDIAN);
608 proto_tree_add_item(tree, hf_s5066dts_exp_data_only_cpdu_end, tvb, offset, 1, ENC_BIG_ENDIAN);
609 proto_tree_add_item(tree, hf_s5066dts_exp_data_only_cpdu_id, tvb, offset, 1, ENC_BIG_ENDIAN);
610 proto_tree_add_item(tree, hf_s5066dts_exp_data_only_segmented_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
611 proto_tree_add_item(tree, hf_s5066dts_exp_data_only_transmit_sequence_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
613 return offset;
616 /* { 5, "EXP_ACK_ONLY"}, */
617 static unsigned dissect_s5066dts_exp_ack_only(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
618 unsigned header_size)
620 unsigned ack_size;
621 ack_size = header_size - 7;
623 proto_tree_add_item(tree, hf_s5066dts_exp_ack_only_rx_lwe, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
624 if (ack_size > 0)
625 proto_tree_add_item(tree, hf_s5066dts_exp_ack_only_acks, tvb, offset, ack_size, ENC_NA);
626 offset += ack_size;
628 return offset;
631 /* { 6, "MANAGEMENT"}, */
632 static unsigned dissect_s5066dts_management(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned header_size)
634 uint8_t eow_content;
635 proto_tree *hftrp_token_tree = NULL;
636 unsigned eow_type;
637 unsigned extended_message_size;
639 eow_type = tvb_get_uint8(tvb, offset) & 0x0F;
640 eow_content = tvb_get_uint8(tvb, S5066_DPDU_EOW_CONTENT_INDEX);
641 extended_message_size = header_size - 8;
643 proto_tree_add_item(tree, hf_s5066dts_management_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
644 proto_tree_add_item(tree, hf_s5066dts_management_extended_message_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
645 proto_tree_add_item(tree, hf_s5066dts_management_message, tvb, offset, 1, ENC_BIG_ENDIAN);
646 proto_tree_add_item(tree, hf_s5066dts_management_ack, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
647 proto_tree_add_item(tree, hf_s5066dts_management_management_frame_id, tvb, offset, 1, ENC_BIG_ENDIAN);
648 offset++;
650 if (eow_type == S5066_EOW_HDR_DRC_REQUEST)
652 proto_tree_add_item(tree, hf_s5066dts_eow_hdr_drc_request_data_rate, tvb, offset, 4, ENC_BIG_ENDIAN);
653 offset += 4;
655 proto_tree_add_item(tree, hf_s5066dts_eow_hdr_drc_request_interleaver_length, tvb, offset, 2, ENC_BIG_ENDIAN);
656 offset += 2;
658 else if (extended_message_size > 0)
660 /* If eow type is 15 then parse HFTRP token details */
661 if (eow_type == S5066_EOW_HFTRP_TOKEN)
663 /* Add a new subtree for HFTRP token details */
664 hftrp_token_tree = proto_tree_add_subtree_format(tree, tvb, offset, extended_message_size,
665 ett_s5066dts_hftrp_token, NULL, "HFTRP Token (%s)",
666 val_to_str_const(eow_content, s5066dts_eow_hftrp_frame_control, "UNKNOWN_HFTRP_TOKEN"));
667 proto_tree_add_item(hftrp_token_tree,
668 hf_s5066dts_management_extended_message_hftrp_payload_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
669 proto_tree_add_item(hftrp_token_tree,
670 hf_s5066dts_management_extended_message_hftrp_ra, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
671 proto_tree_add_item(hftrp_token_tree,
672 hf_s5066dts_management_extended_message_hftrp_seq_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
673 proto_tree_add_item(hftrp_token_tree,
674 hf_s5066dts_management_extended_message_hftrp_gen_seq_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
675 proto_tree_add_item(hftrp_token_tree,
676 hf_s5066dts_management_extended_message_hftrp_new_successor_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
677 proto_tree_add_item(hftrp_token_tree,
678 hf_s5066dts_management_extended_message_hftrp_number_of_nodes, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
680 /* otherwise just display it as a byte stream */
681 else
683 proto_tree_add_item(tree, hf_s5066dts_management_extended_message, tvb, offset, extended_message_size, ENC_NA);
684 offset += extended_message_size;
688 return offset;
691 /* { 7, "NON_ARQ_DATA"}, */
692 static unsigned dissect_s5066dts_non_arq_data(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
694 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_cpdu_id_1, tvb, offset, 1, ENC_BIG_ENDIAN);
695 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_deliver_in_order, tvb, offset, 1, ENC_BIG_ENDIAN);
696 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_group_address, tvb, offset, 1, ENC_BIG_ENDIAN);
697 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_segmented_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
698 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_cpdu_id_2, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
699 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
700 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_cpdu_segment_offset, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
701 proto_tree_add_item(tree, hf_s5066dts_non_arq_data_cpdu_reception_window, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
703 return offset;
706 /* { 8, "EXP_NON_ARQ_DATA"}, */
707 static unsigned dissect_s5066dts_exp_non_arq_data(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
709 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_cpdu_id_1, tvb, offset, 1, ENC_BIG_ENDIAN);
710 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_deliver_in_order, tvb, offset, 1, ENC_BIG_ENDIAN);
711 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_group_address, tvb, offset, 1, ENC_BIG_ENDIAN);
712 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_segmented_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
713 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_cpdu_id_2, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
714 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_cpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
715 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_cpdu_segment_offset, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
716 proto_tree_add_item(tree, hf_s5066dts_exp_non_arq_data_cpdu_reception_window, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
718 return offset;
721 /* {15, "WARNING"}, */
722 static unsigned dissect_s5066dts_warning(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
724 proto_tree_add_item(tree, hf_s5066dts_warning_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
725 proto_tree_add_item(tree, hf_s5066dts_warning_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
727 return offset;
730 static unsigned calculate_s5066dts_dpdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
731 int offset _U_, void *data _U_)
733 unsigned pdu_type;
734 unsigned address_size;
735 unsigned header_size;
736 unsigned pdu_size;
737 unsigned segmented_cpdu_size;
739 /* XXX: why is the offset not used to get this value? */
740 if (tvb_get_uint8(tvb, 0) != 0x90)
741 return 1;
742 else if (tvb_get_uint8(tvb, 1) != 0xEB)
743 return 2;
745 pdu_type = (tvb_get_uint8(tvb, 2) & 0xF0) >> 4;
746 address_size = (tvb_get_uint8(tvb, S5066_DPDU_SIZE_OF_ADDRESS_INDEX) & 0xE0) >> 5;
747 header_size = tvb_get_uint8(tvb, S5066_DPDU_SIZE_OF_HEADER_INDEX) & 0x1F;
748 pdu_size = header_size + address_size + S5066_DPDU_SYNC_SEQUENCE_SIZE;
750 if (pdu_type == S5066_DPDU_DATA_ONLY || pdu_type == S5066_DPDU_DATA_ACK ||
751 pdu_type == S5066_DPDU_EXP_DATA_ONLY || pdu_type == S5066_DPDU_NON_ARQ_DATA ||
752 pdu_type == S5066_DPDU_EXP_NON_ARQ_DATA)
754 segmented_cpdu_size = tvb_get_ntohs(tvb, 6 + address_size) & 0x03FF;
755 pdu_size += segmented_cpdu_size + 4;
757 return pdu_size;
760 static int dissect_s5066dts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
762 proto_tree *s5066dts_tree = NULL, *pdu_tree = NULL;
763 proto_item *ti = NULL;
764 unsigned offset = 0;
765 unsigned pdu_type;
766 unsigned address_size;
767 unsigned header_size;
768 unsigned segmented_cpdu_size;
769 /* Add EOW (Engineering OrderWire */
770 uint8_t eow_type;
771 uint8_t eow_content;
773 if (tvb_get_uint8(tvb, 0) != 0x90 || tvb_get_uint8(tvb, 1) != 0xEB) {
774 /* Cannot find sync pattern at dissect_s5066dts()! */
775 return 0;
778 col_set_str(pinfo->cinfo, COL_PROTOCOL, DISSECTOR_NAME);
779 pdu_type = (tvb_get_uint8(tvb, 2) & 0xF0) >> 4;
781 /* Add DPDU type and name */
782 col_add_fstr(pinfo->cinfo, COL_INFO, "DpduType=%d (%s)", pdu_type, val_to_str(pdu_type, s5066dts_dpdu_type,
783 "Unknown (0x%02x)"));
785 address_size = (tvb_get_uint8(tvb, S5066_DPDU_SIZE_OF_ADDRESS_INDEX) & 0xE0) >> 5;
786 eow_type = tvb_get_uint8(tvb, S5066_DPDU_EOW_TYPE_INDEX) & 0x0F;
787 eow_content = tvb_get_uint8(tvb, S5066_DPDU_EOW_CONTENT_INDEX);
789 switch (eow_type)
791 case S5066_EOW_RESERVED:
792 col_append_str(pinfo->cinfo, COL_INFO, " EowType=RESERVED");
793 break;
794 case S5066_EOW_DRC_REQUEST: /* Data Rate Change Request */
795 case S5066_EOW_DRC_RESPONSE: /* Data Rate Change Response */
796 case S5066_EOW_UNRECOGNIZED_TYPE: /* Unrecognized Type Error */
797 case S5066_EOW_CAPABILITY: /* Capability Advertisement */
798 case S5066_EOW_ALM_REQUEST: /* Frequency Change / ALM Request */
799 case S5066_EOW_ALM_RESPONSE: /* Frequency Change / ALM Response */
800 case S5066_EOW_HDR_DRC_REQUEST: /* High Data Rate (HDR) Change Request */
801 col_append_fstr(pinfo->cinfo, COL_INFO, " EowType=%d (%s)", eow_type,
802 val_to_str_const(eow_type, s5066dts_eow_type, "UNKNOWN_EOW_TYPE"));
803 break;
804 case 8: /* Unspecified/User Defined */
805 case 9: /* Unspecified/User Defined */
806 case 10: /* Unspecified/User Defined */
807 case 11: /* Unspecified/User Defined */
808 case 12: /* Unspecified/User Defined */
809 case 13: /* Unspecified/User Defined */
810 case 14: /* Unspecified/User Defined */
811 col_append_str(pinfo->cinfo, COL_INFO, " EowType=UNSPECIFIED");
812 break;
813 case S5066_EOW_HFTRP_TOKEN:
814 col_append_fstr(pinfo->cinfo, COL_INFO, " EowType=%d (%s:%s)", eow_type,
815 val_to_str_const(eow_type, s5066dts_eow_type, "UNKNOWN_EOW_TYPE"),
816 val_to_str_const(eow_content, s5066dts_eow_hftrp_frame_control_abbr, "UNKNOWN_HFTRP_TOKEN"));
817 break;
820 /* Append EOT (End of Transmission) */
821 col_append_fstr(pinfo->cinfo, COL_INFO, " EOT=%d", tvb_get_uint8(tvb, S5066_DPDU_EOT_INDEX));
823 /* Append DPDU-specific information */
824 switch (pdu_type)
826 case S5066_DPDU_DATA_ONLY:
827 case S5066_DPDU_EXP_DATA_ONLY:
828 col_append_fstr(pinfo->cinfo, COL_INFO, " Seq=%d", tvb_get_uint8(tvb, 8 + address_size));
829 break;
830 case S5066_DPDU_ACK_ONLY:
831 case S5066_DPDU_EXP_ACK_ONLY:
832 col_append_fstr(pinfo->cinfo, COL_INFO, " RxLWE=%d", tvb_get_uint8(tvb, 6 + address_size));
833 break;
834 case S5066_DPDU_DATA_ACK:
835 col_append_fstr(pinfo->cinfo, COL_INFO, " Seq=%d RxLWE=%d",
836 tvb_get_uint8(tvb, 8 + address_size),
837 tvb_get_uint8(tvb, 9 + address_size));
838 break;
839 case S5066_DPDU_MANAGEMENT:
840 col_append_fstr(pinfo->cinfo, COL_INFO, " FrameID=%d", tvb_get_uint8(tvb, 7 + address_size));
841 break;
844 if (tree)
846 ti = proto_tree_add_protocol_format(tree, proto_s5066dts, tvb, 0, -1, "STANAG 5066 (DTS Layer)");
847 s5066dts_tree = proto_item_add_subtree(ti, ett_s5066dts);
848 proto_tree_add_item(s5066dts_tree, hf_s5066dts_sync_word, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
849 proto_tree_add_item(s5066dts_tree, hf_s5066dts_dpdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
850 offset = dissect_s5066dts_eow(tvb, pinfo, offset, s5066dts_tree, pdu_type);
853 * Append DPDU type to the root
855 proto_item_append_text(ti, ", DPDU Type %s ", val_to_str_const(pdu_type, s5066dts_dpdu_type, "UNKNOWN_DPDU_TYPE"));
856 proto_tree_add_item(s5066dts_tree, hf_s5066dts_eot, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
857 proto_tree_add_item(s5066dts_tree, hf_s5066dts_address_size, tvb, offset, 1, ENC_BIG_ENDIAN);
858 proto_tree_add_item(s5066dts_tree, hf_s5066dts_header_size, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
859 offset = dissect_s5066dts_address(tvb, offset, s5066dts_tree, pinfo, address_size);
860 header_size = tvb_get_uint8(tvb, S5066_DPDU_SIZE_OF_HEADER_INDEX) & 0x1F;
861 pdu_tree = proto_tree_add_subtree(s5066dts_tree, tvb, offset, header_size - 6, ett_s5066dts_pdu, NULL, "D_PDU Type Specific Header");
863 switch (pdu_type)
865 case S5066_DPDU_DATA_ONLY: offset = dissect_s5066dts_data_only(tvb, offset, pdu_tree); break;
866 case S5066_DPDU_ACK_ONLY: offset = dissect_s5066dts_ack_only(tvb, offset, pdu_tree, header_size); break;
867 case S5066_DPDU_DATA_ACK: offset = dissect_s5066dts_data_ack(tvb, offset, pdu_tree, header_size); break;
868 case S5066_DPDU_RESET_WIN_RESYNC: offset = dissect_s5066dts_reset_win_resync(tvb, offset, pdu_tree); break;
869 case S5066_DPDU_EXP_DATA_ONLY: offset = dissect_s5066dts_exp_data_only(tvb, offset, pdu_tree); break;
870 case S5066_DPDU_EXP_ACK_ONLY: offset = dissect_s5066dts_exp_ack_only(tvb, offset, pdu_tree, header_size); break;
871 case S5066_DPDU_MANAGEMENT: offset = dissect_s5066dts_management(tvb, offset, pdu_tree, header_size); break;
872 case S5066_DPDU_NON_ARQ_DATA: offset = dissect_s5066dts_non_arq_data(tvb, offset, pdu_tree); break;
873 case S5066_DPDU_EXP_NON_ARQ_DATA: offset = dissect_s5066dts_exp_non_arq_data(tvb, offset, pdu_tree); break;
874 case S5066_DPDU_WARNING: offset = dissect_s5066dts_warning(tvb, offset, pdu_tree); break;
876 offset = dissect_s5066dts_header_crc(tvb, offset, s5066dts_tree, address_size, header_size);
877 if (pdu_type == S5066_DPDU_DATA_ONLY || pdu_type == S5066_DPDU_DATA_ACK
878 || pdu_type == S5066_DPDU_EXP_DATA_ONLY || pdu_type == S5066_DPDU_NON_ARQ_DATA
879 || pdu_type == S5066_DPDU_EXP_NON_ARQ_DATA)
881 segmented_cpdu_size = tvb_get_ntohs(tvb, 6 + address_size) & 0x03FF;
882 proto_tree_add_item(s5066dts_tree, hf_s5066dts_segmented_cpdu, tvb, offset, segmented_cpdu_size, ENC_NA);
883 offset += segmented_cpdu_size;
884 /*offset = */dissect_s5066dts_cpdu_crc(tvb, offset, s5066dts_tree, address_size, header_size, segmented_cpdu_size);
888 return tvb_captured_length(tvb);
891 static int dissect_s5066dts_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
893 unsigned b_length = tvb_captured_length(tvb);
895 /* Make sure there are enough bytes for a DPDU */
896 if ( b_length < S5066_DPDU_FRAME_HEADER_LEN){
897 /* "There are not enough bytes for a DPDU! */
898 return 0;
901 /* Check if the first two bytes are 0x90 and 0xEB
902 * If not then this is neither a DPDU nor an un-reassembled one
904 if ((tvb_get_uint8(tvb, 0) != 0x90) || (tvb_get_uint8(tvb, 1) != 0xEB)) {
905 /* Cannot find sync pattern at dissect_s5066dts_raw()! */
906 return 0;
908 calculate_s5066dts_dpdu_len(pinfo, tvb, 0, NULL);
909 dissect_s5066dts(tvb, pinfo, tree, NULL);
911 return b_length;
914 static int dissect_s5066dts_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
916 unsigned b_length = tvb_captured_length(tvb);
918 /* Make sure there are enough bytes for a DPDU */
919 if ( b_length < S5066_DPDU_FRAME_HEADER_LEN){
920 /* "There are not enough bytes for a DPDU! */
921 return 0;
924 /* Check if the first two bytes are 0x90 and 0xEB
925 * If not then this is neitger a DPDU nor an un-reassembled one
927 if ((tvb_get_uint8(tvb, 0) != 0x90) || (tvb_get_uint8(tvb, 1) != 0xEB)) {
928 /* Cannot find sync pattern at dissect_s5066dts_tcp()! */
929 return 0;
932 /* Drop packets with port matches other than the destination port. */
933 if (!value_is_in_range(config_s5066dts_ports, pinfo->destport)) {
934 /* Configured to dissect TCP destination port matches only, dropping.. */
935 return 0;
938 tcp_dissect_pdus(tvb, pinfo, tree, config_proto_desegment, S5066_DPDU_FRAME_HEADER_LEN, calculate_s5066dts_dpdu_len,
939 dissect_s5066dts, data);
941 return b_length;
944 static void
945 apply_s5066dts_prefs(void)
947 /* STANAG 5066 uses the port preference for some heuristics */
948 config_s5066dts_ports = prefs_get_range_value("s5066dts", "tcp.port");
951 void proto_register_s5066dts (void)
953 module_t *s5066dts_module;
954 static hf_register_info hf[] = {
955 { &hf_s5066dts_sync_word,
956 { "Sync preamble", "s5066dts.sync", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
958 { &hf_s5066dts_dpdu_type,
959 { "D_PDU type", "s5066dts.type", FT_UINT8, BASE_DEC, VALS(s5066dts_dpdu_type), 0xF0, NULL, HFILL }
961 { &hf_s5066dts_eow_type,
962 { "EOW type", "s5066dts.eow.type", FT_UINT8, BASE_DEC, VALS(s5066dts_eow_type), 0x0F, NULL, HFILL }
964 { &hf_s5066dts_eow_data,
965 { "EOW data", "s5066dts.eow.data", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
967 { &hf_s5066dts_eot,
968 { "EOT", "s5066dts.eot", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
970 { &hf_s5066dts_address_size,
971 { "Address size (1/2 bytes)", "s5066dts.address.size", FT_UINT8, BASE_DEC, NULL, 0xE0, NULL, HFILL }
973 { &hf_s5066dts_header_size,
974 { "Header size", "s5066dts.header_size", FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL }
976 { &hf_s5066dts_segmented_cpdu,
977 { "C_PDU Segment", "s5066dts.segmented_cpdu", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
979 { &hf_s5066dts_dest_addr,
980 { "Destination Address", "s5066dts.dest_addr", FT_UINT32, BASE_CUSTOM, CF_FUNC(s5066dts_address_format), 0x0, NULL, HFILL }
982 { &hf_s5066dts_src_addr,
983 { "Source Address", "s5066dts.src_addr", FT_UINT32, BASE_CUSTOM, CF_FUNC(s5066dts_address_format), 0x0, NULL, HFILL }
985 { &hf_s5066dts_header_crc,
986 { "CRC on header", "s5066dts.header_crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
988 { &hf_s5066dts_cpdu_crc,
989 { "CRC on C_PDU segment", "s5066dts.cpdu_crc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
991 /* { 1, "DRC_REQUEST"}, */
992 { &hf_s5066dts_eow_drc_request_data_rate,
993 { "Data Rate", "s5066dts.eow.drc_request.data_rate", FT_UINT8, BASE_DEC, VALS(s5066dts_eow_data_rate),
994 0xF0, NULL, HFILL }
996 { &hf_s5066dts_eow_drc_request_interleaving,
997 { "Interleaver parameter", "s5066dts.eow.drc_request.interleaving", FT_UINT8, BASE_DEC,
998 VALS(s5066dts_eow_interleaving), 0x0C, NULL, HFILL }
1000 { &hf_s5066dts_eow_drc_request_others,
1001 { "Other parameters", "s5066dts.eow.drc_request.others", FT_UINT8, BASE_DEC,
1002 VALS(s5066dts_eow_others), 0x03, NULL, HFILL }
1004 /* { 2, "DRC_RESPONSE"}, */
1005 { &hf_s5066dts_eow_drc_response_response,
1006 { "Response for DRC", "s5066dts.eow.drc_response.response", FT_UINT8, BASE_DEC,
1007 VALS(s5066dts_eow_response), 0xE0, NULL, HFILL }
1009 { &hf_s5066dts_eow_drc_response_reason,
1010 { "Reason", "s5066dts.eow.drc_response.reason", FT_UINT8, BASE_DEC,
1011 VALS(s5066dts_eow_reason), 0x1F, NULL, HFILL }
1013 /* { 3, "UNRECOGNIZED_TYPE"}, */
1014 { &hf_s5066dts_eow_unrec_type_response,
1015 { "This value should be set to 0", "s5066dts.eow.unrec_type.response", FT_UINT8, BASE_DEC,
1016 NULL, 0xE0, NULL, HFILL }
1018 { &hf_s5066dts_eow_unrec_type_reason,
1019 { "Reason", "s5066dts.eow.unrec_type.reason", FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL }
1021 /* { 4, "CAPABILITY"}, */
1022 { &hf_s5066dts_eow_capability_adaptive,
1023 { "Adaptive modem parameters capable", "s5066dts.eow.capability.adaptive", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
1025 { &hf_s5066dts_eow_capability_stanag_4529,
1026 { "STANAG 4529 available", "s5066dts.eow.capability.stanag_4529", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
1028 { &hf_s5066dts_eow_capability_mil_std_188_110a,
1029 { "MIL-STD-188-110A available", "s5066dts.eow.capability.mil_std_188_110a", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }
1031 { &hf_s5066dts_eow_capability_extended,
1032 { "Extended data rate available", "s5066dts.eow.capability.extended", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }
1034 { &hf_s5066dts_eow_capability_full_duplex,
1035 { "Full duplex supported", "s5066dts.eow.capability.full_duplex", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1037 { &hf_s5066dts_eow_capability_split_frequency,
1038 { "Split frequency supported", "s5066dts.eow.capability.split_frequency", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1040 { &hf_s5066dts_eow_capability_non_arcs_ale,
1041 { "Non-ARCS ALE capable", "s5066dts.eow.capability.non_arcs_ale", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }
1043 { &hf_s5066dts_eow_capability_arcs,
1044 { "ARCS capable", "s5066dts.eow.capability.arcs", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
1046 /* { 5, "ALM_REQUEST"}, */
1047 { &hf_s5066dts_eow_alm_request_data_rate,
1048 { "Data Rate", "s5066dts.eow.alm_request.data_rate", FT_UINT8, BASE_DEC,
1049 VALS(s5066dts_eow_data_rate), 0xF0, NULL, HFILL }
1051 { &hf_s5066dts_eow_alm_request_interleaving,
1052 { "Interleaver parameter", "s5066dts.eow.alm_request.interleaving", FT_UINT8, BASE_DEC,
1053 VALS(s5066dts_eow_interleaving), 0x0C, NULL, HFILL }
1055 { &hf_s5066dts_eow_alm_request_others,
1056 { "Other parameters", "s5066dts.eow.alm_request.others", FT_UINT8, BASE_DEC,
1057 VALS(s5066dts_eow_others), 0x03, NULL, HFILL }
1059 /* { 6, "ALM_RESPONSE"}, */
1060 { &hf_s5066dts_eow_alm_response_response,
1061 { "Response for DRC", "s5066dts.eow.alm_response.response", FT_UINT8, BASE_DEC,
1062 VALS(s5066dts_eow_response), 0xE0, NULL, HFILL }
1064 { &hf_s5066dts_eow_alm_response_reason,
1065 { "Reason", "s5066dts.eow.alm_response.reason", FT_UINT8, BASE_DEC, VALS(s5066dts_alm_reason), 0x1F, NULL, HFILL }
1067 /* { 7, "HDR_DRC_REQUEST"}, */
1068 { &hf_s5066dts_eow_hdr_drc_request_waveform,
1069 { "Modem waveform", "s5066dts.eow.hdr_drc_request.waveform", FT_UINT8, BASE_DEC,
1070 VALS(s5066dts_eow_waveform), 0xF8, NULL, HFILL }
1072 { &hf_s5066dts_eow_hdr_drc_request_num_channels,
1073 { "Number of channels", "s5066dts.eow.hdr_drc_request.num_channels", FT_UINT8, BASE_DEC, NULL, 0x07, NULL, HFILL }
1075 { &hf_s5066dts_eow_hdr_drc_request_data_rate,
1076 { "Requested data rate for each channel", "s5066dts.eow.hdr_drc_request.data_rate",
1077 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1079 { &hf_s5066dts_eow_hdr_drc_request_interleaver_length,
1080 { "Interleaver length for each channel", "s5066dts.eow.hdr_drc_request.interleaver_length",
1081 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1083 /* { 15, "HFTRP FRAME CONTROL"}, */
1084 { &hf_s5066dts_eow_hftrp_hftrp_token,
1085 { "HFTRP Token Type", "s5066dts.eow.hftrp.token_type", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }
1087 /* { 0, "DATA_ONLY"}, */
1088 { &hf_s5066dts_data_only_cpdu_start,
1089 { "C_PDU Start", "s5066dts.data_only.cpdu_start", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
1091 { &hf_s5066dts_data_only_cpdu_end,
1092 { "C_PDU End", "s5066dts.data_only.cpdu_end", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
1094 { &hf_s5066dts_data_only_deliver_in_order,
1095 { "C_PDU Deliver-in-Order", "s5066dts.data_only.deliver_in_order", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }
1097 { &hf_s5066dts_data_only_drop_cpdu,
1098 { "Drop C_PDU", "s5066dts.data_only.drop_cpdu", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }
1100 { &hf_s5066dts_data_only_tx_win_uwe,
1101 { "TX WIN UWE", "s5066dts.data_only.tx_win_uwe", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1103 { &hf_s5066dts_data_only_tx_win_lwe,
1104 { "TX WIN LWE", "s5066dts.data_only.tx_win_lwe", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1106 { &hf_s5066dts_data_only_segmented_cpdu_size,
1107 { "Size of segmented C_PDU", "s5066dts.data_only.segmented_cpdu_size", FT_UINT16, BASE_DEC,
1108 NULL, 0x03FF, NULL, HFILL }
1110 { &hf_s5066dts_data_only_transmit_sequence_number,
1111 { "TX Frame Sequence Number", "s5066dts.data_only.transmit_sequence_number", FT_UINT8, BASE_DEC,
1112 NULL, 0x0, NULL, HFILL }
1114 /* { 1, "ACK_ONLY"}, */
1115 { &hf_s5066dts_ack_only_rx_lwe,
1116 { "RX LWE", "s5066dts.ack_only.rx_lwe", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1118 { &hf_s5066dts_ack_only_acks,
1119 { "Selective ACK", "s5066dts.ack_only.acks", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1121 /* { 2, "DATA_ACK"}, */
1122 { &hf_s5066dts_data_ack_cpdu_start,
1123 { "C_PDU Start", "s5066dts.data_ack.cpdu_start", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
1125 { &hf_s5066dts_data_ack_cpdu_end,
1126 { "C_PDU End", "s5066dts.data_ack.cpdu_end", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
1128 { &hf_s5066dts_data_ack_deliver_in_order,
1129 { "C_PDU Deliver-in-Order", "s5066dts.data_ack.deliver_in_order", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }
1131 { &hf_s5066dts_data_ack_drop_cpdu,
1132 { "Drop C_PDU", "s5066dts.data_ack.drop_cpdu", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }
1134 { &hf_s5066dts_data_ack_tx_win_uwe,
1135 { "TX WIN UWE", "s5066dts.data_ack.tx_win_uwe", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1137 { &hf_s5066dts_data_ack_tx_win_lwe,
1138 { "TX WIN LWE", "s5066dts.data_ack.tx_win_lwe", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1140 { &hf_s5066dts_data_ack_segmented_cpdu_size,
1141 { "Size of segmented C_PDU", "s5066dts.data_ack.segmented_cpdu_size", FT_UINT16, BASE_DEC,
1142 NULL, 0x03FF, NULL, HFILL }
1144 { &hf_s5066dts_data_ack_transmit_sequence_number,
1145 { "TX frame sequence number", "s5066dts.data_ack.transmit_sequence_number", FT_UINT8, BASE_DEC,
1146 NULL, 0x0, NULL, HFILL }
1148 { &hf_s5066dts_data_ack_rx_lwe,
1149 { "RX LWE", "s5066dts.data_ack.rx_lwe", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1151 { &hf_s5066dts_data_ack_acks,
1152 { "Selective ACK", "s5066dts.data_ack.acks", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1154 /* { 3, "RESET_WIN_RESYNC"}, */
1155 { &hf_s5066dts_reset_win_resync_unused,
1156 { "Unused", "s5066dts.reset_win_resync.unused", FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }
1158 { &hf_s5066dts_reset_win_resync_full_reset_command,
1159 { "Full reset command", "s5066dts.reset_win_resync.full_reset", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1161 { &hf_s5066dts_reset_win_resync_reset_tx_win_rqst,
1162 { "Reset TX-WIN request", "s5066dts.reset_win_resync.reset_tx_win", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1164 { &hf_s5066dts_reset_win_resync_reset_rx_win_cmnd,
1165 { "Reset RX-WIN command", "s5066dts.reset_win_resync.reset_rx_win", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }
1167 { &hf_s5066dts_reset_win_resync_reset_ack,
1168 { "Reset acknowledgment", "s5066dts.reset_win_resync.reset_ack", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
1170 { &hf_s5066dts_reset_win_resync_new_rx_lwe,
1171 { "New receiver ARQ RX-LWE", "s5066dts.reset_win_resync.new_rx_lwe", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1173 { &hf_s5066dts_reset_win_resync_reset_frame_id_number,
1174 { "Reset frame ID number", "s5066dts.reset_win_resync.reset_frame_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1176 /* { 4, "EXP_DATA_ONLY"}, */
1177 { &hf_s5066dts_exp_data_only_cpdu_start,
1178 { "C_PDU Start", "s5066dts.exp_data_only.cpdu_start", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
1180 { &hf_s5066dts_exp_data_only_cpdu_end,
1181 { "C_PDU End", "s5066dts.exp_data_only.cpdu_end", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
1183 { &hf_s5066dts_exp_data_only_cpdu_id,
1184 { "Segmented C_PDU ID", "s5066dts.exp_data_only.cpdu_id", FT_UINT8, BASE_DEC, NULL, 0x3C, NULL, HFILL }
1186 { &hf_s5066dts_exp_data_only_segmented_cpdu_size,
1187 { "Size of segmented C_PDU", "s5066dts.exp_data_only.segmented_cpdu_size", FT_UINT16, BASE_DEC, NULL, 0x03FF, NULL, HFILL }
1189 { &hf_s5066dts_exp_data_only_transmit_sequence_number,
1190 { "TX frame sequence number", "s5066dts.exp_data_only.transmit_sequence_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1192 /* { 5, "EXP_ACK_ONLY"}, */
1193 { &hf_s5066dts_exp_ack_only_rx_lwe,
1194 { "RX LWE", "s5066dts.exp_ack_only.rx_lwe", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1196 { &hf_s5066dts_exp_ack_only_acks,
1197 { "Selective ACK", "s5066dts.exp_ack_only.acks", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1199 /* { 6, "MANAGEMENT"}, */
1200 { &hf_s5066dts_management_unused,
1201 { "Unused", "s5066dts.management.unused", FT_UINT8, BASE_HEX, NULL, 0xF8, NULL, HFILL }
1203 { &hf_s5066dts_management_extended_message_flag,
1204 { "Extended message flag", "s5066dts.management.extended_message_flag", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1206 { &hf_s5066dts_management_message,
1207 { "Valid message", "s5066dts.management.message", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }
1209 { &hf_s5066dts_management_ack,
1210 { "Acknowledgment", "s5066dts.management.ack", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
1212 { &hf_s5066dts_management_management_frame_id,
1213 { "Management frame ID number", "s5066dts.management.management_frame_id", FT_UINT8, BASE_DEC,
1214 NULL, 0x0, NULL, HFILL }
1216 { &hf_s5066dts_management_extended_message,
1217 { "Extended management message", "s5066dts.management.extended_message", FT_BYTES, BASE_NONE,
1218 NULL, 0x0, NULL, HFILL }
1220 { &hf_s5066dts_management_extended_message_hftrp_payload_size,
1221 { "Payload Size", "s5066dts.management.extended_message.reserved", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1223 { &hf_s5066dts_management_extended_message_hftrp_ra,
1224 { "Ring Address", "s5066dts.management.extended_message.ring_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1226 { &hf_s5066dts_management_extended_message_hftrp_seq_id,
1227 { "Sequence ID", "s5066dts.management.extended_message.sequence_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1229 { &hf_s5066dts_management_extended_message_hftrp_gen_seq_id,
1230 { "Generation Sequence ID", "s5066dts.management.extended_message.generation_sequence_id",
1231 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1233 { &hf_s5066dts_management_extended_message_hftrp_new_successor_id,
1234 { "New Successor ID", "s5066dts.management.extended_message.new_successor_id", FT_UINT32, BASE_DEC,
1235 NULL, 0x0, NULL, HFILL }
1237 { &hf_s5066dts_management_extended_message_hftrp_number_of_nodes,
1238 { "Number of Nodes", "s5066dts.management.extended_message.number_of_nodes", FT_UINT16, BASE_DEC,
1239 NULL, 0x0, NULL, HFILL }
1241 /* { 7, "NON_ARQ_DATA"}, */
1242 { &hf_s5066dts_non_arq_data_cpdu_id_1,
1243 { "C_PDU ID number (field 1)", "s5066dts.non_arq_data.cpdu_id_1", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1245 { &hf_s5066dts_non_arq_data_deliver_in_order,
1246 { "C_PDU Deliver-in-Order", "s5066dts.non_arq_data.deliver_in_order", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1248 { &hf_s5066dts_non_arq_data_group_address,
1249 { "Group Address", "s5066dts.non_arq_data.group_address", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1251 { &hf_s5066dts_non_arq_data_cpdu_id_2,
1252 { "C_PDU ID number (field 2)", "s5066dts.non_arq_data.cpdu_id_2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1254 { &hf_s5066dts_non_arq_data_cpdu_size,
1255 { "C_PDU size", "s5066dts.non_arq_data.cpdu_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1257 { &hf_s5066dts_non_arq_data_cpdu_segment_offset,
1258 { "Offset of segmented C_PDU", "s5066dts.non_arq_data.cpdu_segment_offset", FT_UINT16, BASE_DEC,
1259 NULL, 0x0, NULL, HFILL }
1261 { &hf_s5066dts_non_arq_data_cpdu_reception_window,
1262 { "C_PDU reception window", "s5066dts.non_arq_data.cpdu_reception_window", FT_UINT16, BASE_DEC,
1263 NULL, 0x0, NULL, HFILL }
1265 { &hf_s5066dts_non_arq_data_segmented_cpdu_size,
1266 { "Size of segmented C_PDU", "s5066dts.non_arq_data.segmented_cpdu_size", FT_UINT16, BASE_DEC,
1267 NULL, 0x03FF, NULL, HFILL }
1269 /* { 8, "EXP_NON_ARQ_DATA"}, */
1270 { &hf_s5066dts_exp_non_arq_data_cpdu_id_1,
1271 { "C_PDU ID number (field 1)", "s5066dts.exp_non_arq_data.cpdu_id_1", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1273 { &hf_s5066dts_exp_non_arq_data_deliver_in_order,
1274 { "C_PDU Deliver-in-Order", "s5066dts.exp_non_arq_data.deliver_in_order", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
1276 { &hf_s5066dts_exp_non_arq_data_group_address,
1277 { "Group Address", "s5066dts.exp_non_arq_data.group_address", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
1279 { &hf_s5066dts_exp_non_arq_data_cpdu_id_2,
1280 { "C_PDU ID number (field 2)", "s5066dts.exp_non_arq_data.cpdu_id_2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1282 { &hf_s5066dts_exp_non_arq_data_cpdu_size,
1283 { "C_PDU size", "s5066dts.exp_non_arq_data.cpdu_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1285 { &hf_s5066dts_exp_non_arq_data_cpdu_segment_offset,
1286 { "Offset of segmented C_PDU", "s5066dts.exp_non_arq_data.cpdu_segment_offset", FT_UINT16, BASE_DEC,
1287 NULL, 0x0, NULL, HFILL }
1289 { &hf_s5066dts_exp_non_arq_data_cpdu_reception_window,
1290 { "C_PDU reception window", "s5066dts.exp_non_arq_data.cpdu_reception_window", FT_UINT16, BASE_DEC,
1291 NULL, 0x0, NULL, HFILL }
1293 { &hf_s5066dts_exp_non_arq_data_segmented_cpdu_size,
1294 { "Size of segmented C_PDU", "s5066dts.exp_non_arq_data.segmented_cpdu_size", FT_UINT16, BASE_DEC,
1295 NULL, 0x03FF, NULL, HFILL }
1297 /* {15, "WARNING"}, */
1298 { &hf_s5066dts_warning_frame_type,
1299 { "Received frame type", "s5066dts.warning.frame_type", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1301 { &hf_s5066dts_warning_reason,
1302 { "Reason warning sent", "s5066dts.warning.reason", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1306 static int *ett[] = {
1307 &ett_s5066dts,
1308 &ett_s5066dts_eow,
1309 &ett_s5066dts_address,
1310 &ett_s5066dts_pdu,
1311 &ett_s5066dts_hftrp_token,
1314 /* Setup protocol expert items */
1315 static ei_register_info ei[] = {
1316 { &ei_s5066dts_eow_hdr_drc_request_invalid, { "s5066dts.eow_hdr_drc_request.invalid", PI_MALFORMED, PI_ERROR,
1317 "High data rate change request can only be made in Management D_PDU", EXPFILL }},
1318 { &ei_s5066dts_eow_hftrp_invalid, { "s5066dts.eow_hftrp.invalid", PI_MALFORMED, PI_ERROR,
1319 "HFTRP tokens can only be carried with Management D_PDU", EXPFILL }},
1322 expert_module_t* expert_s5066dts;
1324 if (proto_s5066dts <= 0) /* do protocol initialization only once */
1326 proto_s5066dts = proto_register_protocol ("STANAG 5066(DTS layer)", "STANAG 5066 DTS", "s5066dts");
1327 proto_register_field_array(proto_s5066dts, hf, array_length(hf));
1328 proto_register_subtree_array(ett, array_length(ett));
1329 expert_s5066dts = expert_register_protocol(proto_s5066dts);
1330 expert_register_field_array(expert_s5066dts, ei, array_length(ei));
1331 s5066dts_handle = register_dissector(DISSECTOR_NAME ".raw", dissect_s5066dts_raw, proto_s5066dts);
1332 s5066dts_over_tcp_handle = register_dissector(DISSECTOR_NAME, dissect_s5066dts_tcp, proto_s5066dts);
1335 s5066dts_module = prefs_register_protocol(proto_s5066dts, apply_s5066dts_prefs);
1337 prefs_register_bool_preference(s5066dts_module, "proto_desegment",
1338 "Reassemble STANAG 5066 DPDUs spanning multiple TCP segments",
1339 "Whether the STANAG 5066 DTS Layer dissector should reassemble DPDUs spanning multiple TCP segments",
1340 &config_proto_desegment);
1343 /* Routine that will be called when s5066dts is handing off to the next dissector */
1344 void proto_reg_handoff_s5066dts(void)
1346 dissector_add_uint("wtap_encap", WTAP_ENCAP_STANAG_5066_D_PDU, s5066dts_handle);
1347 dissector_add_for_decode_as_with_preference("tcp.port", s5066dts_over_tcp_handle);
1348 apply_s5066dts_prefs();
1352 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1354 * Local variables:
1355 * c-basic-offset: 4
1356 * tab-width: 8
1357 * indent-tabs-mode: nil
1358 * End:
1360 * vi: set shiftwidth=4 tabstop=8 expandtab:
1361 * :indentSize=4:tabSize=8:noTabs=true: