2 * Routines to dissect STANAG 5066 Subnetwork Interface Sublayer (SIS)
3 * packets, as described in Annex A of STANAG 5066.
7 * Copyright (c) 2005 by Menno Andriesse <s5066 [AT] nc3a.nato.int>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1999 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33 #include <epan/dissectors/packet-tcp.h> /* For tcp_dissect_pdus() */
35 /* Forward reference */
36 /* Register functions */
37 void proto_reg_handoff_s5066(void);
39 static int dissect_s5066_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
);
40 static guint
get_s5066_pdu_len(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
);
41 static int dissect_s5066_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
);
42 /* Service type and address dissectors */
43 static guint
dissect_s5066_servicetype(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
44 static guint
dissect_s5066_address(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
, gint source
);
45 /* S-Primitive dissectors */
46 static guint
dissect_s5066_01(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
47 /* static guint dissect_s5066_02(tvbuff_t *tvb, guint offset, proto_tree *tree); */
48 static guint
dissect_s5066_03(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
49 static guint
dissect_s5066_04(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
50 static guint
dissect_s5066_05(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
51 static guint
dissect_s5066_06(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
52 static guint
dissect_s5066_07(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
53 static guint
dissect_s5066_08(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
54 static guint
dissect_s5066_09(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
55 static guint
dissect_s5066_10(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
56 static guint
dissect_s5066_11(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
57 static guint
dissect_s5066_12(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
58 static guint
dissect_s5066_13(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
59 static guint
dissect_s5066_14(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
60 /* static guint dissect_s5066_15(tvbuff_t *tvb, guint offset, proto_tree *tree); */
61 /* static guint dissect_s5066_16(tvbuff_t *tvb, guint offset, proto_tree *tree); */
62 /* static guint dissect_s5066_17(tvbuff_t *tvb, guint offset, proto_tree *tree); */
63 static guint
dissect_s5066_18(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
, guint pdu_size
);
64 static guint
dissect_s5066_19(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
, guint pdu_size
);
65 static guint
dissect_s5066_20(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
66 static guint
dissect_s5066_21(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
, guint pdu_size
);
67 static guint
dissect_s5066_22(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
68 static guint
dissect_s5066_23(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
69 static guint
dissect_s5066_24(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
70 static guint
dissect_s5066_25(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
, guint pdu_size
);
71 static guint
dissect_s5066_26(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
72 static guint
dissect_s5066_27(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
);
74 static gint proto_s5066
= -1;
75 static dissector_handle_t data_handle
;
77 /* Enable desegmentation of S5066 over TCP */
78 static gboolean s5066_desegment
= TRUE
;
79 /* Dissect old 'edition 1' of STANAG 5066 (It lacks the 'version' field.) */
80 static gboolean s5066_edition_one
= FALSE
;
81 /* This port is registered with IANA */
82 static guint global_s5066_port
= 5066;
83 /* Size of header outside 'size' field */
84 static gint s5066_header_size
= 5;
85 /* Offset of 'size' field */
86 static gint s5066_size_offset
= 3;
88 /* Sync should be 0x90EB */
89 static gint hf_s5066_sync_word
= -1;
90 /* Version should be 0x00 */
91 static gint hf_s5066_version
= -1;
92 /* Total size of the PDU, excluding this size and previous fields */
93 /* So total size is this + 5 bytes (s5066_header_size) */
94 static gint hf_s5066_size
= -1;
96 static gint hf_s5066_type
= -1;
97 static const value_string s5066_pdu_type
[] = {
98 { 1, "S_BIND_REQUEST"},
99 { 2, "S_UNBIND_REQUEST"},
100 { 3, "S_BIND_ACCEPTED"},
101 { 4, "S_BIND_REJECTED"},
102 { 5, "S_UNBIND_INDICATION"},
103 { 6, "S_HARD_LINK_ESTABLISH"},
104 { 7, "S_HARD_LINK_TERMINATE"},
105 { 8, "S_HARD_LINK_ESTABLISHED"},
106 { 9, "S_HARD_LINK_REJECTED"},
107 {10, "S_HARD_LINK_TERMINATED"},
108 {11, "S_HARD_LINK_INDICATION"},
109 {12, "S_HARD_LINK_ACCEPT"},
110 {13, "S_HARD_LINK_REJECT"},
111 {14, "S_SUBNET_AVAILABILITY"},
112 {15, "S_DATAFLOW_ON"},
113 {16, "S_DATAFLOW_OFF"},
114 {17, "S_KEEP_ALIVE"},
115 {18, "S_MANAGEMENT_MESSAGE_REQUEST"},
116 {19, "S_MANAGEMENT_MESSAGE_INDICATION"},
117 {20, "S_UNIDATA_REQUEST"},
118 {21, "S_UNIDATA_INDICATION"},
119 {22, "S_UNIDATA_REQUEST_CONFIRM"},
120 {23, "S_UNIDATA_REQUEST_REJECTED"},
121 {24, "S_EXPEDITED_UNIDATA_REQUEST"},
122 {25, "S_EXPEDITED_UNIDATA_INDICATION"},
123 {26, "S_EXPEDITED_UNIDATA_REQUEST_CONFIRM"},
124 {27, "S_EXPEDITED_UNIDATA_REQUEST_REJECTED"},
128 /* STANAG 5066 Address */
129 /* Size is defined in nibbles (4 bits) */
130 static gint hf_s5066_ad_size
= -1;
131 /* Group flag: 0 = false, 1 = true */
132 static gint hf_s5066_ad_group
= -1;
133 /* The remainder of the 4 bytes form the address */
134 static gint hf_s5066_ad_address
= -1;
137 /* Transmission mode: */
138 static gint hf_s5066_st_txmode
= -1;
139 static const value_string s5066_st_txmode
[] = {
140 { 0, "Ignore service type field"},
142 { 2, "Non-ARQ (Broadcast)"},
143 { 3, "Non-ARQ (with errors)"},
144 { 4, "Other non-ARQ types"},
145 { 5, "Other non-ARQ types"},
146 { 6, "Other non-ARQ types"},
147 { 7, "Other non-ARQ types"},
148 { 8, "Other non-ARQ types"},
149 { 9, "Other non-ARQ types"},
150 {10, "Other non-ARQ types"},
151 {11, "Other non-ARQ types"},
152 {12, "Other non-ARQ types"},
153 {13, "Other non-ARQ types"},
154 {14, "Other non-ARQ types"},
155 {15, "Other non-ARQ types"},
158 /* Delivery confirmation: */
159 static gint hf_s5066_st_delivery_confirmation
= -1;
160 static const value_string s5066_st_delivery_confirmation
[] = {
161 { 0, "No confirmation"},
162 { 1, "Node delivery confirmation"},
163 { 2, "Client delivery confirmation"},
164 { 3, "-- Not defined --"},
167 /* Delivery order: */
168 static gint hf_s5066_st_delivery_order
= -1;
169 static const value_string s5066_st_delivery_order
[] = {
170 { 0, "In-order delivery"},
171 { 1, "As-they-arrive"},
174 /* Extended field present: (Never in the current version.) */
175 static gint hf_s5066_st_extended
= -1;
176 static const value_string s5066_st_extended
[] = {
177 { 0, "No extended field"},
178 { 1, "Extended field follows"},
181 /* Number of retransmissions when in Non-ARQ: */
182 static gint hf_s5066_st_retries
= -1;
184 /* Type 1: S_BIND_REQUEST */
185 static gint hf_s5066_01_sapid
= -1;
186 static gint hf_s5066_01_rank
= -1;
187 static gint hf_s5066_01_unused
= -1;
189 /* Type 2: S_UNBIND_REQUEST */
190 /* --- no subfields --- */
192 /* Type 3: S_BIND_ACCEPTED */
193 static gint hf_s5066_03_sapid
= -1;
194 static gint hf_s5066_03_unused
= -1;
195 static gint hf_s5066_03_mtu
= -1;
197 /* Type 4: S_BIND_REJECTED */
198 static gint hf_s5066_04_reason
= -1;
199 static const value_string s5066_04_reason
[] = {
200 { 0, "Unknown reason"},
201 { 1, "Not enough resources"},
202 { 2, "Invalid Sap ID"},
203 { 3, "Sap ID already allocated"},
204 { 4, "ARQ mode unsupportable during broadcast session"},
208 /* Type 5: S_UNBIND_INDICATION */
209 static gint hf_s5066_05_reason
= -1;
210 static const value_string s5066_05_reason
[] = {
211 { 0, "Unknown reason"},
212 { 1, "Connection pre-empted by higher ranking client"},
213 { 2, "Inactivity (failure to respond to 'Keep-alive')"},
214 { 3, "Too many invalid primitives"},
215 { 4, "Too many expedited data request primitives"},
216 { 5, "ARQ mode unsupportable during broadcast session"},
220 /* Hard links: hardlinktype value string array. */
221 static const value_string s5066_hard_link_type
[] = {
222 { 0, "Link reservation"},
223 { 1, "Partial Bandwidth reservation"},
224 { 2, "Full Bandwidth reservation"},
225 { 3, "--- undefined ---"},
229 /* Type 6: S_HARD_LINK_ESTABLISH */
230 static gint hf_s5066_06_link_type
= -1;
231 static gint hf_s5066_06_link_priority
= -1;
232 static gint hf_s5066_06_sapid
= -1;
234 /* Type 7: S_HARD_LINK_TERMINATE */
235 /* Only remote node address */
237 /* Type 8: S_HARD_LINK_ESTABLISHED */
238 static gint hf_s5066_08_remote_status
= -1;
239 static const value_string s5066_08_remote_status
[] = {
244 static gint hf_s5066_08_link_type
= -1;
245 static gint hf_s5066_08_link_priority
= -1;
246 static gint hf_s5066_08_sapid
= -1;
248 /* Type 9: S_HARD_LINK_REJECTED */
249 static gint hf_s5066_09_reason
= -1;
250 static const value_string s5066_09_reason
[] = {
251 { 0, "--- undefined ---"},
252 { 1, "Remote node busy"},
253 { 2, "Higher priority link exists"},
254 { 3, "Remote node not responding"},
255 { 4, "Destination Sap ID not bound"},
256 { 5, "Requested Type-0 link exists"},
259 static gint hf_s5066_09_link_type
= -1;
260 static gint hf_s5066_09_link_priority
= -1;
261 static gint hf_s5066_09_sapid
= -1;
263 /* Type 10: S_HARD_LINK_TERMINATED */
264 static gint hf_s5066_10_reason
= -1;
265 static const value_string s5066_10_reason
[] = {
266 { 0, "--- undefined ---"},
267 { 1, "Link terminated by remote node"},
268 { 2, "Higher priority link requested"},
269 { 3, "Remote node not responding"},
270 { 4, "Destination Sap ID not bound"},
271 { 5, "Physical link broken"},
274 static gint hf_s5066_10_link_type
= -1;
275 static gint hf_s5066_10_link_priority
= -1;
276 static gint hf_s5066_10_sapid
= -1;
278 /* Type 11: S_HARD_LINK_INDICATION */
279 static gint hf_s5066_11_remote_status
= -1;
280 static const value_string s5066_11_remote_status
[] = {
285 static gint hf_s5066_11_link_type
= -1;
286 static gint hf_s5066_11_link_priority
= -1;
287 static gint hf_s5066_11_sapid
= -1;
289 /* Type 12: S_HARD_LINK_ACCEPT */
290 static gint hf_s5066_12_link_type
= -1;
291 static gint hf_s5066_12_link_priority
= -1;
292 static gint hf_s5066_12_sapid
= -1;
294 /* Type 13: S_HARD_LINK_REJECT */
295 static gint hf_s5066_13_reason
= -1;
296 static const value_string s5066_13_reason
[] = {
297 { 0, "--- undefined ---"},
300 static gint hf_s5066_13_link_type
= -1;
301 static gint hf_s5066_13_link_priority
= -1;
302 static gint hf_s5066_13_sapid
= -1;
304 /* Type 14: S_SUBNET_AVAILABILITY */
305 static gint hf_s5066_14_status
= -1;
306 static const value_string s5066_14_status
[] = {
309 { 2, "Receive only"},
314 static gint hf_s5066_14_reason
= -1;
315 static const value_string s5066_14_reason
[] = {
316 { 0, "Unknown reason"},
317 { 1, "Local node in EMCON"},
318 { 2, "Higher priority link requested"},
322 /* Type 15: S_DATAFLOW_ON */
323 /* --- no subfields --- */
325 /* Type 16: S_DATAFLOW_OFF */
326 /* --- no subfields --- */
328 /* Type 17: S_KEEP_ALIVE */
329 /* --- no subfields --- */
331 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
332 static gint hf_s5066_18_type
= -1;
333 static gint hf_s5066_18_body
= -1;
335 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
336 static gint hf_s5066_19_type
= -1;
337 static gint hf_s5066_19_body
= -1;
339 /* Type 20: S_UNIDATA_REQUEST */
340 static gint hf_s5066_20_priority
= -1;
341 static gint hf_s5066_20_sapid
= -1;
342 static gint hf_s5066_20_ttl
= -1;
343 static gint hf_s5066_20_size
= -1;
345 /* Type 21: S_UNIDATA_INDICATION */
346 static gint hf_s5066_21_priority
= -1;
347 static gint hf_s5066_21_dest_sapid
= -1;
348 static gint hf_s5066_21_tx_mode
= -1;
349 static gint hf_s5066_21_src_sapid
= -1;
350 static gint hf_s5066_21_size
= -1;
351 static gint hf_s5066_21_err_blocks
= -1;
352 static gint hf_s5066_21_err_ptr
= -1;
353 static gint hf_s5066_21_err_size
= -1;
354 static gint hf_s5066_21_nrx_blocks
= -1;
355 static gint hf_s5066_21_nrx_ptr
= -1;
356 static gint hf_s5066_21_nrx_size
= -1;
359 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
360 static gint hf_s5066_22_unused
= -1;
361 static gint hf_s5066_22_sapid
= -1;
362 static gint hf_s5066_22_size
= -1;
363 static gint hf_s5066_22_data
= -1;
365 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
366 static gint hf_s5066_23_reason
= -1;
367 static const value_string s5066_23_reason
[] = {
368 { 0, "Unknown reason"},
369 { 1, "Time-To-Live expired"},
370 { 2, "Destination SapID not bound"},
371 { 3, "Destination node not responding"},
372 { 4, "U_PDU larger than MTU"},
373 { 5, "Transmission Mode not specified"},
376 static gint hf_s5066_23_sapid
= -1;
377 static gint hf_s5066_23_size
= -1;
378 static gint hf_s5066_23_data
= -1;
380 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
381 static gint hf_s5066_24_unused
= -1;
382 static gint hf_s5066_24_sapid
= -1;
383 static gint hf_s5066_24_ttl
= -1;
384 static gint hf_s5066_24_size
= -1;
386 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
387 static gint hf_s5066_25_unused
= -1;
388 static gint hf_s5066_25_dest_sapid
= -1;
389 static gint hf_s5066_25_tx_mode
= -1;
390 static gint hf_s5066_25_src_sapid
= -1;
391 static gint hf_s5066_25_size
= -1;
392 static gint hf_s5066_25_err_blocks
= -1;
393 static gint hf_s5066_25_err_ptr
= -1;
394 static gint hf_s5066_25_err_size
= -1;
395 static gint hf_s5066_25_nrx_blocks
= -1;
396 static gint hf_s5066_25_nrx_ptr
= -1;
397 static gint hf_s5066_25_nrx_size
= -1;
399 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
400 static gint hf_s5066_26_unused
= -1;
401 static gint hf_s5066_26_sapid
= -1;
402 static gint hf_s5066_26_size
= -1;
403 static gint hf_s5066_26_data
= -1;
405 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
406 static gint hf_s5066_27_reason
= -1;
407 static const value_string s5066_27_reason
[] = {
408 { 0, "Unknown reason"},
409 { 1, "Time-To-Live expired"},
410 { 2, "Destination SapID not bound"},
411 { 3, "Destination node not responding"},
412 { 4, "U_PDU larger than MTU"},
413 { 5, "Transmission Mode not specified"},
416 static gint hf_s5066_27_sapid
= -1;
417 static gint hf_s5066_27_size
= -1;
418 static gint hf_s5066_27_data
= -1;
421 static gint ett_s5066
= -1;
422 static gint ett_s5066_pdu
= -1;
423 static gint ett_s5066_servicetype
= -1;
424 static gint ett_s5066_address
= -1;
427 proto_register_s5066(void)
429 static hf_register_info hf
[] = {
430 { &hf_s5066_sync_word
,
431 { "Sync preamble", "s5066sis.sync", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
434 { "S5066 version", "s5066sis.version", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
437 { "S_Primitive size", "s5066sis.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
440 { "PDU Type", "s5066sis.type", FT_UINT8
, BASE_DEC
, VALS(s5066_pdu_type
), 0x0, NULL
, HFILL
}
442 /* STANAG 5066 Address */
444 { "Address size (1/2 Bytes)", "s5066sis.address.size", FT_UINT8
, BASE_HEX
, NULL
, 0xE0, NULL
, HFILL
}
446 { &hf_s5066_ad_group
,
447 { "Group address", "s5066sis.address.group", FT_UINT8
, BASE_HEX
, NULL
, 0x10, NULL
, HFILL
}
449 { &hf_s5066_ad_address
,
450 { "Address", "s5066sis.address.address", FT_IPv4
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
453 { &hf_s5066_st_txmode
,
454 { "Transmission mode", "s5066sis.st.txmode", FT_UINT8
, BASE_HEX
, VALS(s5066_st_txmode
), 0xF0, NULL
, HFILL
}
456 { &hf_s5066_st_delivery_confirmation
,
457 { "Delivery confirmation", "s5066sis.st.confirm", FT_UINT8
, BASE_HEX
, VALS(s5066_st_delivery_confirmation
), 0x0C, NULL
, HFILL
}
459 { &hf_s5066_st_delivery_order
,
460 { "Delivery order", "s5066sis.st.order", FT_UINT8
, BASE_HEX
, VALS(s5066_st_delivery_order
), 0x02, NULL
, HFILL
}
462 { &hf_s5066_st_extended
,
463 { "Extended field", "s5066sis.st.extended", FT_UINT8
, BASE_HEX
, VALS(s5066_st_extended
), 0x01, NULL
, HFILL
}
465 { &hf_s5066_st_retries
,
466 { "Minimum number of retransmissions", "s5066sis.st.retries", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
468 /* PDU Type 01: S_BIND_REQUEST */
469 { &hf_s5066_01_sapid
,
470 { "Sap ID", "s5066sis.01.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
473 { "Rank", "s5066sis.01.rank", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
475 { &hf_s5066_01_unused
,
476 { "(Unused)", "s5066sis.01.unused", FT_UINT8
, BASE_HEX
, NULL
, 0x0F, NULL
, HFILL
}
478 /* PDU Type 02: S_UNBIND_REQUEST */
479 /* --- no subfields --- */
480 /* PDU Type 03: S_BIND_ACCEPTED */
481 { &hf_s5066_03_sapid
,
482 { "Sap ID", "s5066sis.03.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
484 { &hf_s5066_03_unused
,
485 { "(Unused)", "s5066sis.03.unused", FT_UINT8
, BASE_HEX
, NULL
, 0x0F, NULL
, HFILL
}
488 { "MTU", "s5066sis.03.mtu", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
490 /* PDU Type 04: S_BIND_REJECTED */
491 { &hf_s5066_04_reason
,
492 { "Reason", "s5066sis.04.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_04_reason
), 0x0, NULL
, HFILL
}
494 /* PDU Type 05: S_UNBIND_INDICATION */
495 { &hf_s5066_05_reason
,
496 { "Reason", "s5066sis.05.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_05_reason
), 0x0, NULL
, HFILL
}
498 /* Type 6: S_HARD_LINK_ESTABLISH */
499 { &hf_s5066_06_link_type
,
500 { "Hardlink type", "s5066sis.06.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
502 { &hf_s5066_06_link_priority
,
503 { "Priority", "s5066sis.06.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
505 { &hf_s5066_06_sapid
,
506 { "Remote Sap ID", "s5066sis.06.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
508 /* Type 7: S_HARD_LINK_TERMINATE */
509 /* --- Only remote node address --- */
510 /* Type 8: S_HARD_LINK_ESTABLISHED */
511 { &hf_s5066_08_remote_status
,
512 { "Remote node status", "s5066sis.08.status", FT_UINT8
, BASE_DEC
, VALS(s5066_08_remote_status
), 0x0, NULL
, HFILL
}
514 { &hf_s5066_08_link_type
,
515 { "Hardlink type", "s5066sis.08.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
517 { &hf_s5066_08_link_priority
,
518 { "Priority", "s5066sis.08.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
520 { &hf_s5066_08_sapid
,
521 { "Remote Sap ID", "s5066sis.08.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
523 /* Type 9: S_HARD_LINK_REJECTED */
524 { &hf_s5066_09_reason
,
525 { "Reason", "s5066sis.09.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_09_reason
), 0x0, NULL
, HFILL
}
527 { &hf_s5066_09_link_type
,
528 { "Hardlink type", "s5066sis.09.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
530 { &hf_s5066_09_link_priority
,
531 { "Priority", "s5066sis.09.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
533 { &hf_s5066_09_sapid
,
534 { "Remote Sap ID", "s5066sis.09.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
536 /* Type 10: S_HARD_LINK_TERMINATED */
537 { &hf_s5066_10_reason
,
538 { "Reason", "s5066sis.10.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_10_reason
), 0x0, NULL
, HFILL
}
540 { &hf_s5066_10_link_type
,
541 { "Hardlink type", "s5066sis.10.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
543 { &hf_s5066_10_link_priority
,
544 { "Priority", "s5066sis.10.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
546 { &hf_s5066_10_sapid
,
547 { "Remote Sap ID", "s5066sis.10.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
549 /* Type 11: S_HARD_LINK_INDICATION */
550 { &hf_s5066_11_remote_status
,
551 { "Remote node status", "s5066sis.11.status", FT_UINT8
, BASE_DEC
, VALS(s5066_11_remote_status
), 0x0, NULL
, HFILL
}
553 { &hf_s5066_11_link_type
,
554 { "Hardlink type", "s5066sis.11.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
556 { &hf_s5066_11_link_priority
,
557 { "Priority", "s5066sis.11.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
559 { &hf_s5066_11_sapid
,
560 { "Remote Sap ID", "s5066sis.11.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
562 /* Type 12: S_HARD_LINK_ACCEPT */
563 { &hf_s5066_12_link_type
,
564 { "Hardlink type", "s5066sis.12.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
566 { &hf_s5066_12_link_priority
,
567 { "Priority", "s5066sis.12.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
569 { &hf_s5066_12_sapid
,
570 { "Remote Sap ID", "s5066sis.12.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
572 /* Type 13: S_HARD_LINK_REJECT */
573 { &hf_s5066_13_reason
,
574 { "Reason", "s5066sis.13.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_13_reason
), 0x0, NULL
, HFILL
}
576 { &hf_s5066_13_link_type
,
577 { "Hardlink type", "s5066sis.13.type", FT_UINT8
, BASE_DEC
, VALS(s5066_hard_link_type
), 0xC0, NULL
, HFILL
}
579 { &hf_s5066_13_link_priority
,
580 { "Priority", "s5066sis.13.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x30, NULL
, HFILL
}
582 { &hf_s5066_13_sapid
,
583 { "Remote Sap ID", "s5066sis.13.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
585 /* Type 14: S_SUBNET_AVAILABILITY */
586 { &hf_s5066_14_status
,
587 { "Status", "s5066sis.14.status", FT_UINT8
, BASE_DEC
, VALS(s5066_14_status
), 0x0, NULL
, HFILL
}
589 { &hf_s5066_14_reason
,
590 { "Reason", "s5066sis.14.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_14_reason
), 0x0, NULL
, HFILL
}
592 /* Type 15: S_DATAFLOW_ON */
593 /* --- no subfields --- */
594 /* Type 16: S_DATAFLOW_OFF */
595 /* --- no subfields --- */
596 /* Type 17: S_KEEP_ALIVE */
597 /* --- no subfields --- */
598 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
600 { "Message Type", "s5066sis.18.type", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
603 { "Message Body", "s5066sis.18.body", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
605 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
607 { "Message Type", "s5066sis.19.type", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
610 { "Message Body", "s5066sis.19.body", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
612 /* Type 20: S_UNIDATA_REQUEST */
613 { &hf_s5066_20_priority
,
614 { "Priority", "s5066sis.20.priority", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
616 { &hf_s5066_20_sapid
,
617 { "Destination Sap ID", "s5066sis.20.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
620 { "Time-To-Live (x2 seconds)", "s5066sis.20.ttl", FT_UINT24
, BASE_DEC
, NULL
, 0x0FFFFF, NULL
, HFILL
}
623 { "U_PDU Size", "s5066sis.20.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
625 /* Type 21: S_UNIDATA_INDICATION */
626 { &hf_s5066_21_priority
,
627 { "Priority", "s5066sis.21.priority", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
629 { &hf_s5066_21_dest_sapid
,
630 { "Destination Sap ID", "s5066sis.21.dest_sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
632 { &hf_s5066_21_tx_mode
,
633 { "Transmission Mode", "s5066sis.21.txmode", FT_UINT8
, BASE_HEX
, VALS(s5066_st_txmode
), 0xF0, NULL
, HFILL
}
635 { &hf_s5066_21_src_sapid
,
636 { "Source Sap ID", "s5066sis.21.src_sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
639 { "U_PDU Size", "s5066sis.21.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
641 { &hf_s5066_21_err_blocks
,
642 { "Number of errored blocks", "s5066sis.21.err_blocks", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
644 { &hf_s5066_21_err_ptr
,
645 { "Pointer to error block", "s5066sis.21.err_ptr", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
647 { &hf_s5066_21_err_size
,
648 { "Size of error block", "s5066sis.21.err_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
650 { &hf_s5066_21_nrx_blocks
,
651 { "Number of non-received blocks", "s5066sis.21.nrx_blocks", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
653 { &hf_s5066_21_nrx_ptr
,
654 { "Pointer to non-received block", "s5066sis.21.nrx_ptr", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
656 { &hf_s5066_21_nrx_size
,
657 { "Size of non-received block", "s5066sis.21.nrx_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
659 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
660 { &hf_s5066_22_unused
,
661 { "(Unused)", "s5066sis.22.unused", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
663 { &hf_s5066_22_sapid
,
664 { "Destination Sap ID", "s5066sis.22.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
667 { "U_PDU Size", "s5066sis.22.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
670 { "(Part of) Confirmed data", "s5066sis.22.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
672 /* Type 23: S_UNIDATA_REQUEST_REJECTED */
673 { &hf_s5066_23_reason
,
674 { "Reason", "s5066sis.23.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_23_reason
), 0xF0, NULL
, HFILL
}
676 { &hf_s5066_23_sapid
,
677 { "Destination Sap ID", "s5066sis.23.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
680 { "U_PDU Size", "s5066sis.23.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
683 { "(Part of) Rejected data", "s5066sis.23.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
685 /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
686 { &hf_s5066_24_unused
,
687 { "(Unused)", "s5066sis.24.unused", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
689 { &hf_s5066_24_sapid
,
690 { "Destination Sap ID", "s5066sis.24.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
693 { "Time-To-Live (x2 seconds)", "s5066sis.24.ttl", FT_UINT24
, BASE_DEC
, NULL
, 0x0FFFFF, NULL
, HFILL
}
696 { "U_PDU Size", "s5066sis.24.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
698 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
699 { &hf_s5066_25_unused
,
700 { "(Unused)", "s5066sis.25.unused", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
702 { &hf_s5066_25_dest_sapid
,
703 { "Destination Sap ID", "s5066sis.25.dest_sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
705 { &hf_s5066_25_tx_mode
,
706 { "Transmission Mode", "s5066sis.25.txmode", FT_UINT8
, BASE_HEX
, VALS(s5066_st_txmode
), 0xF0, NULL
, HFILL
}
708 { &hf_s5066_25_src_sapid
,
709 { "Source Sap ID", "s5066sis.25.src_sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
712 { "U_PDU Size", "s5066sis.25.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
714 { &hf_s5066_25_err_blocks
,
715 { "Number of errored blocks", "s5066sis.25.err_blocks", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
717 { &hf_s5066_25_err_ptr
,
718 { "Pointer to error block", "s5066sis.25.err_ptr", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
720 { &hf_s5066_25_err_size
,
721 { "Size of error block", "s5066sis.25.err_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
723 { &hf_s5066_25_nrx_blocks
,
724 { "Number of non-received blocks", "s5066sis.25.nrx_blocks", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
726 { &hf_s5066_25_nrx_ptr
,
727 { "Pointer to non-received block", "s5066sis.25.nrx_ptr", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
729 { &hf_s5066_25_nrx_size
,
730 { "Size of non-received block", "s5066sis.25.nrx_size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
732 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
733 { &hf_s5066_26_unused
,
734 { "(Unused)", "s5066sis.26.unused", FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
736 { &hf_s5066_26_sapid
,
737 { "Destination Sap ID", "s5066sis.26.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
740 { "U_PDU Size", "s5066sis.26.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
743 { "(Part of) Confirmed data", "s5066sis.26.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
745 /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
746 { &hf_s5066_27_reason
,
747 { "Reason", "s5066sis.27.reason", FT_UINT8
, BASE_DEC
, VALS(s5066_27_reason
), 0xF0, NULL
, HFILL
}
749 { &hf_s5066_27_sapid
,
750 { "Destination Sap ID", "s5066sis.27.sapid", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
753 { "U_PDU Size", "s5066sis.27.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
756 { "(Part of) Rejected data", "s5066sis.27.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
761 /* Setup protocol subtree array */
762 static gint
*ett
[] = {
765 &ett_s5066_servicetype
,
769 module_t
*s5066_module
;
771 proto_s5066
= proto_register_protocol (
772 "STANAG 5066 (SIS layer)", /* name */
773 "STANAG 5066 SIS", /* short name*/
774 "s5066sis" /* abbrev */
776 proto_register_field_array(proto_s5066
, hf
, array_length(hf
));
777 proto_register_subtree_array(ett
, array_length(ett
));
779 s5066_module
= prefs_register_protocol(proto_s5066
, proto_reg_handoff_s5066
);
780 prefs_register_bool_preference(s5066_module
, "desegment_pdus",
781 "Reassemble S5066 SIS PDUs spanning multiple TCP segments",
782 "Whether the S5066 SIS dissector should reassemble PDUs spanning multiple TCP segments."
783 " The default is to use reassembly.",
785 prefs_register_bool_preference(s5066_module
, "edition_one",
786 "Dissect edition 1.0 of STANAG 5066",
787 "Whether the S5066 SIS dissector should dissect this edition of the STANAG."
788 " This edition was never formally approved and is very rare. The common edition is edition 1.2.",
790 prefs_register_uint_preference(s5066_module
, "tcp.port",
791 "STANAG 5066 SIS TCP Port",
792 "Set the port for STANAG 5066 SIS. (If other than the default 5066."
793 " This number is registered with IANA.)",
794 10, &global_s5066_port
);
798 proto_reg_handoff_s5066(void)
800 static gboolean Initialized
= FALSE
;
801 static dissector_handle_t s5066_tcp_handle
;
802 static guint saved_s5066_port
;
805 s5066_tcp_handle
= new_create_dissector_handle(dissect_s5066_tcp
, proto_s5066
);
806 data_handle
= find_dissector("data");
809 dissector_delete_uint("tcp.port", saved_s5066_port
, s5066_tcp_handle
);
812 dissector_add_uint("tcp.port", global_s5066_port
, s5066_tcp_handle
);
813 saved_s5066_port
= global_s5066_port
;
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, ENC_BIG_ENDIAN
);
839 proto_tree_add_item(s5066_tree_address
, hf_s5066_ad_group
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
840 addr
= tvb_get_ntohl(tvb
, offset
);
841 addr
= addr
& 0x1FFFFFFF;
842 proto_tree_add_ipv4(s5066_tree_address
, hf_s5066_ad_address
, tvb
, offset
, 4, g_htonl(addr
));
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, ENC_BIG_ENDIAN
);
857 proto_tree_add_item(s5066_tree_servicetype
, hf_s5066_st_delivery_confirmation
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
858 proto_tree_add_item(s5066_tree_servicetype
, hf_s5066_st_delivery_order
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
859 proto_tree_add_item(s5066_tree_servicetype
, hf_s5066_st_extended
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
++;
860 proto_tree_add_item(s5066_tree_servicetype
, hf_s5066_st_retries
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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, ENC_BIG_ENDIAN
);
870 proto_tree_add_item(tree
, hf_s5066_01_rank
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
++;
872 offset
= dissect_s5066_servicetype(tvb
, offset
, tree
);
874 proto_tree_add_item(tree
, hf_s5066_01_unused
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
892 proto_tree_add_item(tree
, hf_s5066_03_unused
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
++;
893 proto_tree_add_item(tree
, hf_s5066_03_mtu
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
918 proto_tree_add_item(tree
, hf_s5066_06_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
919 proto_tree_add_item(tree
, hf_s5066_06_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
937 proto_tree_add_item(tree
, hf_s5066_08_link_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
938 proto_tree_add_item(tree
, hf_s5066_08_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
939 proto_tree_add_item(tree
, hf_s5066_08_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
949 proto_tree_add_item(tree
, hf_s5066_09_link_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
950 proto_tree_add_item(tree
, hf_s5066_09_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
951 proto_tree_add_item(tree
, hf_s5066_09_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
961 proto_tree_add_item(tree
, hf_s5066_10_link_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
962 proto_tree_add_item(tree
, hf_s5066_10_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
963 proto_tree_add_item(tree
, hf_s5066_10_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
973 proto_tree_add_item(tree
, hf_s5066_11_link_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
974 proto_tree_add_item(tree
, hf_s5066_11_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
975 proto_tree_add_item(tree
, hf_s5066_11_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
985 proto_tree_add_item(tree
, hf_s5066_12_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
986 proto_tree_add_item(tree
, hf_s5066_12_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
996 proto_tree_add_item(tree
, hf_s5066_13_link_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
997 proto_tree_add_item(tree
, hf_s5066_13_link_priority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
998 proto_tree_add_item(tree
, hf_s5066_13_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
1008 proto_tree_add_item(tree
, hf_s5066_14_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
++;
1046 body_size
= pdu_size
- offset
;
1047 proto_tree_add_item(tree
, hf_s5066_18_body
, tvb
, offset
, body_size
, ENC_NA
); 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, ENC_BIG_ENDIAN
); offset
++;
1057 body_size
= pdu_size
- offset
;
1058 proto_tree_add_item(tree
, hf_s5066_19_body
, tvb
, offset
, body_size
, ENC_NA
); 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, ENC_BIG_ENDIAN
);
1067 proto_tree_add_item(tree
, hf_s5066_20_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 3;
1071 proto_tree_add_item(tree
, hf_s5066_20_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1089 proto_tree_add_item(tree
, hf_s5066_21_dest_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1099 proto_tree_add_item(tree
, hf_s5066_21_src_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1118 proto_tree_add_item(tree
, hf_s5066_21_err_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1124 proto_tree_add_item(tree
, hf_s5066_21_nrx_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1136 proto_tree_add_item(tree
, hf_s5066_22_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1140 proto_tree_add_item(tree
, hf_s5066_22_data
, tvb
, offset
, pdu_size
, ENC_NA
); 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, ENC_BIG_ENDIAN
);
1151 proto_tree_add_item(tree
, hf_s5066_23_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1155 proto_tree_add_item(tree
, hf_s5066_23_data
, tvb
, offset
, pdu_size
, ENC_NA
); 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, ENC_BIG_ENDIAN
);
1165 proto_tree_add_item(tree
, hf_s5066_24_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 3;
1169 proto_tree_add_item(tree
, hf_s5066_24_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1187 proto_tree_add_item(tree
, hf_s5066_25_dest_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1197 proto_tree_add_item(tree
, hf_s5066_25_src_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1216 proto_tree_add_item(tree
, hf_s5066_25_err_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1222 proto_tree_add_item(tree
, hf_s5066_25_nrx_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
);
1234 proto_tree_add_item(tree
, hf_s5066_26_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1238 proto_tree_add_item(tree
, hf_s5066_26_data
, tvb
, offset
, pdu_size
, ENC_NA
); 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, ENC_BIG_ENDIAN
);
1249 proto_tree_add_item(tree
, hf_s5066_27_sapid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); 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, ENC_BIG_ENDIAN
); offset
+= 2;
1253 proto_tree_add_item(tree
, hf_s5066_27_data
, tvb
, offset
, pdu_size
, ENC_NA
); 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
, void* data
)
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
, data
);
1285 return tvb_length(tvb
);
1289 dissect_s5066_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1293 proto_item
*ti_s5066
= NULL
;
1294 proto_item
*ti_pdu
= NULL
;
1296 gint available_length
= 0;
1297 gint reported_length
= 0;
1299 /* Determine PDU type to display in INFO column */
1300 guint8 pdu_type
= tvb_get_guint8(tvb
, s5066_header_size
);
1302 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "S5066");
1303 /* Clear out stuff in the info column, the add PDU type */
1304 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "PDU type %s", val_to_str(pdu_type
, s5066_pdu_type
, "Unknown (0x%02x)"));
1306 if (tree
) { /* We are being asked for details */
1307 proto_tree
*s5066_tree
= NULL
;
1308 proto_tree
*s5066_tree_pdu
= NULL
;
1310 pdu_size
= tvb_get_ntohs(tvb
, s5066_size_offset
) + s5066_header_size
;
1312 ti_s5066
= proto_tree_add_item(tree
, proto_s5066
, tvb
, 0, -1, ENC_NA
);
1313 proto_item_append_text(ti_s5066
, ", PDU type %s", val_to_str(pdu_type
, s5066_pdu_type
, "Unknown (0x%02x)"));
1314 s5066_tree
= proto_item_add_subtree(ti_s5066
, ett_s5066
);
1315 proto_tree_add_item(s5066_tree
, hf_s5066_sync_word
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); offset
+=2;
1316 if (!s5066_edition_one
) {
1317 proto_tree_add_item(s5066_tree
, hf_s5066_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
++;
1319 proto_tree_add_item(s5066_tree
, hf_s5066_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
); offset
+=2;
1320 ti_pdu
= proto_tree_add_item(s5066_tree
, hf_s5066_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
++;
1321 s5066_tree_pdu
= proto_item_add_subtree(ti_pdu
, ett_s5066_pdu
);
1323 case 1: offset
= dissect_s5066_01(tvb
, offset
, s5066_tree_pdu
); break;
1324 /* case 2: offset = dissect_s5066_02(tvb, offset, s5066_tree_pdu); break; */
1325 case 3: offset
= dissect_s5066_03(tvb
, offset
, s5066_tree_pdu
); break;
1326 case 4: offset
= dissect_s5066_04(tvb
, offset
, s5066_tree_pdu
); break;
1327 case 5: offset
= dissect_s5066_05(tvb
, offset
, s5066_tree_pdu
); break;
1328 case 6: offset
= dissect_s5066_06(tvb
, offset
, s5066_tree_pdu
); break;
1329 case 7: offset
= dissect_s5066_07(tvb
, offset
, s5066_tree_pdu
); break;
1330 case 8: offset
= dissect_s5066_08(tvb
, offset
, s5066_tree_pdu
); break;
1331 case 9: offset
= dissect_s5066_09(tvb
, offset
, s5066_tree_pdu
); break;
1332 case 10: offset
= dissect_s5066_10(tvb
, offset
, s5066_tree_pdu
); break;
1333 case 11: offset
= dissect_s5066_11(tvb
, offset
, s5066_tree_pdu
); break;
1334 case 12: offset
= dissect_s5066_12(tvb
, offset
, s5066_tree_pdu
); break;
1335 case 13: offset
= dissect_s5066_13(tvb
, offset
, s5066_tree_pdu
); break;
1336 case 14: offset
= dissect_s5066_14(tvb
, offset
, s5066_tree_pdu
); break;
1337 /* case 15: offset = dissect_s5066_15(tvb, offset, s5066_tree_pdu); break; */
1338 /* case 16: offset = dissect_s5066_16(tvb, offset, s5066_tree_pdu); break; */
1339 /* case 17: offset = dissect_s5066_17(tvb, offset, s5066_tree_pdu); break; */
1340 case 18: offset
= dissect_s5066_18(tvb
, offset
, s5066_tree_pdu
, pdu_size
); break;
1341 case 19: offset
= dissect_s5066_19(tvb
, offset
, s5066_tree_pdu
, pdu_size
); break;
1342 case 20: offset
= dissect_s5066_20(tvb
, offset
, s5066_tree_pdu
); break;
1343 case 21: offset
= dissect_s5066_21(tvb
, offset
, s5066_tree_pdu
, pdu_size
); break;
1344 case 22: offset
= dissect_s5066_22(tvb
, offset
, s5066_tree_pdu
); break;
1345 case 23: offset
= dissect_s5066_23(tvb
, offset
, s5066_tree_pdu
); break;
1346 case 24: offset
= dissect_s5066_24(tvb
, offset
, s5066_tree_pdu
); break;
1347 case 25: offset
= dissect_s5066_25(tvb
, offset
, s5066_tree_pdu
, pdu_size
); break;
1348 case 26: offset
= dissect_s5066_26(tvb
, offset
, s5066_tree_pdu
); break;
1349 case 27: offset
= dissect_s5066_27(tvb
, offset
, s5066_tree_pdu
); break;
1352 proto_item_set_len(ti_s5066
, offset
);
1354 /* Call sub dissector(s) */
1355 reported_length
= pdu_size
- offset
;
1356 available_length
= tvb_length(tvb
) - offset
;
1358 next_tvb
= tvb_new_subset(tvb
, offset
, MIN(available_length
, reported_length
), reported_length
);
1359 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1361 return tvb_length(tvb
);