2 * Routines for STANAG 5066 SIS layer packet disassembly
6 * Copyright (c) 2005 by Menno Andriesse <s5066 [AT] nc3a.nato.int>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/emem.h>
35 #include <epan/dissectors/packet-tcp.h> /* For tcp_dissect_pdus() */
37 /* Forward reference */
38 /* Register functions */
39 void proto_register_s5066(void);
40 void proto_reg_handoff_s5066(void);
42 static void dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
43 static guint get_s5066_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
44 static void dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
45 /* Service type and address dissectors */
46 static guint dissect_s5066_servicetype(tvbuff_t *tvb, guint offset, proto_tree *tree);
47 static guint dissect_s5066_address(tvbuff_t *tvb, guint offset, proto_tree *tree, gint source);
48 /* S-Primitive dissectors */
49 static guint dissect_s5066_01(tvbuff_t *tvb, guint offset, proto_tree *tree);
50 /* static guint dissect_s5066_02(tvbuff_t *tvb, guint offset, proto_tree *tree); */
51 static guint dissect_s5066_03(tvbuff_t *tvb, guint offset, proto_tree *tree);
52 static guint dissect_s5066_04(tvbuff_t *tvb, guint offset, proto_tree *tree);
53 static guint dissect_s5066_05(tvbuff_t *tvb, guint offset, proto_tree *tree);
54 static guint dissect_s5066_06(tvbuff_t *tvb, guint offset, proto_tree *tree);
55 static guint dissect_s5066_07(tvbuff_t *tvb, guint offset, proto_tree *tree);
56 static guint dissect_s5066_08(tvbuff_t *tvb, guint offset, proto_tree *tree);
57 static guint dissect_s5066_09(tvbuff_t *tvb, guint offset, proto_tree *tree);
58 static guint dissect_s5066_10(tvbuff_t *tvb, guint offset, proto_tree *tree);
59 static guint dissect_s5066_11(tvbuff_t *tvb, guint offset, proto_tree *tree);
60 static guint dissect_s5066_12(tvbuff_t *tvb, guint offset, proto_tree *tree);
61 static guint dissect_s5066_13(tvbuff_t *tvb, guint offset, proto_tree *tree);
62 static guint dissect_s5066_14(tvbuff_t *tvb, guint offset, proto_tree *tree);
63 /* static guint dissect_s5066_15(tvbuff_t *tvb, guint offset, proto_tree *tree); */
64 /* static guint dissect_s5066_16(tvbuff_t *tvb, guint offset, proto_tree *tree); */
65 /* static guint dissect_s5066_17(tvbuff_t *tvb, guint offset, proto_tree *tree); */
66 static guint dissect_s5066_18(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size);
67 static guint dissect_s5066_19(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size);
68 static guint dissect_s5066_20(tvbuff_t *tvb, guint offset, proto_tree *tree);
69 static guint dissect_s5066_21(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size);
70 static guint dissect_s5066_22(tvbuff_t *tvb, guint offset, proto_tree *tree);
71 static guint dissect_s5066_23(tvbuff_t *tvb, guint offset, proto_tree *tree);
72 static guint dissect_s5066_24(tvbuff_t *tvb, guint offset, proto_tree *tree);
73 static guint dissect_s5066_25(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size);
74 static guint dissect_s5066_26(tvbuff_t *tvb, guint offset, proto_tree *tree);
75 static guint dissect_s5066_27(tvbuff_t *tvb, guint offset, proto_tree *tree);
77 static gint proto_s5066 = -1;
78 static dissector_handle_t s5066_tcp_handle;
79 static dissector_handle_t data_handle;
81 /* Enable desegmentation of S5066 over TCP */
82 static gboolean s5066_desegment = TRUE;
83 /* Dissect old 'edition 1' of STANAG 5066 (It lacks the 'version' field.) */
84 static gboolean s5066_edition_one = FALSE;
85 /* This port is registered with IANA */
86 static gint global_s5066_port = 5066;
87 /* Size of header outside 'size' field */
88 static gint s5066_header_size = 5;
89 /* Offset of 'size' field */
90 static gint s5066_size_offset = 3;
92 /* Sync should be 0x90EB */
93 static gint hf_s5066_sync_word = -1;
94 /* Version should be 0x00 */
95 static gint hf_s5066_version = -1;
96 /* Total size of the PDU, excluding this size and previous fields */
97 /* So total size is this + 5 bytes (s5066_header_size) */
98 static gint hf_s5066_size = -1;
100 static gint hf_s5066_type = -1;
101 static const value_string s5066_pdu_type[] = {
102 { 1, "S_BIND_REQUEST"},
103 { 2, "S_UNBIND_REQUEST"},
104 { 3, "S_BIND_ACCEPTED"},
105 { 4, "S_BIND_REJECTED"},
106 { 5, "S_UNBIND_INDICATION"},
107 { 6, "S_HARD_LINK_ESTABLISH"},
108 { 7, "S_HARD_LINK_TERMINATE"},
109 { 8, "S_HARD_LINK_ESTABLISHED"},
110 { 9, "S_HARD_LINK_REJECTED"},
111 {10, "S_HARD_LINK_TERMINATED"},
112 {11, "S_HARD_LINK_INDICATION"},
113 {12, "S_HARD_LINK_ACCEPT"},
114 {13, "S_HARD_LINK_REJECT"},
115 {14, "S_SUBNET_AVAILABILITY"},
116 {15, "S_DATAFLOW_ON"},
117 {16, "S_DATAFLOW_OFF"},
118 {17, "S_KEEP_ALIVE"},
119 {18, "S_MANAGEMENT_MESSAGE_REQUEST"},
120 {19, "S_MANAGEMENT_MESSAGE_INDICATION"},
121 {20, "S_UNIDATA_REQUEST"},
122 {21, "S_UNIDATA_INDICATION"},
123 {22, "S_UNIDATA_REQUEST_CONFIRM"},
124 {23, "S_UNIDATA_REQUEST_REJECTED"},
125 {24, "S_EXPEDITED_UNIDATA_REQUEST"},
126 {25, "S_EXPEDITED_UNIDATA_INDICATION"},
127 {26, "S_EXPEDITED_UNIDATA_REQUEST_CONFIRM"},
128 {27, "S_EXPEDITED_UNIDATA_REQUEST_REJECTED"},
132 /* STANAG 5066 Address */
133 /* Size is defined in nibbles (4 bits) */
134 static gint hf_s5066_ad_size = -1;
135 /* Group flag: 0 = false, 1 = true */
136 static gint hf_s5066_ad_group = -1;
137 /* The remainder of the 4 bytes form the address */
138 static gint hf_s5066_ad_address = -1;
141 /* Transmission mode: */
142 static gint hf_s5066_st_txmode = -1;
143 static const value_string s5066_st_txmode[] = {
144 { 0, "Ignore service type field"},
146 { 2, "Non-ARQ (Broacast)"},
147 { 3, "Non-ARQ (with errors)"},
148 { 4, "Other non-ARQ types"},
149 { 5, "Other non-ARQ types"},
150 { 6, "Other non-ARQ types"},
151 { 7, "Other non-ARQ types"},
152 { 8, "Other non-ARQ types"},
153 { 9, "Other non-ARQ types"},
154 {10, "Other non-ARQ types"},
155 {11, "Other non-ARQ types"},
156 {12, "Other non-ARQ types"},
157 {13, "Other non-ARQ types"},
158 {14, "Other non-ARQ types"},
159 {15, "Other non-ARQ types"},
162 /* Delivery confirmation: */
163 static gint hf_s5066_st_delivery_confirmation = -1;
164 static const value_string s5066_st_delivery_confirmation[] = {
165 { 0, "No confirmation"},
166 { 1, "Node delivery confirmation"},
167 { 2, "Client delivery confirmation"},
168 { 3, "-- Not defined --"},
171 /* Delivery order: */
172 static gint hf_s5066_st_delivery_order = -1;
173 static const value_string s5066_st_delivery_order[] = {
174 { 0, "In-order delivery"},
175 { 1, "As-they-arrive"},
178 /* Extended field present: (Never in the current version.) */
179 static gint hf_s5066_st_extended = -1;
180 static const value_string s5066_st_extended[] = {
181 { 0, "No extended field"},
182 { 1, "Extended field follows"},
185 /* Number of retransmissions when in Non-ARQ: */
186 static gint hf_s5066_st_retries = -1;
188 /* Type 1: S_BIND_REQUEST */
189 static gint hf_s5066_01_sapid = -1;
190 static gint hf_s5066_01_rank = -1;
191 static gint hf_s5066_01_unused = -1;
193 /* Type 2: S_UNBIND_REQUEST */
194 /* --- no subfields --- */
196 /* Type 3: S_BIND_ACCEPTED */
197 static gint hf_s5066_03_sapid = -1;
198 static gint hf_s5066_03_unused = -1;
199 static gint hf_s5066_03_mtu = -1;
201 /* Type 4: S_BIND_REJECTED */
202 static gint hf_s5066_04_reason = -1;
203 static const value_string s5066_04_reason[] = {
204 { 0, "Unknown reason"},
205 { 1, "Not enough resources"},
206 { 2, "Invalid Sap ID"},
207 { 3, "Sap ID already allocated"},
208 { 4, "ARQ mode unsupportable during broadcast session"},
212 /* Type 5: S_UNBIND_INDICATION */
213 static gint hf_s5066_05_reason = -1;
214 static const value_string s5066_05_reason[] = {
215 { 0, "Unknown reason"},
216 { 1, "Connection pre-empted by higher ranking client"},
217 { 2, "Inactivity (failure to respond to 'Keep-alive')"},
218 { 3, "Too many invalid primitives"},
219 { 4, "Too many expedited data request primitives"},
220 { 5, "ARQ mode unsupportable during broadcast session"},
224 /* Hard links: hardlinktype value string array. */
225 static const value_string s5066_hard_link_type[] = {
226 { 0, "Link reservation"},
227 { 1, "Partial Bandwidth reservation"},
228 { 2, "Full Bandwidth reservation"},
229 { 3, "--- undefined ---"},
233 /* Type 6: S_HARD_LINK_ESTABLISH */
234 static gint hf_s5066_06_link_type = -1;
235 static gint hf_s5066_06_link_priority = -1;
236 static gint hf_s5066_06_sapid = -1;
238 /* Type 7: S_HARD_LINK_TERMINATE */
239 /* Only remote node address */
241 /* Type 8: S_HARD_LINK_ESTABLISHED */
242 static gint hf_s5066_08_remote_status = -1;
243 static const value_string s5066_08_remote_status[] = {
248 static gint hf_s5066_08_link_type = -1;
249 static gint hf_s5066_08_link_priority = -1;
250 static gint hf_s5066_08_sapid = -1;
252 /* Type 9: S_HARD_LINK_REJECTED */
253 static gint hf_s5066_09_reason = -1;
254 static const value_string s5066_09_reason[] = {
255 { 0, "--- undefined ---"},
256 { 1, "Remote node busy"},
257 { 2, "Higher priority link exists"},
258 { 3, "Remote node not responding"},
259 { 4, "Destination Sap ID not bound"},
260 { 5, "Requested Type-0 link exists"},
263 static gint hf_s5066_09_link_type = -1;
264 static gint hf_s5066_09_link_priority = -1;
265 static gint hf_s5066_09_sapid = -1;
267 /* Type 10: S_HARD_LINK_TERMINATED */
268 static gint hf_s5066_10_reason = -1;
269 static const value_string s5066_10_reason[] = {
270 { 0, "--- undefined ---"},
271 { 1, "Link terminated by remote node"},
272 { 2, "Higher priority link requested"},
273 { 3, "Remote node not responding"},
274 { 4, "Destination Sap ID not bound"},
275 { 5, "Physical link broken"},
278 static gint hf_s5066_10_link_type = -1;
279 static gint hf_s5066_10_link_priority = -1;
280 static gint hf_s5066_10_sapid = -1;
282 /* Type 11: S_HARD_LINK_INDICATION */
283 static gint hf_s5066_11_remote_status = -1;
284 static const value_string s5066_11_remote_status[] = {
289 static gint hf_s5066_11_link_type = -1;
290 static gint hf_s5066_11_link_priority = -1;
291 static gint hf_s5066_11_sapid = -1;
293 /* Type 12: S_HARD_LINK_ACCEPT */
294 static gint hf_s5066_12_link_type = -1;
295 static gint hf_s5066_12_link_priority = -1;
296 static gint hf_s5066_12_sapid = -1;
298 /* Type 13: S_HARD_LINK_REJECT */
299 static gint hf_s5066_13_reason = -1;
300 static const value_string s5066_13_reason[] = {
301 { 0, "--- undefined ---"},
304 static gint hf_s5066_13_link_type = -1;
305 static gint hf_s5066_13_link_priority = -1;
306 static gint hf_s5066_13_sapid = -1;
308 /* Type 14: S_SUBNET_AVAILABILITY */
309 static gint hf_s5066_14_status= -1;
310 static const value_string s5066_14_status[] = {
313 { 2, "Receive only"},
318 static gint hf_s5066_14_reason= -1;
319 static const value_string s5066_14_reason[] = {
320 { 0, "Unknown reason"},
321 { 1, "Local node in EMCON"},
322 { 2, "Higher priority link requested"},
326 /* Type 15: S_DATAFLOW_ON */
327 /* --- no subfields --- */
329 /* Type 16: S_DATAFLOW_OFF */
330 /* --- no subfields --- */
332 /* Type 17: S_KEEP_ALIVE */
333 /* --- no subfields --- */
335 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
336 static gint hf_s5066_18_type = -1;
337 static gint hf_s5066_18_body = -1;
339 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
340 static gint hf_s5066_19_type = -1;
341 static gint hf_s5066_19_body = -1;
343 /* Type 20: S_UNIDATA_REQUEST */
344 static gint hf_s5066_20_priority = -1;
345 static gint hf_s5066_20_sapid = -1;
346 static gint hf_s5066_20_ttl = -1;
347 static gint hf_s5066_20_size = -1;
349 /* Type 21: S_UNIDATA_INDICATION */
350 static gint hf_s5066_21_priority = -1;
351 static gint hf_s5066_21_dest_sapid = -1;
352 static gint hf_s5066_21_tx_mode = -1;
353 static gint hf_s5066_21_src_sapid = -1;
354 static gint hf_s5066_21_size = -1;
355 static gint hf_s5066_21_err_blocks = -1;
356 static gint hf_s5066_21_err_ptr = -1;
357 static gint hf_s5066_21_err_size = -1;
358 static gint hf_s5066_21_nrx_blocks = -1;
359 static gint hf_s5066_21_nrx_ptr = -1;
360 static gint hf_s5066_21_nrx_size = -1;
363 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
364 static gint hf_s5066_22_unused = -1;
365 static gint hf_s5066_22_sapid = -1;
366 static gint hf_s5066_22_size = -1;
367 static gint hf_s5066_22_data = -1;
369 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
370 static gint hf_s5066_23_reason = -1;
371 static const value_string s5066_23_reason[] = {
372 { 0, "Unknown reason"},
373 { 1, "Time-To-Live expired"},
374 { 2, "Destination SapID not bound"},
375 { 3, "Destination node not responding"},
376 { 4, "U_PDU larger than MTU"},
377 { 5, "Transmission Mode not specified"},
380 static gint hf_s5066_23_sapid = -1;
381 static gint hf_s5066_23_size = -1;
382 static gint hf_s5066_23_data = -1;
384 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
385 static gint hf_s5066_24_unused = -1;
386 static gint hf_s5066_24_sapid = -1;
387 static gint hf_s5066_24_ttl = -1;
388 static gint hf_s5066_24_size = -1;
390 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
391 static gint hf_s5066_25_unused = -1;
392 static gint hf_s5066_25_dest_sapid = -1;
393 static gint hf_s5066_25_tx_mode = -1;
394 static gint hf_s5066_25_src_sapid = -1;
395 static gint hf_s5066_25_size = -1;
396 static gint hf_s5066_25_err_blocks = -1;
397 static gint hf_s5066_25_err_ptr = -1;
398 static gint hf_s5066_25_err_size = -1;
399 static gint hf_s5066_25_nrx_blocks = -1;
400 static gint hf_s5066_25_nrx_ptr = -1;
401 static gint hf_s5066_25_nrx_size = -1;
403 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
404 static gint hf_s5066_26_unused = -1;
405 static gint hf_s5066_26_sapid = -1;
406 static gint hf_s5066_26_size = -1;
407 static gint hf_s5066_26_data = -1;
409 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
410 static gint hf_s5066_27_reason = -1;
411 static const value_string s5066_27_reason[] = {
412 { 0, "Unknown reason"},
413 { 1, "Time-To-Live expired"},
414 { 2, "Destination SapID not bound"},
415 { 3, "Destination node not responding"},
416 { 4, "U_PDU larger than MTU"},
417 { 5, "Transmission Mode not specified"},
420 static gint hf_s5066_27_sapid = -1;
421 static gint hf_s5066_27_size = -1;
422 static gint hf_s5066_27_data = -1;
425 static gint ett_s5066 = -1;
426 static gint ett_s5066_pdu = -1;
427 static gint ett_s5066_servicetype = -1;
428 static gint ett_s5066_address = -1;
431 proto_register_s5066(void)
433 static hf_register_info hf[] = {
434 { &hf_s5066_sync_word,
435 { "Sync preample", "s5066.sync", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
438 { "S5066 version", "s5066.version", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
441 { "S_Primitive size", "s5066.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
444 { "PDU Type", "s5066.type", FT_UINT8, BASE_DEC, VALS(s5066_pdu_type), 0x0, "", HFILL }
446 /* STANAG 5066 Address */
448 { "Address size (1/2 Bytes)", "s5066.address.size", FT_UINT8, BASE_HEX, NULL, 0xE0, "", HFILL }
450 { &hf_s5066_ad_group,
451 { "Group address", "s5066.address.group", FT_UINT8, BASE_HEX, NULL, 0x10, "", HFILL }
453 { &hf_s5066_ad_address,
454 { "Address", "s5066.address.address", FT_IPv4, BASE_NONE, NULL, 0, "", HFILL }
457 { &hf_s5066_st_txmode,
458 { "Transmission mode", "s5066.st.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
460 { &hf_s5066_st_delivery_confirmation,
461 { "Delivery confirmation", "s5066.st.confirm", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_confirmation), 0x0C, "", HFILL }
463 { &hf_s5066_st_delivery_order,
464 { "Delivery order", "s5066.st.order", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_order), 0x02, "", HFILL }
466 { &hf_s5066_st_extended,
467 { "Extended field", "s5066.st.extended", FT_UINT8, BASE_HEX, VALS(s5066_st_extended), 0x01, "", HFILL }
469 { &hf_s5066_st_retries,
470 { "Minimum number of retransmissions", "s5066.st.retries", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
472 /* PDU Type 01: S_BIND_REQUEST */
473 { &hf_s5066_01_sapid,
474 { "Sap ID", "s5066.01.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
477 { "Rank", "s5066.01.rank", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
479 { &hf_s5066_01_unused,
480 { "(Unused)", "s5066.01.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, "", HFILL }
482 /* PDU Type 02: S_UNBIND_REQUEST */
483 /* --- no subfields --- */
484 /* PDU Type 03: S_BIND_ACCEPTED */
485 { &hf_s5066_03_sapid,
486 { "Sap ID", "s5066.03.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
488 { &hf_s5066_03_unused,
489 { "(Unused)", "s5066.03.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, "", HFILL }
492 { "MTU", "s5066.03.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
494 /* PDU Type 04: S_BIND_REJECTED */
495 { &hf_s5066_04_reason,
496 { "Reason", "s5066.04.reason", FT_UINT8, BASE_DEC, VALS(s5066_04_reason), 0x0, "", HFILL }
498 /* PDU Type 05: S_UNBIND_INDICATION */
499 { &hf_s5066_05_reason,
500 { "Reason", "s5066.05.reason", FT_UINT8, BASE_DEC, VALS(s5066_05_reason), 0x0, "", HFILL }
502 /* Type 6: S_HARD_LINK_ESTABLISH */
503 { &hf_s5066_06_link_type,
504 { "Hardlink type", "s5066.06.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
506 { &hf_s5066_06_link_priority,
507 { "Priority", "s5066.06.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
509 { &hf_s5066_06_sapid,
510 { "Remote Sap ID", "s5066.06.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
512 /* Type 7: S_HARD_LINK_TERMINATE */
513 /* --- Only remote node address --- */
514 /* Type 8: S_HARD_LINK_ESTABLISHED */
515 { &hf_s5066_08_remote_status,
516 { "Remote node status", "s5066.08.status", FT_UINT8, BASE_DEC, VALS(s5066_08_remote_status), 0x0, "", HFILL }
518 { &hf_s5066_08_link_type,
519 { "Hardlink type", "s5066.08.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
521 { &hf_s5066_08_link_priority,
522 { "Priority", "s5066.08.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
524 { &hf_s5066_08_sapid,
525 { "Remote Sap ID", "s5066.08.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
527 /* Type 9: S_HARD_LINK_REJECTED */
528 { &hf_s5066_09_reason,
529 { "Reason", "s5066.09.reason", FT_UINT8, BASE_DEC, VALS(s5066_09_reason), 0x0, "", HFILL }
531 { &hf_s5066_09_link_type,
532 { "Hardlink type", "s5066.09.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
534 { &hf_s5066_09_link_priority,
535 { "Priority", "s5066.09.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
537 { &hf_s5066_09_sapid,
538 { "Remote Sap ID", "s5066.09.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
540 /* Type 10: S_HARD_LINK_TERMINATED */
541 { &hf_s5066_10_reason,
542 { "Reason", "s5066.10.reason", FT_UINT8, BASE_DEC, VALS(s5066_10_reason), 0x0, "", HFILL }
544 { &hf_s5066_10_link_type,
545 { "Hardlink type", "s5066.10.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
547 { &hf_s5066_10_link_priority,
548 { "Priority", "s5066.10.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
550 { &hf_s5066_10_sapid,
551 { "Remote Sap ID", "s5066.10.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
553 /* Type 11: S_HARD_LINK_INDICATION */
554 { &hf_s5066_11_remote_status,
555 { "Remote node status", "s5066.11.status", FT_UINT8, BASE_DEC, VALS(s5066_11_remote_status), 0x0, "", HFILL }
557 { &hf_s5066_11_link_type,
558 { "Hardlink type", "s5066.11.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
560 { &hf_s5066_11_link_priority,
561 { "Priority", "s5066.11.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
563 { &hf_s5066_11_sapid,
564 { "Remote Sap ID", "s5066.11.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
566 /* Type 12: S_HARD_LINK_ACCEPT */
567 { &hf_s5066_12_link_type,
568 { "Hardlink type", "s5066.12.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
570 { &hf_s5066_12_link_priority,
571 { "Priority", "s5066.12.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
573 { &hf_s5066_12_sapid,
574 { "Remote Sap ID", "s5066.12.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
576 /* Type 13: S_HARD_LINK_REJECT */
577 { &hf_s5066_13_reason,
578 { "Reason", "s5066.13.reason", FT_UINT8, BASE_DEC, VALS(s5066_13_reason), 0x0, "", HFILL }
580 { &hf_s5066_13_link_type,
581 { "Hardlink type", "s5066.13.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
583 { &hf_s5066_13_link_priority,
584 { "Priority", "s5066.13.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
586 { &hf_s5066_13_sapid,
587 { "Remote Sap ID", "s5066.13.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
589 /* Type 14: S_SUBNET_AVAILABILITY */
590 { &hf_s5066_14_status,
591 { "Status", "s5066.14.status", FT_UINT8, BASE_DEC, VALS(s5066_14_status), 0x0, "", HFILL }
593 { &hf_s5066_14_reason,
594 { "Reason", "s5066.14.reason", FT_UINT8, BASE_DEC, VALS(s5066_14_reason), 0x0, "", HFILL }
596 /* Type 15: S_DATAFLOW_ON */
597 /* --- no subfields --- */
598 /* Type 16: S_DATAFLOW_OFF */
599 /* --- no subfields --- */
600 /* Type 17: S_KEEP_ALIVE */
601 /* --- no subfields --- */
602 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
604 { "Message Type", "s5066.18.type", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
607 { "Message Body", "s5066.18.body", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
609 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
611 { "Message Type", "s5066.19.type", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
614 { "Message Body", "s5066.19.body", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
616 /* Type 20: S_UNIDATA_REQUEST */
617 { &hf_s5066_20_priority,
618 { "Priority", "s5066.20.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
620 { &hf_s5066_20_sapid,
621 { "Destination Sap ID", "s5066.20.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
624 { "Time-To-Live (x2 seconds)", "s5066.20.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, "", HFILL }
627 { "U_PDU Size", "s5066.20.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
629 /* Type 21: S_UNIDATA_INDICATION */
630 { &hf_s5066_21_priority,
631 { "Priority", "s5066.21.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
633 { &hf_s5066_21_dest_sapid,
634 { "Destination Sap ID", "s5066.21.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
636 { &hf_s5066_21_tx_mode,
637 { "Transmission Mode", "s5066.21.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
639 { &hf_s5066_21_src_sapid,
640 { "Source Sap ID", "s5066.21.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
643 { "U_PDU Size", "s5066.21.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
645 { &hf_s5066_21_err_blocks,
646 { "Number of errored blocks", "s5066.21.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
648 { &hf_s5066_21_err_ptr,
649 { "Pointer to error block", "s5066.21.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
651 { &hf_s5066_21_err_size,
652 { "Size of error block", "s5066.21.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
654 { &hf_s5066_21_nrx_blocks,
655 { "Number of non-received blocks", "s5066.21.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
657 { &hf_s5066_21_nrx_ptr,
658 { "Pointer to non-received block", "s5066.21.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
660 { &hf_s5066_21_nrx_size,
661 { "Size of non-received block", "s5066.21.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
663 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
664 { &hf_s5066_22_unused,
665 { "(Unused)", "s5066.22.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
667 { &hf_s5066_22_sapid,
668 { "Destination Sap ID", "s5066.22.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
671 { "U_PDU Size", "s5066.22.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
674 { "(Part of) Confirmed data", "s5066.22.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
676 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
677 { &hf_s5066_23_reason,
678 { "Reason", "s5066.23.reason", FT_UINT8, BASE_DEC, VALS(s5066_23_reason), 0xF0, "", HFILL }
680 { &hf_s5066_23_sapid,
681 { "Destination Sap ID", "s5066.23.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
684 { "U_PDU Size", "s5066.23.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
687 { "(Part of) Rejected data", "s5066.23.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
689 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
690 { &hf_s5066_24_unused,
691 { "(Unused)", "s5066.24.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
693 { &hf_s5066_24_sapid,
694 { "Destination Sap ID", "s5066.24.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
697 { "Time-To-Live (x2 seconds)", "s5066.24.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, "", HFILL }
700 { "U_PDU Size", "s5066.24.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
702 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
703 { &hf_s5066_25_unused,
704 { "(Unused)", "s5066.25.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
706 { &hf_s5066_25_dest_sapid,
707 { "Destination Sap ID", "s5066.25.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
709 { &hf_s5066_25_tx_mode,
710 { "Transmission Mode", "s5066.25.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
712 { &hf_s5066_25_src_sapid,
713 { "Source Sap ID", "s5066.25.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
716 { "U_PDU Size", "s5066.25.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
718 { &hf_s5066_25_err_blocks,
719 { "Number of errored blocks", "s5066.25.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
721 { &hf_s5066_25_err_ptr,
722 { "Pointer to error block", "s5066.25.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
724 { &hf_s5066_25_err_size,
725 { "Size of error block", "s5066.25.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
727 { &hf_s5066_25_nrx_blocks,
728 { "Number of non-received blocks", "s5066.25.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
730 { &hf_s5066_25_nrx_ptr,
731 { "Pointer to non-received block", "s5066.25.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
733 { &hf_s5066_25_nrx_size,
734 { "Size of non-received block", "s5066.25.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
736 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
737 { &hf_s5066_26_unused,
738 { "(Unused)", "s5066.26.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
740 { &hf_s5066_26_sapid,
741 { "Destination Sap ID", "s5066.26.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
744 { "U_PDU Size", "s5066.26.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
747 { "(Part of) Confirmed data", "s5066.26.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
749 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
750 { &hf_s5066_27_reason,
751 { "Reason", "s5066.27.reason", FT_UINT8, BASE_DEC, VALS(s5066_27_reason), 0xF0, "", HFILL }
753 { &hf_s5066_27_sapid,
754 { "Destination Sap ID", "s5066.27.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
757 { "U_PDU Size", "s5066.27.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
760 { "(Part of) Rejected data", "s5066.27.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
765 /* Setup protocol subtree array */
766 static gint *ett[] = {
769 &ett_s5066_servicetype,
773 module_t *s5066_module;
775 if (proto_s5066 == -1) {
776 proto_s5066 = proto_register_protocol (
777 "STANAG 5066 (SIS layer)", /* name */
778 "STANAG 5066", /* short name*/
781 proto_register_field_array(proto_s5066, hf, array_length(hf));
782 proto_register_subtree_array(ett, array_length(ett));
785 s5066_module = prefs_register_protocol(proto_s5066, proto_reg_handoff_s5066);
786 prefs_register_bool_preference(s5066_module, "desegment_pdus",
787 "Reassemble S5066 PDUs spanning multiple TCP segments",
788 "Whether the S5066 dissector should reassemble PDUs spanning multiple TCP segments."
789 " The default is to use reassembly.",
791 prefs_register_bool_preference(s5066_module, "edition_one",
792 "Dissect edition 1.0 of STANAG 5066",
793 "Whether the S5066 dissector should dissect editon 1 of the STANAG."
794 " This editon was never formally approved and is very rare. The common edition is editon 1.2.",
796 prefs_register_uint_preference(s5066_module, "tcp.port",
797 "STANAG 5066 TCP Port",
798 "Set the port for STANAG 5066. (If other than the default 5066."
799 " This number is registered with IANA.)",
800 10, &global_s5066_port);
804 proto_reg_handoff_s5066(void)
806 static gint Initialized = FALSE;
809 s5066_tcp_handle = create_dissector_handle(dissect_s5066_tcp, proto_s5066);
810 dissector_add("tcp.port", global_s5066_port, s5066_tcp_handle);
812 data_handle = find_dissector("data");
815 if (!s5066_edition_one) {
816 s5066_header_size = 5;
817 s5066_size_offset = 3;
819 s5066_header_size = 4;
820 s5066_size_offset = 2;
825 dissect_s5066_address(tvbuff_t *tvb, guint offset, proto_tree *tree, gint source)
827 proto_item *ti = NULL;
828 proto_tree *s5066_tree_address = NULL;
832 ti = proto_tree_add_text(tree, tvb, offset, 4, "Source Address");
835 ti = proto_tree_add_text(tree, tvb, offset, 4, "Destination Address");
837 s5066_tree_address = proto_item_add_subtree(ti, ett_s5066_address);
838 proto_tree_add_item(s5066_tree_address, hf_s5066_ad_size, tvb, offset, 1, FALSE);
839 proto_tree_add_item(s5066_tree_address, hf_s5066_ad_group, tvb, offset, 1, FALSE);
840 address = tvb_get_ntohl(tvb, offset);
841 address = address & 0x1FFFFFFF;
842 proto_tree_add_ipv4(s5066_tree_address, hf_s5066_ad_address, tvb, offset, 4, g_htonl(address));
848 dissect_s5066_servicetype(tvbuff_t *tvb, guint offset, proto_tree *tree)
850 proto_item *ti = NULL;
851 proto_tree *s5066_tree_servicetype = NULL;
853 ti = proto_tree_add_text(tree, tvb, offset, 2, "Service type");
854 s5066_tree_servicetype = proto_item_add_subtree(ti, ett_s5066_servicetype);
856 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_txmode, tvb, offset, 1, FALSE);
857 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_delivery_confirmation, tvb, offset, 1, FALSE);
858 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_delivery_order, tvb, offset, 1, FALSE);
859 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_extended, tvb, offset, 1, FALSE); offset++;
860 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_retries, tvb, offset, 1, FALSE);
867 dissect_s5066_01(tvbuff_t *tvb, guint offset, proto_tree *tree)
869 proto_tree_add_item(tree, hf_s5066_01_sapid, tvb, offset, 1, FALSE);
870 proto_tree_add_item(tree, hf_s5066_01_rank, tvb, offset, 1, FALSE); offset++;
872 offset = dissect_s5066_servicetype(tvb, offset, tree);
874 proto_tree_add_item(tree, hf_s5066_01_unused, tvb, offset, 1, FALSE); offset++;
878 /* S_UNBIND_REQUEST */
879 /* Commented out: does nothing and causes <variable not used> messages.
881 dissect_s5066_02(tvbuff_t *tvb, guint offset, proto_tree *tree)
887 /* S_BIND_ACCEPTED */
889 dissect_s5066_03(tvbuff_t *tvb, guint offset, proto_tree *tree)
891 proto_tree_add_item(tree, hf_s5066_03_sapid, tvb, offset, 1, FALSE);
892 proto_tree_add_item(tree, hf_s5066_03_unused, tvb, offset, 1, FALSE); offset++;
893 proto_tree_add_item(tree, hf_s5066_03_mtu, tvb, offset, 2, FALSE); offset +=2;
897 /* S_BIND_REJECTED */
899 dissect_s5066_04(tvbuff_t *tvb, guint offset, proto_tree *tree)
901 proto_tree_add_item(tree, hf_s5066_04_reason, tvb, offset, 1, FALSE); offset++;
905 /* S_UNBIND_INDICATION */
907 dissect_s5066_05(tvbuff_t *tvb, guint offset, proto_tree *tree)
909 proto_tree_add_item(tree, hf_s5066_05_reason, tvb, offset, 1, FALSE); offset++;
913 /* S_HARD_LINK_ESTABLISH */
915 dissect_s5066_06(tvbuff_t *tvb, guint offset, proto_tree *tree)
917 proto_tree_add_item(tree, hf_s5066_06_link_type, tvb, offset, 1, FALSE);
918 proto_tree_add_item(tree, hf_s5066_06_link_priority, tvb, offset, 1, FALSE);
919 proto_tree_add_item(tree, hf_s5066_06_sapid, tvb, offset, 1, FALSE); offset++;
920 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
924 /* S_HARD_LINK_TERMINATE */
926 dissect_s5066_07(tvbuff_t *tvb, guint offset, proto_tree *tree)
928 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
932 /* S_HARD_LINK_ESTABLISHED */
934 dissect_s5066_08(tvbuff_t *tvb, guint offset, proto_tree *tree)
936 proto_tree_add_item(tree, hf_s5066_08_remote_status, tvb, offset, 1, FALSE); offset++;
937 proto_tree_add_item(tree, hf_s5066_08_link_type, tvb, offset, 1, FALSE);
938 proto_tree_add_item(tree, hf_s5066_08_link_priority, tvb, offset, 1, FALSE);
939 proto_tree_add_item(tree, hf_s5066_08_sapid, tvb, offset, 1, FALSE); offset++;
940 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
944 /* S_HARD_LINK_REJECTED */
946 dissect_s5066_09(tvbuff_t *tvb, guint offset, proto_tree *tree)
948 proto_tree_add_item(tree, hf_s5066_09_reason, tvb, offset, 1, FALSE); offset++;
949 proto_tree_add_item(tree, hf_s5066_09_link_type, tvb, offset, 1, FALSE);
950 proto_tree_add_item(tree, hf_s5066_09_link_priority, tvb, offset, 1, FALSE);
951 proto_tree_add_item(tree, hf_s5066_09_sapid, tvb, offset, 1, FALSE); offset++;
952 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
956 /* S_HARD_LINK_TERMINATED */
958 dissect_s5066_10(tvbuff_t *tvb, guint offset, proto_tree *tree)
960 proto_tree_add_item(tree, hf_s5066_10_reason, tvb, offset, 1, FALSE); offset++;
961 proto_tree_add_item(tree, hf_s5066_10_link_type, tvb, offset, 1, FALSE);
962 proto_tree_add_item(tree, hf_s5066_10_link_priority, tvb, offset, 1, FALSE);
963 proto_tree_add_item(tree, hf_s5066_10_sapid, tvb, offset, 1, FALSE); offset++;
964 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
968 /* S_HARD_LINK_INDICATION */
970 dissect_s5066_11(tvbuff_t *tvb, guint offset, proto_tree *tree)
972 proto_tree_add_item(tree, hf_s5066_11_remote_status, tvb, offset, 1, FALSE); offset++;
973 proto_tree_add_item(tree, hf_s5066_11_link_type, tvb, offset, 1, FALSE);
974 proto_tree_add_item(tree, hf_s5066_11_link_priority, tvb, offset, 1, FALSE);
975 proto_tree_add_item(tree, hf_s5066_11_sapid, tvb, offset, 1, FALSE); offset++;
976 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
980 /* S_HARD_LINK_ACCEPT */
982 dissect_s5066_12(tvbuff_t *tvb, guint offset, proto_tree *tree)
984 proto_tree_add_item(tree, hf_s5066_12_link_type, tvb, offset, 1, FALSE);
985 proto_tree_add_item(tree, hf_s5066_12_link_priority, tvb, offset, 1, FALSE);
986 proto_tree_add_item(tree, hf_s5066_12_sapid, tvb, offset, 1, FALSE); offset++;
987 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
991 /* S_HARD_LINK_REJECT */
993 dissect_s5066_13(tvbuff_t *tvb, guint offset, proto_tree *tree)
995 proto_tree_add_item(tree, hf_s5066_13_reason, tvb, offset, 1, FALSE); offset++;
996 proto_tree_add_item(tree, hf_s5066_13_link_type, tvb, offset, 1, FALSE);
997 proto_tree_add_item(tree, hf_s5066_13_link_priority, tvb, offset, 1, FALSE);
998 proto_tree_add_item(tree, hf_s5066_13_sapid, tvb, offset, 1, FALSE); offset++;
999 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1003 /* S_SUBNET_AVAILABILITY */
1005 dissect_s5066_14(tvbuff_t *tvb, guint offset, proto_tree *tree)
1007 proto_tree_add_item(tree, hf_s5066_14_status, tvb, offset, 1, FALSE); offset++;
1008 proto_tree_add_item(tree, hf_s5066_14_reason, tvb, offset, 1, FALSE); offset++;
1012 /* Following three commented out: do nothing and cause <variable not used> messages. */
1013 /* S_DATA_FLOW_ON */
1016 dissect_s5066_15(tvbuff_t *tvb, guint offset, proto_tree *tree)
1022 /* S_DATA_FLOW_OFF */
1025 dissect_s5066_16(tvbuff_t *tvb, guint offset, proto_tree *tree)
1034 dissect_s5066_17(tvbuff_t *tvb, guint offset, proto_tree *tree)
1040 /* S_MANAGEMENT_MESSAGE_REQUEST */
1042 dissect_s5066_18(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
1044 guint body_size = 0;
1045 proto_tree_add_item(tree, hf_s5066_18_type, tvb, offset, 1, FALSE); offset++;
1046 body_size = pdu_size - offset;
1047 proto_tree_add_item(tree, hf_s5066_18_body, tvb, offset, body_size, FALSE); offset += body_size;
1051 /* S_MANAGEMENT_MESSAGE_INDICATION */
1053 dissect_s5066_19(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
1055 guint body_size = 0;
1056 proto_tree_add_item(tree, hf_s5066_19_type, tvb, offset, 1, FALSE); offset++;
1057 body_size = pdu_size - offset;
1058 proto_tree_add_item(tree, hf_s5066_19_body, tvb, offset, body_size, FALSE); offset += body_size;
1062 /* S_UNIDATA_REQUEST */
1064 dissect_s5066_20(tvbuff_t *tvb, guint offset, proto_tree *tree)
1066 proto_tree_add_item(tree, hf_s5066_20_priority, tvb, offset, 1, FALSE);
1067 proto_tree_add_item(tree, hf_s5066_20_sapid, tvb, offset, 1, FALSE); offset++;
1068 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1069 offset = dissect_s5066_servicetype(tvb, offset, tree);
1070 proto_tree_add_item(tree, hf_s5066_20_ttl, tvb, offset, 3, FALSE); offset += 3;
1071 proto_tree_add_item(tree, hf_s5066_20_size, tvb, offset, 2, FALSE); offset += 2;
1076 /* S_UNIDATA_INDICATION */
1078 dissect_s5066_21(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
1081 proto_item *ti = NULL;
1082 guint d_pdu_size = 0;
1084 guint16 no_err_blocks = 0;
1085 guint16 no_nrx_blocks = 0;
1086 gboolean non_arq_w_errors = FALSE;
1088 proto_tree_add_item(tree, hf_s5066_21_priority, tvb, offset, 1, FALSE);
1089 proto_tree_add_item(tree, hf_s5066_21_dest_sapid, tvb, offset, 1, FALSE); offset++;
1090 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1092 tx_mode = tvb_get_guint8(tvb, offset);
1093 tx_mode = (tx_mode & 0xF0) >> 4;
1095 non_arq_w_errors = TRUE;
1098 proto_tree_add_item(tree, hf_s5066_21_tx_mode, tvb, offset, 1, FALSE);
1099 proto_tree_add_item(tree, hf_s5066_21_src_sapid, tvb, offset, 1, FALSE); offset++;
1100 offset = dissect_s5066_address(tvb, offset, tree, TRUE);
1102 d_pdu_size = tvb_get_ntohs(tvb, offset);
1103 proto_tree_add_item(tree, hf_s5066_21_size, tvb, offset, 2, FALSE); offset += 2;
1105 /* Handle RockwellCollins (<= v2.1) 4-byte offset */
1106 if ( (pdu_size - offset) == (d_pdu_size + 4) ) {
1107 ti = proto_tree_add_item(tree, hf_s5066_21_err_blocks, tvb, offset, 2, FALSE); offset += 2;
1108 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
1109 ti = proto_tree_add_item(tree, hf_s5066_21_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
1110 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
1112 /* Handle Non-ARQ with errors */
1113 if ( non_arq_w_errors ) {
1114 no_err_blocks = tvb_get_ntohs(tvb, offset);
1115 proto_tree_add_item(tree, hf_s5066_21_err_blocks, tvb, offset, 2, FALSE); offset += 2;
1116 for (i=0; i<no_err_blocks; i++) {
1117 proto_tree_add_item(tree, hf_s5066_21_err_ptr, tvb, offset, 2, FALSE); offset += 2;
1118 proto_tree_add_item(tree, hf_s5066_21_err_size, tvb, offset, 2, FALSE); offset += 2;
1120 no_nrx_blocks = tvb_get_ntohs(tvb, offset);
1121 proto_tree_add_item(tree, hf_s5066_21_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
1122 for (i=0; i<no_nrx_blocks; i++) {
1123 proto_tree_add_item(tree, hf_s5066_21_nrx_ptr, tvb, offset, 2, FALSE); offset += 2;
1124 proto_tree_add_item(tree, hf_s5066_21_nrx_size, tvb, offset, 2, FALSE); offset += 2;
1130 /* S_UNIDATA_REQUEST_CONFIRM */
1132 dissect_s5066_22(tvbuff_t *tvb, guint offset, proto_tree *tree)
1135 proto_tree_add_item(tree, hf_s5066_22_unused, tvb, offset, 1, FALSE);
1136 proto_tree_add_item(tree, hf_s5066_22_sapid, tvb, offset, 1, FALSE); offset++;
1137 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1138 pdu_size = tvb_get_ntohs(tvb, offset);
1139 proto_tree_add_item(tree, hf_s5066_22_size, tvb, offset, 2, FALSE); offset += 2;
1140 proto_tree_add_item(tree, hf_s5066_22_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
1145 /* S_UNIDATA_REQUEST_REJECTED */
1147 dissect_s5066_23(tvbuff_t *tvb, guint offset, proto_tree *tree)
1150 proto_tree_add_item(tree, hf_s5066_23_reason, tvb, offset, 1, FALSE);
1151 proto_tree_add_item(tree, hf_s5066_23_sapid, tvb, offset, 1, FALSE); offset++;
1152 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1153 pdu_size = tvb_get_ntohs(tvb, offset);
1154 proto_tree_add_item(tree, hf_s5066_23_size, tvb, offset, 2, FALSE); offset += 2;
1155 proto_tree_add_item(tree, hf_s5066_23_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
1160 /* S_EXPEDITED_UNIDATA_REQUEST */
1162 dissect_s5066_24(tvbuff_t *tvb, guint offset, proto_tree *tree)
1164 proto_tree_add_item(tree, hf_s5066_24_unused, tvb, offset, 1, FALSE);
1165 proto_tree_add_item(tree, hf_s5066_24_sapid, tvb, offset, 1, FALSE); offset++;
1166 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1167 offset = dissect_s5066_servicetype(tvb, offset, tree);
1168 proto_tree_add_item(tree, hf_s5066_24_ttl, tvb, offset, 3, FALSE); offset += 3;
1169 proto_tree_add_item(tree, hf_s5066_24_size, tvb, offset, 2, FALSE); offset += 2;
1174 /* S_EXPEDITED_UNIDATA_INDICATION */
1176 dissect_s5066_25(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
1179 proto_item *ti = NULL;
1180 guint d_pdu_size = 0;
1182 guint16 no_err_blocks = 0;
1183 guint16 no_nrx_blocks = 0;
1184 gboolean non_arq_w_errors = FALSE;
1186 proto_tree_add_item(tree, hf_s5066_25_unused, tvb, offset, 1, FALSE);
1187 proto_tree_add_item(tree, hf_s5066_25_dest_sapid, tvb, offset, 1, FALSE); offset++;
1188 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1190 tx_mode = tvb_get_guint8(tvb, offset);
1191 tx_mode = (tx_mode & 0xF0) >> 4;
1193 non_arq_w_errors = TRUE;
1196 proto_tree_add_item(tree, hf_s5066_25_tx_mode, tvb, offset, 1, FALSE);
1197 proto_tree_add_item(tree, hf_s5066_25_src_sapid, tvb, offset, 1, FALSE); offset++;
1198 offset = dissect_s5066_address(tvb, offset, tree, TRUE);
1200 d_pdu_size = tvb_get_ntohs(tvb, offset);
1201 proto_tree_add_item(tree, hf_s5066_25_size, tvb, offset, 2, FALSE); offset += 2;
1203 /* Handle RockwellCollins (<= v2.1) 4-byte offset */
1204 if ( (pdu_size - offset) == d_pdu_size + 4 ) {
1205 ti = proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, FALSE); offset += 2;
1206 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
1207 ti = proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
1208 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
1210 /* Handle Non-ARQ with errors */
1211 if ( non_arq_w_errors ) {
1212 no_err_blocks = tvb_get_ntohs(tvb, offset);
1213 proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, FALSE); offset += 2;
1214 for (i=0; i<no_err_blocks; i++) {
1215 proto_tree_add_item(tree, hf_s5066_25_err_ptr, tvb, offset, 2, FALSE); offset += 2;
1216 proto_tree_add_item(tree, hf_s5066_25_err_size, tvb, offset, 2, FALSE); offset += 2;
1218 no_nrx_blocks = tvb_get_ntohs(tvb, offset);
1219 proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
1220 for (i=0; i<no_nrx_blocks; i++) {
1221 proto_tree_add_item(tree, hf_s5066_25_nrx_ptr, tvb, offset, 2, FALSE); offset += 2;
1222 proto_tree_add_item(tree, hf_s5066_25_nrx_size, tvb, offset, 2, FALSE); offset += 2;
1228 /* S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
1230 dissect_s5066_26(tvbuff_t *tvb, guint offset, proto_tree *tree)
1233 proto_tree_add_item(tree, hf_s5066_26_unused, tvb, offset, 1, FALSE);
1234 proto_tree_add_item(tree, hf_s5066_26_sapid, tvb, offset, 1, FALSE); offset++;
1235 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1236 pdu_size = tvb_get_ntohs(tvb, offset);
1237 proto_tree_add_item(tree, hf_s5066_26_size, tvb, offset, 2, FALSE); offset += 2;
1238 proto_tree_add_item(tree, hf_s5066_26_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
1243 /* S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
1245 dissect_s5066_27(tvbuff_t *tvb, guint offset, proto_tree *tree)
1248 proto_tree_add_item(tree, hf_s5066_27_reason, tvb, offset, 1, FALSE);
1249 proto_tree_add_item(tree, hf_s5066_27_sapid, tvb, offset, 1, FALSE); offset++;
1250 offset = dissect_s5066_address(tvb, offset, tree, FALSE);
1251 pdu_size = tvb_get_ntohs(tvb, offset);
1252 proto_tree_add_item(tree, hf_s5066_27_size, tvb, offset, 2, FALSE); offset += 2;
1253 proto_tree_add_item(tree, hf_s5066_27_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
1259 get_s5066_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1263 /* Get the length of the S5066 PDU. */
1264 plen = tvb_get_ntohs(tvb, offset + s5066_size_offset);
1266 /* That length doesn't include the sync, version and length fields; add that in. */
1267 return plen + s5066_header_size;
1271 dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1273 /* Make sure there are enough bytes... */
1274 if (tvb_length(tvb) < 5)
1276 /* Check if the first two bytes are 0x90 0xEB: if not,
1277 then this is not a S5066 PDU or an unreassembled one.
1278 The third byte is the STANAG 5066 version: Right now only 0x00 is defined. */
1279 if( (tvb_get_guint8(tvb, 0) != 0x90) ||
1280 (tvb_get_guint8(tvb, 1) != 0xEB) ||
1281 (tvb_get_guint8(tvb, 2) != 0x00) ) {
1284 tcp_dissect_pdus(tvb, pinfo, tree, s5066_desegment, s5066_header_size, get_s5066_pdu_len, dissect_s5066_common);
1288 dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1292 proto_item *ti_s5066 = NULL;
1293 proto_item *ti_pdu = NULL;
1295 gint available_length = 0;
1296 gint reported_length = 0;
1298 /* Determine PDU type to display in INFO column */
1299 guint8 pdu_type = tvb_get_guint8(tvb, s5066_header_size);
1301 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1302 col_set_str(pinfo->cinfo, COL_PROTOCOL, "S5066");
1304 /* Clear out stuff in the info column, the add PDU type */
1305 if (check_col(pinfo->cinfo, COL_INFO)) {
1306 col_clear(pinfo->cinfo, COL_INFO);
1308 if (check_col(pinfo->cinfo, COL_INFO)) {
1309 col_add_fstr(pinfo->cinfo, COL_INFO, "PDU type %s", val_to_str(pdu_type, s5066_pdu_type, "Unknown (0x%02x)"));
1312 if (tree) { /* We are being asked for details */
1313 proto_tree *s5066_tree = NULL;
1314 proto_tree *s5066_tree_pdu = NULL;
1316 pdu_size = tvb_get_ntohs(tvb, s5066_size_offset) + s5066_header_size;
1318 ti_s5066 = proto_tree_add_item(tree, proto_s5066, tvb, 0, -1, FALSE);
1319 proto_item_append_text(ti_s5066, ", PDU type %s", val_to_str(pdu_type, s5066_pdu_type, "Unknown (0x%02x)"));
1320 s5066_tree = proto_item_add_subtree(ti_s5066, ett_s5066);
1321 proto_tree_add_item(s5066_tree, hf_s5066_sync_word, tvb, offset, 2, FALSE); offset +=2;
1322 if (!s5066_edition_one) {
1323 proto_tree_add_item(s5066_tree, hf_s5066_version, tvb, offset, 1, FALSE); offset++;
1325 proto_tree_add_item(s5066_tree, hf_s5066_size, tvb, offset, 2, FALSE); offset +=2;
1326 ti_pdu = proto_tree_add_item(s5066_tree, hf_s5066_type, tvb, offset, 1, FALSE); offset++;
1327 s5066_tree_pdu = proto_item_add_subtree(ti_pdu, ett_s5066_pdu);
1329 case 1: offset = dissect_s5066_01(tvb, offset, s5066_tree_pdu); break;
1330 /* case 2: offset = dissect_s5066_02(tvb, offset, s5066_tree_pdu); break; */
1331 case 3: offset = dissect_s5066_03(tvb, offset, s5066_tree_pdu); break;
1332 case 4: offset = dissect_s5066_04(tvb, offset, s5066_tree_pdu); break;
1333 case 5: offset = dissect_s5066_05(tvb, offset, s5066_tree_pdu); break;
1334 case 6: offset = dissect_s5066_06(tvb, offset, s5066_tree_pdu); break;
1335 case 7: offset = dissect_s5066_07(tvb, offset, s5066_tree_pdu); break;
1336 case 8: offset = dissect_s5066_08(tvb, offset, s5066_tree_pdu); break;
1337 case 9: offset = dissect_s5066_09(tvb, offset, s5066_tree_pdu); break;
1338 case 10: offset = dissect_s5066_10(tvb, offset, s5066_tree_pdu); break;
1339 case 11: offset = dissect_s5066_11(tvb, offset, s5066_tree_pdu); break;
1340 case 12: offset = dissect_s5066_12(tvb, offset, s5066_tree_pdu); break;
1341 case 13: offset = dissect_s5066_13(tvb, offset, s5066_tree_pdu); break;
1342 case 14: offset = dissect_s5066_14(tvb, offset, s5066_tree_pdu); break;
1343 /* case 15: offset = dissect_s5066_15(tvb, offset, s5066_tree_pdu); break; */
1344 /* case 16: offset = dissect_s5066_16(tvb, offset, s5066_tree_pdu); break; */
1345 /* case 17: offset = dissect_s5066_17(tvb, offset, s5066_tree_pdu); break; */
1346 case 18: offset = dissect_s5066_18(tvb, offset, s5066_tree_pdu, pdu_size); break;
1347 case 19: offset = dissect_s5066_19(tvb, offset, s5066_tree_pdu, pdu_size); break;
1348 case 20: offset = dissect_s5066_20(tvb, offset, s5066_tree_pdu); break;
1349 case 21: offset = dissect_s5066_21(tvb, offset, s5066_tree_pdu, pdu_size); break;
1350 case 22: offset = dissect_s5066_22(tvb, offset, s5066_tree_pdu); break;
1351 case 23: offset = dissect_s5066_23(tvb, offset, s5066_tree_pdu); break;
1352 case 24: offset = dissect_s5066_24(tvb, offset, s5066_tree_pdu); break;
1353 case 25: offset = dissect_s5066_25(tvb, offset, s5066_tree_pdu, pdu_size); break;
1354 case 26: offset = dissect_s5066_26(tvb, offset, s5066_tree_pdu); break;
1355 case 27: offset = dissect_s5066_27(tvb, offset, s5066_tree_pdu); break;
1358 proto_item_set_len(ti_s5066, offset);
1360 /* Call sub dissector(s) */
1361 reported_length = pdu_size - offset;
1362 available_length = tvb_length(tvb) - offset;
1364 next_tvb = tvb_new_subset(tvb, offset, MIN(available_length, reported_length), reported_length);
1365 call_dissector(data_handle, next_tvb, pinfo, tree);