/src/wireshark/epan/dissectors/packet-link16.c
Line | Count | Source |
1 | | /* packet-link16.c |
2 | | * Routines for Link 16 message dissection (MIL-STD-6016) |
3 | | * William Robertson <aliask@gmail.com> |
4 | | * Peter Ross <peter.ross@dsto.defence.gov.au> |
5 | | * |
6 | | * http://willrobertson.id.au/resources/wireshark/DSTO-TN-1257.pdf |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | */ |
10 | | |
11 | | #include "config.h" |
12 | | |
13 | | #include <epan/packet.h> |
14 | | #include "packet-link16.h" |
15 | | |
16 | | void proto_register_link16(void); |
17 | | |
18 | | /* Elmasry, G., (2012), Tactical Wireless Communications and Networks: Design Concepts and Challenges, Wiley, ISBN 9781119951766. */ |
19 | | enum { |
20 | | WORDFORMAT_INITIAL = 0, |
21 | | WORDFORMAT_CONTINUATION, |
22 | | WORDFORMAT_EXTENSION |
23 | | }; |
24 | | |
25 | | static const value_string WordFormat_Strings[] = { |
26 | | { WORDFORMAT_INITIAL, "Initial Word" }, |
27 | | { WORDFORMAT_CONTINUATION, "Continuation Word" }, |
28 | | { WORDFORMAT_EXTENSION, "Extension Word" }, |
29 | | { 0, NULL }, |
30 | | }; |
31 | | |
32 | | /* Viasat, Inc., (2012), Link 16 Network Participant Group and Message Card, accessed from <http://www.viasat.com/files/assets/assets/Link16_NPG_Message_Card_100112a.pdf> on 15 April 2013. */ |
33 | | static const value_string Link16_Label_Strings[] = { |
34 | | { 0, "Network Management" }, |
35 | | { 1, "Network Management" }, |
36 | | { 2, "Precise Participant Location and Identification" }, |
37 | | { 3, "Surveillance" }, |
38 | | { 5, "Anti-submarine Warfare" }, |
39 | | { 6, "Intelligence" }, |
40 | | { 7, "Information Management" }, |
41 | | { 8, "Information Management" }, |
42 | | { 9, "Weapons Coordination and Management" }, |
43 | | { 10, "Weapons Coordination and Management" }, |
44 | | { 11, "Weapons Coordination and Management" }, |
45 | | { 12, "Control" }, |
46 | | { 13, "Platform and System Status" }, |
47 | | { 14, "Electronic Warfare" }, |
48 | | { 15, "Threat Warning" }, |
49 | | { 16, "Imagery" }, |
50 | | { 17, "Weather" }, |
51 | | { 28, "National Use" }, |
52 | | { 29, "National Use" }, |
53 | | { 30, "National Use" }, |
54 | | { 31, "Miscellaneous" }, |
55 | | { 0, NULL }, |
56 | | }; |
57 | | |
58 | | /* Viasat, Inc., (2012), Link 16 Network Participant Group and Message Card, accessed from <http://www.viasat.com/files/assets/assets/Link16_NPG_Message_Card_100112a.pdf> on 15 April 2013. */ |
59 | | /* SyntheSys (2021), Link 16 Messages, accessed from <https://resources.synthesys.co.uk/defence/datasheet-link-16-message-table.pdf> on 15 May 2024. */ |
60 | 370 | #define MKPAIR(a, b) (((b) << 5) | (a)) |
61 | | static const value_string Link16_Message_Strings[] = { |
62 | | { MKPAIR(0, 0), "Initial Entry" }, |
63 | | { MKPAIR(0, 1), "Test" }, |
64 | | { MKPAIR(0, 2), "Network Time Update" }, |
65 | | { MKPAIR(0, 3), "Time Slot Assignment" }, |
66 | | { MKPAIR(0, 4), "Radio Relay Control" }, |
67 | | { MKPAIR(0, 5), "Repromulgation Relay" }, |
68 | | { MKPAIR(0, 6), "Communication Control" }, |
69 | | { MKPAIR(0, 7), "Time Slot Reallocation" }, |
70 | | { MKPAIR(1, 0), "Connectivity Interrogation" }, |
71 | | { MKPAIR(1, 1), "Connectivity Status" }, |
72 | | { MKPAIR(1, 2), "Route Establishment" }, |
73 | | { MKPAIR(1, 3), "Acknowledgment" }, |
74 | | { MKPAIR(1, 4), "Communication Status" }, |
75 | | { MKPAIR(1, 5), "Net Control Initialization" }, |
76 | | { MKPAIR(1, 6), "Needline Participation Group Assignment" }, |
77 | | { MKPAIR(1, 7), "Fine Pulse Count Report" }, |
78 | | { MKPAIR(2, 0), "Indirect Interface Unit PPLI" }, |
79 | | { MKPAIR(2, 2), "Air PPLI" }, |
80 | | { MKPAIR(2, 3), "Surface PPLI" }, |
81 | | { MKPAIR(2, 4), "Subsurface PPLI" }, |
82 | | { MKPAIR(2, 5), "Land Point PPLI" }, |
83 | | { MKPAIR(2, 6), "Land Track PPLI" }, |
84 | | { MKPAIR(3, 0), "Reference Point" }, |
85 | | { MKPAIR(3, 1), "Emergency Point" }, |
86 | | { MKPAIR(3, 2), "Air Track" }, |
87 | | { MKPAIR(3, 3), "Surface Track" }, |
88 | | { MKPAIR(3, 4), "Subsurface Track" }, |
89 | | { MKPAIR(3, 5), "Land Point or Track" }, |
90 | | { MKPAIR(3, 6), "Space Track" }, |
91 | | { MKPAIR(3, 7), "Electronic Warfare Product Information" }, |
92 | | { MKPAIR(5, 4), "Acoustic Bearing and Range" }, |
93 | | { MKPAIR(6, 0), "Track/Point Amplification" }, |
94 | | { MKPAIR(6, 1), "Personnel Recovery Amplification" }, |
95 | | { MKPAIR(7, 0), "Track Management" }, |
96 | | { MKPAIR(7, 1), "Data Update Request" }, |
97 | | { MKPAIR(7, 2), "Correlation" }, |
98 | | { MKPAIR(7, 3), "Pointer" }, |
99 | | { MKPAIR(7, 4), "Track Identifier" }, |
100 | | { MKPAIR(7, 5), "IFF/SIF Management" }, |
101 | | { MKPAIR(7, 6), "Filter Management" }, |
102 | | { MKPAIR(7, 7), "Association" }, |
103 | | { MKPAIR(8, 0), "Unit Designator" }, |
104 | | { MKPAIR(8, 1), "Mission Correlator Change" }, |
105 | | { MKPAIR(9, 0), "Command" }, |
106 | | { MKPAIR(9, 1), "Engagement Coordination" }, |
107 | | { MKPAIR(9, 2), "ECCM Coordination" }, |
108 | | { MKPAIR(10, 2), "Engagement Status" }, |
109 | | { MKPAIR(10, 3), "Handover" }, |
110 | | { MKPAIR(10, 5), "Controlling Unit Report" }, |
111 | | { MKPAIR(10, 6), "Pairing" }, |
112 | | { MKPAIR(11, 0), "Weapon Response/Status" }, |
113 | | { MKPAIR(11, 1), "Weapon Directive" }, |
114 | | { MKPAIR(11, 2), "Weapon Coordination" }, |
115 | | { MKPAIR(12, 0), "Mission Assignment" }, |
116 | | { MKPAIR(12, 1), "Vector" }, |
117 | | { MKPAIR(12, 2), "Precision Aircraft Direction" }, |
118 | | { MKPAIR(12, 3), "Flight Path" }, |
119 | | { MKPAIR(12, 4), "Controlling Unit Change" }, |
120 | | { MKPAIR(12, 5), "Target/Track Correlation" }, |
121 | | { MKPAIR(12, 6), "Target Sorting" }, |
122 | | { MKPAIR(12, 7), "Target Bearing" }, |
123 | | { MKPAIR(13, 0), "Airfield Status" }, |
124 | | { MKPAIR(13, 2), "Air Platform and System Status" }, |
125 | | { MKPAIR(13, 3), "Surface Platform and System Status" }, |
126 | | { MKPAIR(13, 4), "Subsurface Platform and System Status" }, |
127 | | { MKPAIR(13, 5), "Land Platform and System Status" }, |
128 | | { MKPAIR(14, 0), "Parametric Information" }, |
129 | | { MKPAIR(14, 2), "Electronic Warfare Control / Coordination" }, |
130 | | { MKPAIR(14, 3), "ECM Management" }, |
131 | | { MKPAIR(15, 0), "Threat Warning" }, |
132 | | { MKPAIR(16, 0), "Imager Transfer" }, |
133 | | { MKPAIR(16, 1), "Route Change" }, |
134 | | { MKPAIR(16, 2), "Global Area Reference System" }, |
135 | | { MKPAIR(17, 0), "Weather Over target" }, |
136 | | { MKPAIR(28, 0), "U.S. National 1 (Army)" }, |
137 | | { MKPAIR(28, 1), "U.S. National 2 (Navy)" }, |
138 | | { MKPAIR(28, 2), "U.S. National 3 (Air Force)" }, |
139 | | { MKPAIR(28, 3), "U.S. National 4 (Marine Corps)" }, |
140 | | { MKPAIR(28, 4), "French National 1" }, |
141 | | { MKPAIR(28, 5), "French National 2" }, |
142 | | { MKPAIR(28, 6), "U.S. National 5 (NSA)" }, |
143 | | { MKPAIR(28, 7), "UK National" }, |
144 | | { MKPAIR(31, 0), "Over-the-Air Rekeying Management" }, |
145 | | { MKPAIR(31, 1), "Over-the-Air Rekeying" }, |
146 | | { MKPAIR(31, 7), "No Statement" }, |
147 | | { 0, NULL }, |
148 | | }; |
149 | | |
150 | | /* Viasat, Inc., (2012), Link 16 Network Participant Group and Message Card, accessed from <http://www.viasat.com/files/assets/assets/Link16_NPG_Message_Card_100112a.pdf> on 15 April 2013. */ |
151 | | /* SyntheSys (2021), Network Participation Groups (NPGs), accessed from <https://resources.synthesys.co.uk/defence/datasheet-network-participation-groups-table.pdf> on 15 May 2024. */ |
152 | | const value_string Link16_NPG_Strings[] = { |
153 | | { 1, "Initial Entry" }, |
154 | | { 2, "RTT-A" }, |
155 | | { 3, "RTT-B" }, |
156 | | { 4, "Network Management" }, |
157 | | { 5, "PPLI and Status A" }, |
158 | | { 6, "PPLI and Status B" }, |
159 | | { 7, "Surveillance" }, |
160 | | { 8, "Mission Management/Weapons Coordination" }, |
161 | | { 9, "Control" }, |
162 | | { 10, "Electronic Warfare" }, |
163 | | { 11, "Image Transfer" }, |
164 | | { 12, "Voice A" }, |
165 | | { 13, "Voice B" }, |
166 | | { 14, "Indirect PPLI" }, |
167 | | { 18, "Network Enabled Weapons" }, |
168 | | { 19, "Fighter-to-Fighter A" }, |
169 | | { 20, "Fighter-to-Fighter B" }, |
170 | | { 21, "Engagement Coordination" }, |
171 | | { 24, "Bomb Hit Indication" }, |
172 | | { 27, "Joint Net PPLI" }, |
173 | | { 28, "Distributed Network Management" }, |
174 | | { 29, "Residual Messages" }, |
175 | | { 30, "IJMS Position and Status" }, |
176 | | { 31, "Other IJMS Message" }, |
177 | | { 0, NULL }, |
178 | | }; |
179 | | |
180 | | static int proto_link16; |
181 | | |
182 | | static int hf_link16_wordformat; |
183 | | static int hf_link16_label; |
184 | | static int hf_link16_sublabel; |
185 | | static int hf_link16_mli; |
186 | | static int hf_link16_contlabel; |
187 | | |
188 | | static int ett_link16; |
189 | | |
190 | | static int * const link16_initial_word_fields[] = { |
191 | | &hf_link16_wordformat, |
192 | | &hf_link16_label, |
193 | | &hf_link16_sublabel, |
194 | | &hf_link16_mli, |
195 | | NULL |
196 | | }; |
197 | | |
198 | | static int * const link16_continuation_word_fields[] = { |
199 | | &hf_link16_wordformat, |
200 | | &hf_link16_contlabel, |
201 | | NULL |
202 | | }; |
203 | | |
204 | | static int * const link16_extension_or_other_word_fields[] = { |
205 | | &hf_link16_wordformat, |
206 | | NULL |
207 | | }; |
208 | | |
209 | | static int * const *link16_fields[4] = { |
210 | | link16_initial_word_fields, |
211 | | link16_continuation_word_fields, |
212 | | link16_extension_or_other_word_fields, |
213 | | link16_extension_or_other_word_fields |
214 | | }; |
215 | | |
216 | | static int dissect_link16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
217 | 370 | { |
218 | 370 | Link16State *state = (Link16State *)data; |
219 | 370 | proto_item *link16_item = NULL; |
220 | 370 | proto_tree *link16_tree = NULL; |
221 | 370 | uint16_t cache; |
222 | 370 | uint8_t wordformat, contlabel; |
223 | | |
224 | 370 | if (!state) |
225 | 0 | REPORT_DISSECTOR_BUG("Link 16 dissector state missing"); |
226 | | |
227 | 370 | cache = tvb_get_letohs(tvb, 0); |
228 | 370 | wordformat = cache & 0x3; |
229 | | |
230 | 370 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Link 16"); |
231 | | |
232 | 370 | if (tree) { |
233 | 370 | link16_item = proto_tree_add_item(tree, proto_link16, tvb, 0, -1, ENC_NA); |
234 | 370 | link16_tree = proto_item_add_subtree(link16_item, ett_link16); |
235 | 370 | proto_tree_add_bitmask_text(link16_tree, tvb, 0, 2, "Header", NULL, ett_link16, link16_fields[wordformat], ENC_LITTLE_ENDIAN, BMT_NO_APPEND); |
236 | 370 | } |
237 | | |
238 | | /* Elmasry, G., (2012), Tactical Wireless Communications and Networks: Design Concepts and Challenges, Wiley, ISBN 9781119951766. */ |
239 | 370 | switch (wordformat) { |
240 | 166 | case WORDFORMAT_INITIAL: |
241 | 166 | state->label = (cache >> 2) & 0x1F; |
242 | 166 | state->sublabel = (cache >> 7) & 0x7; |
243 | 166 | state->extension = 0; |
244 | 166 | col_append_fstr(pinfo->cinfo, COL_INFO, " J%d.%dI", state->label, state->sublabel); |
245 | | |
246 | 166 | proto_item_append_text(link16_item, " J%d.%dI", state->label, state->sublabel); |
247 | 166 | break; |
248 | 44 | case WORDFORMAT_EXTENSION: |
249 | 44 | col_append_fstr(pinfo->cinfo, COL_INFO, " J%d.%dE%d", state->label, state->sublabel, state->extension); |
250 | | |
251 | 44 | proto_item_append_text(link16_item, " J%d.%dE%d", state->label, state->sublabel, state->extension); |
252 | 44 | state->extension++; |
253 | 44 | break; |
254 | 50 | case WORDFORMAT_CONTINUATION: |
255 | 50 | contlabel = (cache >> 2) & 0x1F; |
256 | 50 | col_append_fstr(pinfo->cinfo, COL_INFO, " J%d.%dC%d", state->label, state->sublabel, contlabel); |
257 | | |
258 | 50 | proto_item_append_text(link16_item, " J%d.%dC%d", state->label, state->sublabel, contlabel); |
259 | 370 | } |
260 | | |
261 | 370 | proto_item_append_text(link16_item, " %s", val_to_str_const(MKPAIR(state->label, state->sublabel), Link16_Message_Strings, "Unknown")); |
262 | | |
263 | 370 | return tvb_captured_length(tvb); |
264 | 370 | } |
265 | | |
266 | | void proto_register_link16(void) |
267 | 14 | { |
268 | 14 | static hf_register_info hf[] = { |
269 | 14 | { &hf_link16_wordformat, |
270 | 14 | { "Word Format", "link16.wordformat", FT_UINT16, BASE_DEC, VALS(WordFormat_Strings), 0x0003, |
271 | 14 | NULL, HFILL }}, |
272 | 14 | { &hf_link16_label, |
273 | 14 | { "Label", "link16.label", FT_UINT16, BASE_DEC, VALS(Link16_Label_Strings), 0x007C, |
274 | 14 | NULL, HFILL }}, |
275 | 14 | { &hf_link16_sublabel, |
276 | 14 | { "Sublabel", "link16.sublabel", FT_UINT16, BASE_DEC, NULL, 0x0380, |
277 | 14 | NULL, HFILL }}, |
278 | 14 | { &hf_link16_mli, |
279 | 14 | { "Message Length Indicator", "link16.mli", FT_UINT16, BASE_DEC, NULL, 0x1C00, |
280 | 14 | NULL, HFILL }}, |
281 | 14 | { &hf_link16_contlabel, |
282 | 14 | { "Continuation Word Label", "link16.contlabel", FT_UINT16, BASE_DEC, NULL, 0x7C, |
283 | 14 | NULL, HFILL }} |
284 | 14 | }; |
285 | 14 | static int *ett[] = { |
286 | 14 | &ett_link16, |
287 | 14 | }; |
288 | | |
289 | 14 | proto_link16 = proto_register_protocol("Link 16", "LINK16", "link16"); |
290 | 14 | proto_register_field_array(proto_link16, hf, array_length (hf)); |
291 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
292 | 14 | register_dissector("link16", dissect_link16, proto_link16); |
293 | 14 | } |
294 | | |
295 | | /* |
296 | | * Editor modelines |
297 | | * |
298 | | * Local Variables: |
299 | | * c-basic-offset: 4 |
300 | | * tab-width: 8 |
301 | | * indent-tabs-mode: nil |
302 | | * End: |
303 | | * |
304 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
305 | | * :indentSize=4:tabSize=8:noTabs=true: |
306 | | */ |