Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-s5066sis.c
blob9377bb54ddc772318795e2566cb20fa364bd50dd
1 /* packet-s5066sis.c
2 * Routines to dissect STANAG 5066 Subnetwork Interface Sublayer (SIS)
3 * packets, as described in Annex A of STANAG 5066.
5 * Copyright (c) 2005 by Menno Andriesse <s5066 [AT] nc3a.nato.int>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1999 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/prefs.h>
18 #include "packet-tcp.h" /* For tcp_dissect_pdus() */
19 #include "packet-s5066sis.h"
22 /* SapIDs for RCOP/UDOP clients */
23 # define SAPID_TMMHS 2
24 # define SAPID_RCOP 6
25 # define SAPID_UDOP 7
27 /* Forward reference */
28 static dissector_handle_t s5066_tcp_handle;
29 /* Register functions */
30 void proto_register_s5066(void);
31 void proto_reg_handoff_s5066(void);
32 /* Main dissectors */
33 static int dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
34 static unsigned get_s5066_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data);
35 static int dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
36 /* Client transport layer header dissector */
37 static unsigned dissect_s5066_client_transport_header(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint8_t sapid, unsigned *client_app_id);
38 /* Service type and address dissectors */
39 static unsigned dissect_s5066_servicetype(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
40 static unsigned dissect_s5066_address(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int source);
41 /* S-Primitive dissectors */
42 static unsigned dissect_s5066_01(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
43 /* static unsigned dissect_s5066_02(tvbuff_t *tvb, unsigned offset, proto_tree *tree); */
44 static unsigned dissect_s5066_03(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
45 static unsigned dissect_s5066_04(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
46 static unsigned dissect_s5066_05(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
47 static unsigned dissect_s5066_06(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
48 static unsigned dissect_s5066_07(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
49 static unsigned dissect_s5066_08(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
50 static unsigned dissect_s5066_09(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
51 static unsigned dissect_s5066_10(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
52 static unsigned dissect_s5066_11(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
53 static unsigned dissect_s5066_12(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
54 static unsigned dissect_s5066_13(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
55 static unsigned dissect_s5066_14(tvbuff_t *tvb, unsigned offset, proto_tree *tree);
56 /* static unsigned dissect_s5066_15(tvbuff_t *tvb, unsigned offset, proto_tree *tree); */
57 /* static unsigned dissect_s5066_16(tvbuff_t *tvb, unsigned offset, proto_tree *tree); */
58 /* static unsigned dissect_s5066_17(tvbuff_t *tvb, unsigned offset, proto_tree *tree); */
59 static unsigned dissect_s5066_18(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size);
60 static unsigned dissect_s5066_19(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size);
61 static unsigned dissect_s5066_20(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
62 static unsigned dissect_s5066_21(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size, unsigned *client_app_id);
63 static unsigned dissect_s5066_22(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
64 static unsigned dissect_s5066_23(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
65 static unsigned dissect_s5066_24(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
66 static unsigned dissect_s5066_25(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size, unsigned *client_app_id);
67 static unsigned dissect_s5066_26(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
68 static unsigned dissect_s5066_27(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id);
70 static int proto_s5066;
72 static dissector_table_t s5066sis_dissector_table;
74 /* Enable desegmentation of S5066 over TCP */
75 static bool s5066_desegment = true;
76 /* Dissect old 'edition 1' of STANAG 5066 (It lacks the 'version' field.) */
77 static bool s5066_edition_one;
78 /* This port is registered with IANA */
79 #define S5066_PORT 5066
80 /* Size of header outside 'size' field */
81 static int s5066_header_size = 5;
82 /* Offset of 'size' field */
83 static int s5066_size_offset = 3;
85 /* Sync should be 0x90EB */
86 static int hf_s5066_sync_word;
87 /* Version should be 0x00 */
88 static int hf_s5066_version;
89 /* Total size of the PDU, excluding this size and previous fields */
90 /* So total size is this + 5 bytes (s5066_header_size) */
91 static int hf_s5066_size;
92 /* Th type of PDU */
93 static int hf_s5066_type;
94 static const value_string s5066_pdu_type[] = {
95 { 1, "S_BIND_REQUEST"},
96 { 2, "S_UNBIND_REQUEST"},
97 { 3, "S_BIND_ACCEPTED"},
98 { 4, "S_BIND_REJECTED"},
99 { 5, "S_UNBIND_INDICATION"},
100 { 6, "S_HARD_LINK_ESTABLISH"},
101 { 7, "S_HARD_LINK_TERMINATE"},
102 { 8, "S_HARD_LINK_ESTABLISHED"},
103 { 9, "S_HARD_LINK_REJECTED"},
104 {10, "S_HARD_LINK_TERMINATED"},
105 {11, "S_HARD_LINK_INDICATION"},
106 {12, "S_HARD_LINK_ACCEPT"},
107 {13, "S_HARD_LINK_REJECT"},
108 {14, "S_SUBNET_AVAILABILITY"},
109 {15, "S_DATAFLOW_ON"},
110 {16, "S_DATAFLOW_OFF"},
111 {17, "S_KEEP_ALIVE"},
112 {18, "S_MANAGEMENT_MESSAGE_REQUEST"},
113 {19, "S_MANAGEMENT_MESSAGE_INDICATION"},
114 {20, "S_UNIDATA_REQUEST"},
115 {21, "S_UNIDATA_INDICATION"},
116 {22, "S_UNIDATA_REQUEST_CONFIRM"},
117 {23, "S_UNIDATA_REQUEST_REJECTED"},
118 {24, "S_EXPEDITED_UNIDATA_REQUEST"},
119 {25, "S_EXPEDITED_UNIDATA_INDICATION"},
120 {26, "S_EXPEDITED_UNIDATA_REQUEST_CONFIRM"},
121 {27, "S_EXPEDITED_UNIDATA_REQUEST_REJECTED"},
122 { 0, NULL },
125 /* STANAG 5066 Address */
126 /* Size is defined in nibbles (4 bits) */
127 static int hf_s5066_ad_size;
128 /* Group flag: 0 = false, 1 = true */
129 static int hf_s5066_ad_group;
130 /* The remainder of the 4 bytes form the address */
131 static int hf_s5066_ad_address;
133 /* Service type */
134 /* Transmission mode: */
135 static int hf_s5066_st_txmode;
136 static const value_string s5066_st_txmode[] = {
137 { 0, "Ignore service type field"},
138 { 1, "ARQ"},
139 { 2, "Non-ARQ (Broadcast)"},
140 { 3, "Non-ARQ (with errors)"},
141 { 4, "Other non-ARQ types"},
142 { 5, "Other non-ARQ types"},
143 { 6, "Other non-ARQ types"},
144 { 7, "Other non-ARQ types"},
145 { 8, "Other non-ARQ types"},
146 { 9, "Other non-ARQ types"},
147 {10, "Other non-ARQ types"},
148 {11, "Other non-ARQ types"},
149 {12, "Other non-ARQ types"},
150 {13, "Other non-ARQ types"},
151 {14, "Other non-ARQ types"},
152 {15, "Other non-ARQ types"},
153 { 0, NULL },
155 /* Delivery confirmation: */
156 static int hf_s5066_st_delivery_confirmation;
157 static const value_string s5066_st_delivery_confirmation[] = {
158 { 0, "No confirmation"},
159 { 1, "Node delivery confirmation"},
160 { 2, "Client delivery confirmation"},
161 { 3, "-- Not defined --"},
162 { 0, NULL },
164 /* Delivery order: */
165 static int hf_s5066_st_delivery_order;
166 static const value_string s5066_st_delivery_order[] = {
167 { 0, "In-order delivery"},
168 { 1, "As-they-arrive"},
169 { 0, NULL },
171 /* Extended field present: (Never in the current version.) */
172 static int hf_s5066_st_extended;
173 static const value_string s5066_st_extended[] = {
174 { 0, "No extended field"},
175 { 1, "Extended field follows"},
176 { 0, NULL },
178 /* Number of retransmissions when in Non-ARQ: */
179 static int hf_s5066_st_retries;
181 /* Client transport layer header */
182 static int hf_s5066_ctl_conn_id;
183 static int hf_s5066_ctl_reserved;
184 static int hf_s5066_ctl_updu_id;
185 static int hf_s5066_ctl_updu_segment;
186 static int hf_s5066_ctl_app_id;
187 static const value_string s5066_client_application_ids[] = {
188 { S5066_CLIENT_BFTP, "Basic File Transfer Protocol (BFTP) File Transfer Service"},
189 { S5066_CLIENT_FRAP, "File-Receipt/Acknowledgement Protocol"},
190 { S5066_CLIENT_FRAP_V2, "File-Receipt/Acknowledgement Protocol Version 2"},
191 { S5066_CLIENT_S4406_ANNEX_E_TMI_1_P_MUL, "STANAG 4406 ANNEX E: Acp 142 (TMI-1)"},
192 { S5066_CLIENT_S4406_ANNEX_E_TMI_2, "STANAG 4406 ANNEX E (TMI-2)"},
193 { S5066_CLIENT_S4406_ANNEX_E_TMI_3, "STANAG 4406 ANNEX E (TMI-3)"},
194 { S5066_CLIENT_S4406_ANNEX_E_TMI_4_DMP, "STANAG 4406 ANNEX E: DMP (TMI-4)"},
195 { S5066_CLIENT_S4406_ANNEX_E_TMI_5_ACP_127, "STANAG 4406 ANNEX E: Acp 127 Access Unit (TMI-5)"},
196 { 0, NULL },
199 /* SAP ID Assignments from Table F-1 */
200 static const value_string s5066_sapid_assignments[] = {
201 { 0, "Subnet management client"},
202 { 1, "Character-Oriented Serial Stream (COSS) Client"},
203 { 2, "STANAG 4406 Annex E - Tactical Military Message Handling (T-MMHS) Client"},
204 { 3, "HMTP (HF Mail Transfer Protocol)"},
205 { 4, "HFPOP (HF Post-Office Protocol)"},
206 { 5, "Operator orderwire (HFCHAT)"},
207 { 6, "Reliable Connection-Oriented Protocol (RCOP) w/ Extended Client"},
208 { 7, "Unreliable Datagram Oriented Protocol (UDOP) w/ Extended Client"},
209 { 8, "ETHER client"},
210 { 9, "IP client"},
211 { 10, "RESERVED - for future assignment"},
212 { 11, "RESERVED - for future assignment"},
213 { 12, "Compressed File Transport Protocol (CFTP)"},
214 { 13, "UNASSIGNED - available for arbitrary use"},
215 { 14, "UNASSIGNED - available for arbitrary use"},
216 { 15, "UNASSIGNED - available for arbitrary use"},
217 { 0, NULL },
220 /* Type 1: S_BIND_REQUEST */
221 static int hf_s5066_01_sapid;
222 static int hf_s5066_01_rank;
223 static int hf_s5066_01_unused;
225 /* Type 2: S_UNBIND_REQUEST */
226 /* --- no subfields --- */
228 /* Type 3: S_BIND_ACCEPTED */
229 static int hf_s5066_03_sapid;
230 static int hf_s5066_03_unused;
231 static int hf_s5066_03_mtu;
233 /* Type 4: S_BIND_REJECTED */
234 static int hf_s5066_04_reason;
235 static const value_string s5066_04_reason[] = {
236 { 0, "Unknown reason"},
237 { 1, "Not enough resources"},
238 { 2, "Invalid Sap ID"},
239 { 3, "Sap ID already allocated"},
240 { 4, "ARQ mode unsupportable during broadcast session"},
241 { 0, NULL },
244 /* Type 5: S_UNBIND_INDICATION */
245 static int hf_s5066_05_reason;
246 static const value_string s5066_05_reason[] = {
247 { 0, "Unknown reason"},
248 { 1, "Connection pre-empted by higher ranking client"},
249 { 2, "Inactivity (failure to respond to 'Keep-alive')"},
250 { 3, "Too many invalid primitives"},
251 { 4, "Too many expedited data request primitives"},
252 { 5, "ARQ mode unsupportable during broadcast session"},
253 { 0, NULL },
256 /* Hard links: hardlinktype value string array. */
257 static const value_string s5066_hard_link_type[] = {
258 { 0, "Link reservation"},
259 { 1, "Partial Bandwidth reservation"},
260 { 2, "Full Bandwidth reservation"},
261 { 3, "--- undefined ---"},
262 { 0, NULL },
265 /* Type 6: S_HARD_LINK_ESTABLISH */
266 static int hf_s5066_06_link_type;
267 static int hf_s5066_06_link_priority;
268 static int hf_s5066_06_sapid;
270 /* Type 7: S_HARD_LINK_TERMINATE */
271 /* Only remote node address */
273 /* Type 8: S_HARD_LINK_ESTABLISHED */
274 static int hf_s5066_08_remote_status;
275 static const value_string s5066_08_remote_status[] = {
276 { 0, "ERROR"},
277 { 1, "OK"},
278 { 0, NULL },
280 static int hf_s5066_08_link_type;
281 static int hf_s5066_08_link_priority;
282 static int hf_s5066_08_sapid;
284 /* Type 9: S_HARD_LINK_REJECTED */
285 static int hf_s5066_09_reason;
286 static const value_string s5066_09_reason[] = {
287 { 0, "--- undefined ---"},
288 { 1, "Remote node busy"},
289 { 2, "Higher priority link exists"},
290 { 3, "Remote node not responding"},
291 { 4, "Destination Sap ID not bound"},
292 { 5, "Requested Type-0 link exists"},
293 { 0, NULL },
295 static int hf_s5066_09_link_type;
296 static int hf_s5066_09_link_priority;
297 static int hf_s5066_09_sapid;
299 /* Type 10: S_HARD_LINK_TERMINATED */
300 static int hf_s5066_10_reason;
301 static const value_string s5066_10_reason[] = {
302 { 0, "--- undefined ---"},
303 { 1, "Link terminated by remote node"},
304 { 2, "Higher priority link requested"},
305 { 3, "Remote node not responding"},
306 { 4, "Destination Sap ID not bound"},
307 { 5, "Physical link broken"},
308 { 0, NULL },
310 static int hf_s5066_10_link_type;
311 static int hf_s5066_10_link_priority;
312 static int hf_s5066_10_sapid;
314 /* Type 11: S_HARD_LINK_INDICATION */
315 static int hf_s5066_11_remote_status;
316 static const value_string s5066_11_remote_status[] = {
317 { 0, "ERROR"},
318 { 1, "OK"},
319 { 0, NULL },
321 static int hf_s5066_11_link_type;
322 static int hf_s5066_11_link_priority;
323 static int hf_s5066_11_sapid;
325 /* Type 12: S_HARD_LINK_ACCEPT */
326 static int hf_s5066_12_link_type;
327 static int hf_s5066_12_link_priority;
328 static int hf_s5066_12_sapid;
330 /* Type 13: S_HARD_LINK_REJECT */
331 static int hf_s5066_13_reason;
332 static const value_string s5066_13_reason[] = {
333 { 0, "--- undefined ---"},
334 { 0, NULL },
336 static int hf_s5066_13_link_type;
337 static int hf_s5066_13_link_priority;
338 static int hf_s5066_13_sapid;
340 /* Type 14: S_SUBNET_AVAILABILITY */
341 static int hf_s5066_14_status;
342 static const value_string s5066_14_status[] = {
343 { 0, "Off"},
344 { 1, "On"},
345 { 2, "Receive only"},
346 { 3, "Half-duplex"},
347 { 4, "Full-duplex"},
348 { 0, NULL },
350 static int hf_s5066_14_reason;
351 static const value_string s5066_14_reason[] = {
352 { 0, "Unknown reason"},
353 { 1, "Local node in EMCON"},
354 { 2, "Higher priority link requested"},
355 { 0, NULL },
358 /* Type 15: S_DATAFLOW_ON */
359 /* --- no subfields --- */
361 /* Type 16: S_DATAFLOW_OFF */
362 /* --- no subfields --- */
364 /* Type 17: S_KEEP_ALIVE */
365 /* --- no subfields --- */
367 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
368 static int hf_s5066_18_type;
369 static int hf_s5066_18_body;
371 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
372 static int hf_s5066_19_type;
373 static int hf_s5066_19_body;
375 /* Type 20: S_UNIDATA_REQUEST */
376 static int hf_s5066_20_priority;
377 static int hf_s5066_20_sapid;
378 static int hf_s5066_20_ttl;
379 static int hf_s5066_20_size;
381 /* Type 21: S_UNIDATA_INDICATION */
382 static int hf_s5066_21_priority;
383 static int hf_s5066_21_dest_sapid;
384 static int hf_s5066_21_tx_mode;
385 static int hf_s5066_21_src_sapid;
386 static int hf_s5066_21_size;
387 static int hf_s5066_21_err_blocks;
388 static int hf_s5066_21_err_ptr;
389 static int hf_s5066_21_err_size;
390 static int hf_s5066_21_nrx_blocks;
391 static int hf_s5066_21_nrx_ptr;
392 static int hf_s5066_21_nrx_size;
395 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
396 static int hf_s5066_22_unused;
397 static int hf_s5066_22_sapid;
398 static int hf_s5066_22_size;
399 static int hf_s5066_22_data;
401 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
402 static int hf_s5066_23_reason;
403 static const value_string s5066_23_reason[] = {
404 { 0, "Unknown reason"},
405 { 1, "Time-To-Live expired"},
406 { 2, "Destination SapID not bound"},
407 { 3, "Destination node not responding"},
408 { 4, "U_PDU larger than MTU"},
409 { 5, "Transmission Mode not specified"},
410 { 0, NULL },
412 static int hf_s5066_23_sapid;
413 static int hf_s5066_23_size;
414 static int hf_s5066_23_data;
416 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
417 static int hf_s5066_24_unused;
418 static int hf_s5066_24_sapid;
419 static int hf_s5066_24_ttl;
420 static int hf_s5066_24_size;
422 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
423 static int hf_s5066_25_unused;
424 static int hf_s5066_25_dest_sapid;
425 static int hf_s5066_25_tx_mode;
426 static int hf_s5066_25_src_sapid;
427 static int hf_s5066_25_size;
428 static int hf_s5066_25_err_blocks;
429 static int hf_s5066_25_err_ptr;
430 static int hf_s5066_25_err_size;
431 static int hf_s5066_25_nrx_blocks;
432 static int hf_s5066_25_nrx_ptr;
433 static int hf_s5066_25_nrx_size;
435 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
436 static int hf_s5066_26_unused;
437 static int hf_s5066_26_sapid;
438 static int hf_s5066_26_size;
439 static int hf_s5066_26_data;
441 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
442 static int hf_s5066_27_reason;
443 static const value_string s5066_27_reason[] = {
444 { 0, "Unknown reason"},
445 { 1, "Time-To-Live expired"},
446 { 2, "Destination SapID not bound"},
447 { 3, "Destination node not responding"},
448 { 4, "U_PDU larger than MTU"},
449 { 5, "Transmission Mode not specified"},
450 { 0, NULL },
452 static int hf_s5066_27_sapid;
453 static int hf_s5066_27_size;
454 static int hf_s5066_27_data;
457 static int ett_s5066;
458 static int ett_s5066_pdu;
459 static int ett_s5066_servicetype;
460 static int ett_s5066_client_transport_header;
461 static int ett_s5066_address;
463 static unsigned
464 dissect_s5066_address(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int source)
466 proto_tree *s5066_tree_address;
467 uint32_t addr;
469 if (source) {
470 s5066_tree_address = proto_tree_add_subtree(tree, tvb, offset, 4, ett_s5066_address, NULL, "Source Address");
472 else {
473 s5066_tree_address = proto_tree_add_subtree(tree, tvb, offset, 4, ett_s5066_address, NULL, "Destination Address");
476 proto_tree_add_item(s5066_tree_address, hf_s5066_ad_size, tvb, offset, 1, ENC_BIG_ENDIAN);
477 proto_tree_add_item(s5066_tree_address, hf_s5066_ad_group, tvb, offset, 1, ENC_BIG_ENDIAN);
478 addr = tvb_get_ntohl(tvb, offset);
479 addr = addr & 0x1FFFFFFF;
480 proto_tree_add_ipv4(s5066_tree_address, hf_s5066_ad_address, tvb, offset, 4, g_htonl(addr));
482 return offset + 4;
485 static unsigned
486 dissect_s5066_servicetype(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
488 proto_tree *s5066_tree_servicetype;
490 s5066_tree_servicetype = proto_tree_add_subtree(tree, tvb, offset, 2, ett_s5066_servicetype, NULL, "Service type");
492 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_txmode, tvb, offset, 1, ENC_BIG_ENDIAN);
493 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_delivery_confirmation, tvb, offset, 1, ENC_BIG_ENDIAN);
494 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_delivery_order, tvb, offset, 1, ENC_BIG_ENDIAN);
495 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_extended, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
496 proto_tree_add_item(s5066_tree_servicetype, hf_s5066_st_retries, tvb, offset, 1, ENC_BIG_ENDIAN);
498 return offset;
501 static unsigned
502 dissect_s5066_client_transport_header(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint8_t sapid, unsigned *client_app_id)
504 proto_tree *s5066_tree_client_transport_header;
506 if (!((sapid == SAPID_TMMHS) || (sapid == SAPID_RCOP) || (sapid == SAPID_UDOP))) {
507 return offset;
510 s5066_tree_client_transport_header = proto_tree_add_subtree(tree, tvb, offset, 6, ett_s5066_client_transport_header, NULL, "Client Transport Layer Header");
512 proto_tree_add_item(s5066_tree_client_transport_header, hf_s5066_ctl_conn_id, tvb, offset, 1, ENC_BIG_ENDIAN);
513 proto_tree_add_item(s5066_tree_client_transport_header, hf_s5066_ctl_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
514 offset++;
515 proto_tree_add_item(s5066_tree_client_transport_header, hf_s5066_ctl_updu_id, tvb, offset, 1, ENC_BIG_ENDIAN);
516 offset++;
517 proto_tree_add_item(s5066_tree_client_transport_header, hf_s5066_ctl_updu_segment, tvb, offset, 2, ENC_BIG_ENDIAN);
518 offset += 2;
519 *client_app_id = tvb_get_ntohs(tvb, offset);
520 proto_tree_add_item(s5066_tree_client_transport_header, hf_s5066_ctl_app_id, tvb, offset, 2, ENC_BIG_ENDIAN);
521 offset += 2;
523 return offset;
526 /* S_BIND_REQUEST */
527 static unsigned
528 dissect_s5066_01(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
530 proto_tree_add_item(tree, hf_s5066_01_sapid, tvb, offset, 1, ENC_BIG_ENDIAN);
531 proto_tree_add_item(tree, hf_s5066_01_rank, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
533 offset = dissect_s5066_servicetype(tvb, offset, tree);
535 proto_tree_add_item(tree, hf_s5066_01_unused, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
536 return offset;
539 /* S_UNBIND_REQUEST */
540 /* Commented out: does nothing and causes <variable not used> messages.
541 static unsigned
542 dissect_s5066_02(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
544 return offset;
548 /* S_BIND_ACCEPTED */
549 static unsigned
550 dissect_s5066_03(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
552 proto_tree_add_item(tree, hf_s5066_03_sapid, tvb, offset, 1, ENC_BIG_ENDIAN);
553 proto_tree_add_item(tree, hf_s5066_03_unused, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
554 proto_tree_add_item(tree, hf_s5066_03_mtu, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
555 return offset;
558 /* S_BIND_REJECTED */
559 static unsigned
560 dissect_s5066_04(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
562 proto_tree_add_item(tree, hf_s5066_04_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
563 return offset;
566 /* S_UNBIND_INDICATION */
567 static unsigned
568 dissect_s5066_05(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
570 proto_tree_add_item(tree, hf_s5066_05_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
571 return offset;
574 /* S_HARD_LINK_ESTABLISH */
575 static unsigned
576 dissect_s5066_06(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
578 proto_tree_add_item(tree, hf_s5066_06_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
579 proto_tree_add_item(tree, hf_s5066_06_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
580 proto_tree_add_item(tree, hf_s5066_06_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
581 offset = dissect_s5066_address(tvb, offset, tree, false);
582 return offset;
585 /* S_HARD_LINK_TERMINATE */
586 static unsigned
587 dissect_s5066_07(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
589 offset = dissect_s5066_address(tvb, offset, tree, false);
590 return offset;
593 /* S_HARD_LINK_ESTABLISHED */
594 static unsigned
595 dissect_s5066_08(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
597 proto_tree_add_item(tree, hf_s5066_08_remote_status, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
598 proto_tree_add_item(tree, hf_s5066_08_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
599 proto_tree_add_item(tree, hf_s5066_08_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
600 proto_tree_add_item(tree, hf_s5066_08_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
601 offset = dissect_s5066_address(tvb, offset, tree, false);
602 return offset;
605 /* S_HARD_LINK_REJECTED */
606 static unsigned
607 dissect_s5066_09(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
609 proto_tree_add_item(tree, hf_s5066_09_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
610 proto_tree_add_item(tree, hf_s5066_09_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
611 proto_tree_add_item(tree, hf_s5066_09_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
612 proto_tree_add_item(tree, hf_s5066_09_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
613 offset = dissect_s5066_address(tvb, offset, tree, false);
614 return offset;
617 /* S_HARD_LINK_TERMINATED */
618 static unsigned
619 dissect_s5066_10(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
621 proto_tree_add_item(tree, hf_s5066_10_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
622 proto_tree_add_item(tree, hf_s5066_10_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
623 proto_tree_add_item(tree, hf_s5066_10_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
624 proto_tree_add_item(tree, hf_s5066_10_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
625 offset = dissect_s5066_address(tvb, offset, tree, false);
626 return offset;
629 /* S_HARD_LINK_INDICATION */
630 static unsigned
631 dissect_s5066_11(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
633 proto_tree_add_item(tree, hf_s5066_11_remote_status, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
634 proto_tree_add_item(tree, hf_s5066_11_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
635 proto_tree_add_item(tree, hf_s5066_11_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
636 proto_tree_add_item(tree, hf_s5066_11_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
637 offset = dissect_s5066_address(tvb, offset, tree, false);
638 return offset;
641 /* S_HARD_LINK_ACCEPT */
642 static unsigned
643 dissect_s5066_12(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
645 proto_tree_add_item(tree, hf_s5066_12_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
646 proto_tree_add_item(tree, hf_s5066_12_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
647 proto_tree_add_item(tree, hf_s5066_12_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
648 offset = dissect_s5066_address(tvb, offset, tree, false);
649 return offset;
652 /* S_HARD_LINK_REJECT */
653 static unsigned
654 dissect_s5066_13(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
656 proto_tree_add_item(tree, hf_s5066_13_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
657 proto_tree_add_item(tree, hf_s5066_13_link_type, tvb, offset, 1, ENC_BIG_ENDIAN);
658 proto_tree_add_item(tree, hf_s5066_13_link_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
659 proto_tree_add_item(tree, hf_s5066_13_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
660 offset = dissect_s5066_address(tvb, offset, tree, false);
661 return offset;
664 /* S_SUBNET_AVAILABILITY */
665 static unsigned
666 dissect_s5066_14(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
668 proto_tree_add_item(tree, hf_s5066_14_status, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
669 proto_tree_add_item(tree, hf_s5066_14_reason, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
670 return offset;
673 /* Following three commented out: do nothing and cause <variable not used> messages. */
674 /* S_DATA_FLOW_ON */
676 static unsigned
677 dissect_s5066_15(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
679 return offset;
683 /* S_DATA_FLOW_OFF */
685 static unsigned
686 dissect_s5066_16(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
688 return offset;
692 /* S_KEEP_ALIVE */
694 static unsigned
695 dissect_s5066_17(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
697 return offset;
701 /* S_MANAGEMENT_MESSAGE_REQUEST */
702 static unsigned
703 dissect_s5066_18(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size)
705 unsigned body_size = 0;
706 proto_tree_add_item(tree, hf_s5066_18_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
707 body_size = pdu_size - offset;
708 proto_tree_add_item(tree, hf_s5066_18_body, tvb, offset, body_size, ENC_NA); offset += body_size;
709 return offset;
712 /* S_MANAGEMENT_MESSAGE_INDICATION */
713 static unsigned
714 dissect_s5066_19(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size)
716 unsigned body_size = 0;
717 proto_tree_add_item(tree, hf_s5066_19_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
718 body_size = pdu_size - offset;
719 proto_tree_add_item(tree, hf_s5066_19_body, tvb, offset, body_size, ENC_NA); offset += body_size;
720 return offset;
723 /* S_UNIDATA_REQUEST */
724 static unsigned
725 dissect_s5066_20(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
727 uint8_t sapid;
728 proto_tree_add_item(tree, hf_s5066_20_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
729 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
730 proto_tree_add_item(tree, hf_s5066_20_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
731 offset = dissect_s5066_address(tvb, offset, tree, false);
732 offset = dissect_s5066_servicetype(tvb, offset, tree);
733 proto_tree_add_item(tree, hf_s5066_20_ttl, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3;
734 proto_tree_add_item(tree, hf_s5066_20_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
735 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
737 return offset;
740 /* S_UNIDATA_INDICATION */
741 static unsigned
742 dissect_s5066_21(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size, unsigned *client_app_id)
744 unsigned i=0;
745 proto_item *ti = NULL;
746 unsigned d_pdu_size = 0;
747 uint8_t tx_mode = 0;
748 uint16_t no_err_blocks = 0;
749 uint16_t no_nrx_blocks = 0;
750 bool non_arq_w_errors = false;
751 unsigned sapid;
753 proto_tree_add_item(tree, hf_s5066_21_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
754 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
755 proto_tree_add_item(tree, hf_s5066_21_dest_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
756 offset = dissect_s5066_address(tvb, offset, tree, false);
758 tx_mode = tvb_get_uint8(tvb, offset);
759 tx_mode = (tx_mode & 0xF0) >> 4;
760 if (tx_mode == 3) {
761 non_arq_w_errors = true;
764 proto_tree_add_item(tree, hf_s5066_21_tx_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
765 proto_tree_add_item(tree, hf_s5066_21_src_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
766 offset = dissect_s5066_address(tvb, offset, tree, true);
768 d_pdu_size = tvb_get_ntohs(tvb, offset);
769 proto_tree_add_item(tree, hf_s5066_21_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
771 /* Handle RockwellCollins (<= v2.1) 4-byte offset */
772 if ( (pdu_size - offset) == (d_pdu_size + 4) ) {
773 ti = proto_tree_add_item(tree, hf_s5066_21_err_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
774 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
775 ti = proto_tree_add_item(tree, hf_s5066_21_nrx_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
776 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
778 /* Handle Non-ARQ with errors */
779 if ( non_arq_w_errors ) {
780 no_err_blocks = tvb_get_ntohs(tvb, offset);
781 proto_tree_add_item(tree, hf_s5066_21_err_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
782 for (i=0; i<no_err_blocks; i++) {
783 proto_tree_add_item(tree, hf_s5066_21_err_ptr, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
784 proto_tree_add_item(tree, hf_s5066_21_err_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
786 no_nrx_blocks = tvb_get_ntohs(tvb, offset);
787 proto_tree_add_item(tree, hf_s5066_21_nrx_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
788 for (i=0; i<no_nrx_blocks; i++) {
789 proto_tree_add_item(tree, hf_s5066_21_nrx_ptr, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
790 proto_tree_add_item(tree, hf_s5066_21_nrx_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
793 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
794 return offset;
797 /* S_UNIDATA_REQUEST_CONFIRM */
798 static unsigned
799 dissect_s5066_22(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
801 unsigned pdu_size = 0;
802 uint8_t sapid;
803 proto_tree_add_item(tree, hf_s5066_22_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
804 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
805 proto_tree_add_item(tree, hf_s5066_22_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
806 offset = dissect_s5066_address(tvb, offset, tree, false);
807 pdu_size = tvb_get_ntohs(tvb, offset);
808 proto_tree_add_item(tree, hf_s5066_22_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
809 proto_tree_add_item(tree, hf_s5066_22_data, tvb, offset, pdu_size, ENC_NA); offset += pdu_size;
810 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
812 return offset;
815 /* S_UNIDATA_REQUEST_REJECTED */
816 static unsigned
817 dissect_s5066_23(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
819 unsigned pdu_size = 0;
820 uint8_t sapid;
821 proto_tree_add_item(tree, hf_s5066_23_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
822 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
823 proto_tree_add_item(tree, hf_s5066_23_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
824 offset = dissect_s5066_address(tvb, offset, tree, false);
825 pdu_size = tvb_get_ntohs(tvb, offset);
826 proto_tree_add_item(tree, hf_s5066_23_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
827 proto_tree_add_item(tree, hf_s5066_23_data, tvb, offset, pdu_size, ENC_NA); offset += pdu_size;
828 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
830 return offset;
833 /* S_EXPEDITED_UNIDATA_REQUEST */
834 static unsigned
835 dissect_s5066_24(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
837 uint8_t sapid;
838 proto_tree_add_item(tree, hf_s5066_24_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
839 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
840 proto_tree_add_item(tree, hf_s5066_24_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
841 offset = dissect_s5066_address(tvb, offset, tree, false);
842 offset = dissect_s5066_servicetype(tvb, offset, tree);
843 proto_tree_add_item(tree, hf_s5066_24_ttl, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3;
844 proto_tree_add_item(tree, hf_s5066_24_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
845 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
847 return offset;
850 /* S_EXPEDITED_UNIDATA_INDICATION */
851 static unsigned
852 dissect_s5066_25(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned pdu_size, unsigned *client_app_id)
854 unsigned i=0;
855 proto_item *ti = NULL;
856 unsigned d_pdu_size = 0;
857 uint8_t tx_mode = 0;
858 uint16_t no_err_blocks = 0;
859 uint16_t no_nrx_blocks = 0;
860 bool non_arq_w_errors = false;
861 uint8_t sapid;
863 proto_tree_add_item(tree, hf_s5066_25_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
864 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
865 proto_tree_add_item(tree, hf_s5066_25_dest_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
866 offset = dissect_s5066_address(tvb, offset, tree, false);
868 tx_mode = tvb_get_uint8(tvb, offset);
869 tx_mode = (tx_mode & 0xF0) >> 4;
870 if (tx_mode == 3) {
871 non_arq_w_errors = true;
874 proto_tree_add_item(tree, hf_s5066_25_tx_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
875 proto_tree_add_item(tree, hf_s5066_25_src_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
876 offset = dissect_s5066_address(tvb, offset, tree, true);
878 d_pdu_size = tvb_get_ntohs(tvb, offset);
879 proto_tree_add_item(tree, hf_s5066_25_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
881 /* Handle RockwellCollins (<= v2.1) 4-byte offset */
882 if ( (pdu_size - offset) == (d_pdu_size + 4) ) {
883 ti = proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
884 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
885 ti = proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
886 proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
888 /* Handle Non-ARQ with errors */
889 if ( non_arq_w_errors ) {
890 no_err_blocks = tvb_get_ntohs(tvb, offset);
891 proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
892 for (i=0; i<no_err_blocks; i++) {
893 proto_tree_add_item(tree, hf_s5066_25_err_ptr, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
894 proto_tree_add_item(tree, hf_s5066_25_err_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
896 no_nrx_blocks = tvb_get_ntohs(tvb, offset);
897 proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
898 for (i=0; i<no_nrx_blocks; i++) {
899 proto_tree_add_item(tree, hf_s5066_25_nrx_ptr, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
900 proto_tree_add_item(tree, hf_s5066_25_nrx_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
903 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
904 return offset;
907 /* S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
908 static unsigned
909 dissect_s5066_26(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
911 unsigned pdu_size = 0;
912 uint8_t sapid;
913 proto_tree_add_item(tree, hf_s5066_26_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
914 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
915 proto_tree_add_item(tree, hf_s5066_26_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
916 offset = dissect_s5066_address(tvb, offset, tree, false);
917 pdu_size = tvb_get_ntohs(tvb, offset);
918 proto_tree_add_item(tree, hf_s5066_26_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
919 proto_tree_add_item(tree, hf_s5066_26_data, tvb, offset, pdu_size, ENC_NA); offset += pdu_size;
920 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
922 return offset;
925 /* S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
926 static unsigned
927 dissect_s5066_27(tvbuff_t *tvb, unsigned offset, proto_tree *tree, unsigned *client_app_id)
929 unsigned pdu_size = 0;
930 uint8_t sapid;
931 proto_tree_add_item(tree, hf_s5066_27_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
932 sapid = tvb_get_uint8(tvb, offset) & 0x0F;
933 proto_tree_add_item(tree, hf_s5066_27_sapid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
934 offset = dissect_s5066_address(tvb, offset, tree, false);
935 pdu_size = tvb_get_ntohs(tvb, offset);
936 proto_tree_add_item(tree, hf_s5066_27_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
937 proto_tree_add_item(tree, hf_s5066_27_data, tvb, offset, pdu_size, ENC_NA); offset += pdu_size;
938 offset = dissect_s5066_client_transport_header(tvb, offset, tree, sapid, client_app_id);
940 return offset;
943 static unsigned
944 get_s5066_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
946 uint16_t plen;
948 /* Get the length of the S5066 PDU. */
949 plen = tvb_get_ntohs(tvb, offset + s5066_size_offset);
951 /* That length doesn't include the sync, version and length fields; add that in. */
952 return plen + s5066_header_size;
955 static int
956 dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
958 /* Make sure there are enough bytes... */
959 if (tvb_captured_length(tvb) < 5)
960 return 0;
961 /* Check if the first two bytes are 0x90 0xEB: if not,
962 then this is not a S5066 PDU or an unreassembled one.
963 The third byte is the STANAG 5066 version: Right now only 0x00 is defined. */
964 if( (tvb_get_uint8(tvb, 0) != 0x90) ||
965 (tvb_get_uint8(tvb, 1) != 0xEB) ||
966 (tvb_get_uint8(tvb, 2) != 0x00) ) {
967 return 0;
969 tcp_dissect_pdus(tvb, pinfo, tree, s5066_desegment, s5066_header_size, get_s5066_pdu_len, dissect_s5066_common, data);
970 return tvb_captured_length(tvb);
973 static int
974 dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
976 unsigned offset = 0;
977 unsigned pdu_size = 0;
978 proto_item *ti_s5066 = NULL;
979 proto_item *ti_pdu = NULL;
980 tvbuff_t *next_tvb;
981 int available_length = 0;
982 int reported_length = 0;
983 int client_app_id = 0;
984 proto_tree *s5066_tree = NULL;
985 proto_tree *s5066_tree_pdu = NULL;
987 /* Determine PDU type to display in INFO column */
988 uint8_t pdu_type = tvb_get_uint8(tvb, s5066_header_size);
990 col_set_str(pinfo->cinfo, COL_PROTOCOL, "S5066");
991 /* Clear out stuff in the info column, the add PDU type */
992 col_add_fstr(pinfo->cinfo, COL_INFO, "PDU type %s", val_to_str(pdu_type, s5066_pdu_type, "Unknown (0x%02x)"));
994 pdu_size = tvb_get_ntohs(tvb, s5066_size_offset) + s5066_header_size;
996 ti_s5066 = proto_tree_add_item(tree, proto_s5066, tvb, 0, -1, ENC_NA);
997 proto_item_append_text(ti_s5066, ", PDU type %s", val_to_str(pdu_type, s5066_pdu_type, "Unknown (0x%02x)"));
998 s5066_tree = proto_item_add_subtree(ti_s5066, ett_s5066);
999 proto_tree_add_item(s5066_tree, hf_s5066_sync_word, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
1000 if (!s5066_edition_one) {
1001 proto_tree_add_item(s5066_tree, hf_s5066_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
1003 proto_tree_add_item(s5066_tree, hf_s5066_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
1004 ti_pdu = proto_tree_add_item(s5066_tree, hf_s5066_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
1005 s5066_tree_pdu = proto_item_add_subtree(ti_pdu, ett_s5066_pdu);
1006 switch (pdu_type) {
1007 case 1: offset = dissect_s5066_01(tvb, offset, s5066_tree_pdu); break;
1008 /* case 2: offset = dissect_s5066_02(tvb, offset, s5066_tree_pdu); break; */
1009 case 3: offset = dissect_s5066_03(tvb, offset, s5066_tree_pdu); break;
1010 case 4: offset = dissect_s5066_04(tvb, offset, s5066_tree_pdu); break;
1011 case 5: offset = dissect_s5066_05(tvb, offset, s5066_tree_pdu); break;
1012 case 6: offset = dissect_s5066_06(tvb, offset, s5066_tree_pdu); break;
1013 case 7: offset = dissect_s5066_07(tvb, offset, s5066_tree_pdu); break;
1014 case 8: offset = dissect_s5066_08(tvb, offset, s5066_tree_pdu); break;
1015 case 9: offset = dissect_s5066_09(tvb, offset, s5066_tree_pdu); break;
1016 case 10: offset = dissect_s5066_10(tvb, offset, s5066_tree_pdu); break;
1017 case 11: offset = dissect_s5066_11(tvb, offset, s5066_tree_pdu); break;
1018 case 12: offset = dissect_s5066_12(tvb, offset, s5066_tree_pdu); break;
1019 case 13: offset = dissect_s5066_13(tvb, offset, s5066_tree_pdu); break;
1020 case 14: offset = dissect_s5066_14(tvb, offset, s5066_tree_pdu); break;
1021 /* case 15: offset = dissect_s5066_15(tvb, offset, s5066_tree_pdu); break; */
1022 /* case 16: offset = dissect_s5066_16(tvb, offset, s5066_tree_pdu); break; */
1023 /* case 17: offset = dissect_s5066_17(tvb, offset, s5066_tree_pdu); break; */
1024 case 18: offset = dissect_s5066_18(tvb, offset, s5066_tree_pdu, pdu_size); break;
1025 case 19: offset = dissect_s5066_19(tvb, offset, s5066_tree_pdu, pdu_size); break;
1026 case 20: offset = dissect_s5066_20(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1027 case 21: offset = dissect_s5066_21(tvb, offset, s5066_tree_pdu, pdu_size, &client_app_id); break;
1028 case 22: offset = dissect_s5066_22(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1029 case 23: offset = dissect_s5066_23(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1030 case 24: offset = dissect_s5066_24(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1031 case 25: offset = dissect_s5066_25(tvb, offset, s5066_tree_pdu, pdu_size, &client_app_id); break;
1032 case 26: offset = dissect_s5066_26(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1033 case 27: offset = dissect_s5066_27(tvb, offset, s5066_tree_pdu, &client_app_id); break;
1035 proto_item_set_len(ti_s5066, offset);
1037 /* Call sub dissector(s) */
1038 reported_length = pdu_size - offset;
1039 available_length = tvb_captured_length(tvb) - offset;
1041 next_tvb = tvb_new_subset_length_caplen(tvb, offset, MIN(available_length, reported_length), reported_length);
1043 if(dissector_try_uint(s5066sis_dissector_table, client_app_id, next_tvb, pinfo, tree) == 0) {
1044 call_data_dissector(next_tvb, pinfo, tree);
1047 return tvb_captured_length(tvb);
1050 void
1051 proto_register_s5066(void)
1053 static hf_register_info hf[] = {
1054 { &hf_s5066_sync_word,
1055 { "Sync preamble", "s5066sis.sync", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1057 { &hf_s5066_version,
1058 { "S5066 version", "s5066sis.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1060 { &hf_s5066_size,
1061 { "S_Primitive size", "s5066sis.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1063 { &hf_s5066_type,
1064 { "PDU Type", "s5066sis.type", FT_UINT8, BASE_DEC, VALS(s5066_pdu_type), 0x0, NULL, HFILL }
1066 /* STANAG 5066 Address */
1067 { &hf_s5066_ad_size,
1068 { "Address size (1/2 Bytes)", "s5066sis.address.size", FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL }
1070 { &hf_s5066_ad_group,
1071 { "Group address", "s5066sis.address.group", FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
1073 { &hf_s5066_ad_address,
1074 { "Address", "s5066sis.address.address", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
1076 /* Service type */
1077 { &hf_s5066_st_txmode,
1078 { "Transmission mode", "s5066sis.st.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
1080 { &hf_s5066_st_delivery_confirmation,
1081 { "Delivery confirmation", "s5066sis.st.confirm", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_confirmation), 0x0C, NULL, HFILL }
1083 { &hf_s5066_st_delivery_order,
1084 { "Delivery order", "s5066sis.st.order", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_order), 0x02, NULL, HFILL }
1086 { &hf_s5066_st_extended,
1087 { "Extended field", "s5066sis.st.extended", FT_UINT8, BASE_HEX, VALS(s5066_st_extended), 0x01, NULL, HFILL }
1089 { &hf_s5066_st_retries,
1090 { "Minimum number of retransmissions", "s5066sis.st.retries", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1092 /* Client transport layer header */
1093 { &hf_s5066_ctl_conn_id,
1094 { "Connection ID number", "s5066sis.ctl.conn_id", FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }
1096 { &hf_s5066_ctl_reserved,
1097 { "Reserved", "s5066sis.ctl.reserved", FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
1099 { &hf_s5066_ctl_updu_id,
1100 { "UPDU ID number", "s5066sis.ctl.updu_id", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1102 { &hf_s5066_ctl_updu_segment,
1103 { "UPDU segment number", "s5066sis.ctl.updu_segment", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1105 { &hf_s5066_ctl_app_id,
1106 { "Application identifier", "s5066sis.ctl.app_id", FT_UINT16, BASE_HEX, VALS(s5066_client_application_ids), 0x0, NULL, HFILL }
1108 /* PDU Type 01: S_BIND_REQUEST */
1109 { &hf_s5066_01_sapid,
1110 { "Sap ID", "s5066sis.01.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0xF0, NULL, HFILL }
1112 { &hf_s5066_01_rank,
1113 { "Rank", "s5066sis.01.rank", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1115 { &hf_s5066_01_unused,
1116 { "(Unused)", "s5066sis.01.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
1118 /* PDU Type 02: S_UNBIND_REQUEST */
1119 /* --- no subfields --- */
1120 /* PDU Type 03: S_BIND_ACCEPTED */
1121 { &hf_s5066_03_sapid,
1122 { "Sap ID", "s5066sis.03.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0xF0, NULL, HFILL }
1124 { &hf_s5066_03_unused,
1125 { "(Unused)", "s5066sis.03.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
1127 { &hf_s5066_03_mtu,
1128 { "MTU", "s5066sis.03.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1130 /* PDU Type 04: S_BIND_REJECTED */
1131 { &hf_s5066_04_reason,
1132 { "Reason", "s5066sis.04.reason", FT_UINT8, BASE_DEC, VALS(s5066_04_reason), 0x0, NULL, HFILL }
1134 /* PDU Type 05: S_UNBIND_INDICATION */
1135 { &hf_s5066_05_reason,
1136 { "Reason", "s5066sis.05.reason", FT_UINT8, BASE_DEC, VALS(s5066_05_reason), 0x0, NULL, HFILL }
1138 /* Type 6: S_HARD_LINK_ESTABLISH */
1139 { &hf_s5066_06_link_type,
1140 { "Hardlink type", "s5066sis.06.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1142 { &hf_s5066_06_link_priority,
1143 { "Priority", "s5066sis.06.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1145 { &hf_s5066_06_sapid,
1146 { "Remote Sap ID", "s5066sis.06.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1148 /* Type 7: S_HARD_LINK_TERMINATE */
1149 /* --- Only remote node address --- */
1150 /* Type 8: S_HARD_LINK_ESTABLISHED */
1151 { &hf_s5066_08_remote_status,
1152 { "Remote node status", "s5066sis.08.status", FT_UINT8, BASE_DEC, VALS(s5066_08_remote_status), 0x0, NULL, HFILL }
1154 { &hf_s5066_08_link_type,
1155 { "Hardlink type", "s5066sis.08.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1157 { &hf_s5066_08_link_priority,
1158 { "Priority", "s5066sis.08.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1160 { &hf_s5066_08_sapid,
1161 { "Remote Sap ID", "s5066sis.08.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1163 /* Type 9: S_HARD_LINK_REJECTED */
1164 { &hf_s5066_09_reason,
1165 { "Reason", "s5066sis.09.reason", FT_UINT8, BASE_DEC, VALS(s5066_09_reason), 0x0, NULL, HFILL }
1167 { &hf_s5066_09_link_type,
1168 { "Hardlink type", "s5066sis.09.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1170 { &hf_s5066_09_link_priority,
1171 { "Priority", "s5066sis.09.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1173 { &hf_s5066_09_sapid,
1174 { "Remote Sap ID", "s5066sis.09.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1176 /* Type 10: S_HARD_LINK_TERMINATED */
1177 { &hf_s5066_10_reason,
1178 { "Reason", "s5066sis.10.reason", FT_UINT8, BASE_DEC, VALS(s5066_10_reason), 0x0, NULL, HFILL }
1180 { &hf_s5066_10_link_type,
1181 { "Hardlink type", "s5066sis.10.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1183 { &hf_s5066_10_link_priority,
1184 { "Priority", "s5066sis.10.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1186 { &hf_s5066_10_sapid,
1187 { "Remote Sap ID", "s5066sis.10.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1189 /* Type 11: S_HARD_LINK_INDICATION */
1190 { &hf_s5066_11_remote_status,
1191 { "Remote node status", "s5066sis.11.status", FT_UINT8, BASE_DEC, VALS(s5066_11_remote_status), 0x0, NULL, HFILL }
1193 { &hf_s5066_11_link_type,
1194 { "Hardlink type", "s5066sis.11.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1196 { &hf_s5066_11_link_priority,
1197 { "Priority", "s5066sis.11.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1199 { &hf_s5066_11_sapid,
1200 { "Remote Sap ID", "s5066sis.11.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1202 /* Type 12: S_HARD_LINK_ACCEPT */
1203 { &hf_s5066_12_link_type,
1204 { "Hardlink type", "s5066sis.12.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1206 { &hf_s5066_12_link_priority,
1207 { "Priority", "s5066sis.12.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1209 { &hf_s5066_12_sapid,
1210 { "Remote Sap ID", "s5066sis.12.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1212 /* Type 13: S_HARD_LINK_REJECT */
1213 { &hf_s5066_13_reason,
1214 { "Reason", "s5066sis.13.reason", FT_UINT8, BASE_DEC, VALS(s5066_13_reason), 0x0, NULL, HFILL }
1216 { &hf_s5066_13_link_type,
1217 { "Hardlink type", "s5066sis.13.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
1219 { &hf_s5066_13_link_priority,
1220 { "Priority", "s5066sis.13.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1222 { &hf_s5066_13_sapid,
1223 { "Remote Sap ID", "s5066sis.13.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1225 /* Type 14: S_SUBNET_AVAILABILITY */
1226 { &hf_s5066_14_status,
1227 { "Status", "s5066sis.14.status", FT_UINT8, BASE_DEC, VALS(s5066_14_status), 0x0, NULL, HFILL }
1229 { &hf_s5066_14_reason,
1230 { "Reason", "s5066sis.14.reason", FT_UINT8, BASE_DEC, VALS(s5066_14_reason), 0x0, NULL, HFILL }
1232 /* Type 15: S_DATAFLOW_ON */
1233 /* --- no subfields --- */
1234 /* Type 16: S_DATAFLOW_OFF */
1235 /* --- no subfields --- */
1236 /* Type 17: S_KEEP_ALIVE */
1237 /* --- no subfields --- */
1238 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
1239 { &hf_s5066_18_type,
1240 { "Message Type", "s5066sis.18.type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1242 { &hf_s5066_18_body,
1243 { "Message Body", "s5066sis.18.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1245 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
1246 { &hf_s5066_19_type,
1247 { "Message Type", "s5066sis.19.type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1249 { &hf_s5066_19_body,
1250 { "Message Body", "s5066sis.19.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1252 /* Type 20: S_UNIDATA_REQUEST */
1253 { &hf_s5066_20_priority,
1254 { "Priority", "s5066sis.20.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1256 { &hf_s5066_20_sapid,
1257 { "Destination Sap ID", "s5066sis.20.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1259 { &hf_s5066_20_ttl,
1260 { "Time-To-Live (x2 seconds)", "s5066sis.20.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL }
1262 { &hf_s5066_20_size,
1263 { "U_PDU Size", "s5066sis.20.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1265 /* Type 21: S_UNIDATA_INDICATION */
1266 { &hf_s5066_21_priority,
1267 { "Priority", "s5066sis.21.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1269 { &hf_s5066_21_dest_sapid,
1270 { "Destination Sap ID", "s5066sis.21.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1272 { &hf_s5066_21_tx_mode,
1273 { "Transmission Mode", "s5066sis.21.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
1275 { &hf_s5066_21_src_sapid,
1276 { "Source Sap ID", "s5066sis.21.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1278 { &hf_s5066_21_size,
1279 { "U_PDU Size", "s5066sis.21.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1281 { &hf_s5066_21_err_blocks,
1282 { "Number of errored blocks", "s5066sis.21.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1284 { &hf_s5066_21_err_ptr,
1285 { "Pointer to error block", "s5066sis.21.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1287 { &hf_s5066_21_err_size,
1288 { "Size of error block", "s5066sis.21.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1290 { &hf_s5066_21_nrx_blocks,
1291 { "Number of non-received blocks", "s5066sis.21.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1293 { &hf_s5066_21_nrx_ptr,
1294 { "Pointer to non-received block", "s5066sis.21.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1296 { &hf_s5066_21_nrx_size,
1297 { "Size of non-received block", "s5066sis.21.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1299 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
1300 { &hf_s5066_22_unused,
1301 { "(Unused)", "s5066sis.22.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1303 { &hf_s5066_22_sapid,
1304 { "Destination Sap ID", "s5066sis.22.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1306 { &hf_s5066_22_size,
1307 { "U_PDU Size", "s5066sis.22.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1309 { &hf_s5066_22_data,
1310 { "(Part of) Confirmed data", "s5066sis.22.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1312 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
1313 { &hf_s5066_23_reason,
1314 { "Reason", "s5066sis.23.reason", FT_UINT8, BASE_DEC, VALS(s5066_23_reason), 0xF0, NULL, HFILL }
1316 { &hf_s5066_23_sapid,
1317 { "Destination Sap ID", "s5066sis.23.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1319 { &hf_s5066_23_size,
1320 { "U_PDU Size", "s5066sis.23.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1322 { &hf_s5066_23_data,
1323 { "(Part of) Rejected data", "s5066sis.23.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1325 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
1326 { &hf_s5066_24_unused,
1327 { "(Unused)", "s5066sis.24.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1329 { &hf_s5066_24_sapid,
1330 { "Destination Sap ID", "s5066sis.24.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1332 { &hf_s5066_24_ttl,
1333 { "Time-To-Live (x2 seconds)", "s5066sis.24.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL }
1335 { &hf_s5066_24_size,
1336 { "U_PDU Size", "s5066sis.24.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1338 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
1339 { &hf_s5066_25_unused,
1340 { "(Unused)", "s5066sis.25.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1342 { &hf_s5066_25_dest_sapid,
1343 { "Destination Sap ID", "s5066sis.25.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1345 { &hf_s5066_25_tx_mode,
1346 { "Transmission Mode", "s5066sis.25.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
1348 { &hf_s5066_25_src_sapid,
1349 { "Source Sap ID", "s5066sis.25.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1351 { &hf_s5066_25_size,
1352 { "U_PDU Size", "s5066sis.25.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1354 { &hf_s5066_25_err_blocks,
1355 { "Number of errored blocks", "s5066sis.25.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1357 { &hf_s5066_25_err_ptr,
1358 { "Pointer to error block", "s5066sis.25.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1360 { &hf_s5066_25_err_size,
1361 { "Size of error block", "s5066sis.25.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1363 { &hf_s5066_25_nrx_blocks,
1364 { "Number of non-received blocks", "s5066sis.25.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1366 { &hf_s5066_25_nrx_ptr,
1367 { "Pointer to non-received block", "s5066sis.25.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1369 { &hf_s5066_25_nrx_size,
1370 { "Size of non-received block", "s5066sis.25.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1372 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
1373 { &hf_s5066_26_unused,
1374 { "(Unused)", "s5066sis.26.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1376 { &hf_s5066_26_sapid,
1377 { "Destination Sap ID", "s5066sis.26.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1379 { &hf_s5066_26_size,
1380 { "U_PDU Size", "s5066sis.26.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1382 { &hf_s5066_26_data,
1383 { "(Part of) Confirmed data", "s5066sis.26.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1385 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
1386 { &hf_s5066_27_reason,
1387 { "Reason", "s5066sis.27.reason", FT_UINT8, BASE_DEC, VALS(s5066_27_reason), 0xF0, NULL, HFILL }
1389 { &hf_s5066_27_sapid,
1390 { "Destination Sap ID", "s5066sis.27.sapid", FT_UINT8, BASE_DEC, VALS(s5066_sapid_assignments), 0x0F, NULL, HFILL }
1393 { &hf_s5066_27_size,
1394 { "U_PDU Size", "s5066sis.27.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1396 { &hf_s5066_27_data,
1397 { "(Part of) Rejected data", "s5066sis.27.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1402 /* Setup protocol subtree array */
1403 static int *ett[] = {
1404 &ett_s5066,
1405 &ett_s5066_pdu,
1406 &ett_s5066_servicetype,
1407 &ett_s5066_address,
1408 &ett_s5066_client_transport_header,
1411 module_t *s5066_module;
1413 proto_s5066 = proto_register_protocol ("STANAG 5066 (SIS layer)", "STANAG 5066 SIS", "s5066sis");
1414 proto_register_field_array(proto_s5066, hf, array_length(hf));
1415 proto_register_subtree_array(ett, array_length(ett));
1417 s5066_tcp_handle = register_dissector("s5066sis", dissect_s5066_tcp, proto_s5066);
1419 s5066_module = prefs_register_protocol(proto_s5066, proto_reg_handoff_s5066);
1420 prefs_register_bool_preference(s5066_module, "desegment_pdus",
1421 "Reassemble S5066 SIS PDUs spanning multiple TCP segments",
1422 "Whether the S5066 SIS dissector should reassemble PDUs spanning multiple TCP segments."
1423 " The default is to use reassembly.",
1424 &s5066_desegment);
1425 prefs_register_bool_preference(s5066_module, "edition_one",
1426 "Dissect edition 1.0 of STANAG 5066",
1427 "Whether the S5066 SIS dissector should dissect this edition of the STANAG."
1428 " This edition was never formally approved and is very rare. The common edition is edition 1.2.",
1429 &s5066_edition_one);
1431 s5066sis_dissector_table = register_dissector_table("s5066sis.ctl.appid", "STANAG 5066 Application Identifier", proto_s5066, FT_UINT16, BASE_DEC);
1435 void
1436 proto_reg_handoff_s5066(void)
1438 static bool Initialized = false;
1440 if (!Initialized) {
1441 dissector_add_uint_with_preference("tcp.port", S5066_PORT, s5066_tcp_handle);
1442 Initialized = true;
1445 if (!s5066_edition_one) {
1446 s5066_header_size = 5;
1447 s5066_size_offset = 3;
1448 } else {
1449 s5066_header_size = 4;
1450 s5066_size_offset = 2;
1455 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1457 * Local variables:
1458 * c-basic-offset: 8
1459 * tab-width: 8
1460 * indent-tabs-mode: t
1461 * End:
1463 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1464 * :indentSize=8:tabSize=8:noTabs=false: