### Bug Summary

File: | epan/dissectors/packet-nmea2000.c
Warning: | line 617, column 9 Value stored to 'offset' is never read

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-nmea2000.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-12-13-100343-3573-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-nmea2000.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* packet-nmea2000.c
2 | * Routines for NMEA 2000 dissection
3 | * Copyright 2025, Anders Broman <a.broman58@gmail.com>
4 | *
5 | * Wireshark - Network traffic analyzer
6 | * By Gerald Combs <gerald@wireshark.org>
7 | * Copyright 1998 Gerald Combs
8 | *
9 | * SPDX-License-Identifier: GPL-2.0-or-later
10 | */
11 |
12 | /*
13 | * NMEA 2000, abbreviated to NMEA2k or N2K and standardized as IEC 61162-3,
14 | * is a plug-and-play communications standard used for connecting marine sensors
15 | * and display units within ships and boats.
16 | * The standard is maintaned by the National Marine Electronics Association (NMEA).
17 | * https://en.wikipedia.org/wiki/NMEA_2000
18 | * https://canboat.github.io/canboat/canboat.html
19 | * https://github.com/fkie-cad/maritime-dissector/tree/master
20 | *
21 | * Relies on the J1939 dissector to dissect CAN messages.
22 | */
23 |
24 | #include "config.h"
25 | #include <wireshark.h>
26 |
27 | #include <epan/packet.h>
28 | #include <epan/reassemble.h>
29 |
30 | /* Define the name for the logging domain (try to avoid collisions with existing domains) */
31 | #define WS_LOG_DOMAIN"packet-nmea2000" "packet-nmea2000"
32 |
33 |
34 | /* (Required to prevent [-Wmissing-prototypes] warnings */
35 | void proto_reg_handoff_nmea2000(void);
36 | void proto_register_nmea2000(void);
37 |
38 | /* Initialize the protocol and registered fields */
39 | static int proto_nmea2000;
40 | static int hf_nmea2000_seq;
41 | static int hf_nmea2000_f_cnt;
42 | static int hf_nmea2000_num_bytes;
43 | static int hf_nmea2000_version;
44 | static int hf_nmea2000_prod_code;
45 | static int hf_nmea2000_model_id;
46 | static int hf_nmea2000_sw_ver_code;
47 | static int hf_nmea2000_model_ver;
48 | static int hf_nmea2000_model_ser_code;
49 | static int hf_nmea2000_cert_lev;
50 | static int hf_nmea2000_load_eq;
51 |
52 | static int hf_nmea2000_man_code;
53 | static int hf_nmea2000_reserved_b4b3;
54 | static int hf_nmea2000_ind_code;
55 | static int hf_nmea2000_reserved16;
56 | static int hf_nmea2000_ap_mode;
57 | static int hf_nmea2000_reserved8;
58 | static int hf_nmea2000_angle;
59 |
60 | static dissector_handle_t nmea2000_handle;
61 |
62 | /* Initialize the subtree pointers */
63 | static int ett_nmea2000;
64 | static int ett_nmea2000_fragment;
65 | static int ett_nmea2000_fragments;
66 |
67 | static reassembly_table nmea2000_reassembly_table;
68 |
69 | /*
70 | * Fast Message fragment handling
71 | */
72 | static int hf_nmea2000_fragments;
73 | static int hf_nmea2000_fragment;
74 | static int hf_nmea2000_fragment_overlap;
75 | static int hf_nmea2000_fragment_overlap_conflicts;
76 | static int hf_nmea2000_fragment_multiple_tails;
77 | static int hf_nmea2000_fragment_too_long_fragment;
78 | static int hf_nmea2000_fragment_error;
79 | static int hf_nmea2000_fragment_count;
80 | static int hf_nmea2000_reassembled_in;
81 | static int hf_nmea2000_reassembled_length;
82 |
83 | static const fragment_items nmea2000_frag_items = {
84 | /* Fragment subtrees */
85 | &ett_nmea2000_fragment,
86 | &ett_nmea2000_fragments,
87 | /* Fragment fields */
88 | &hf_nmea2000_fragments,
89 | &hf_nmea2000_fragment,
90 | &hf_nmea2000_fragment_overlap,
91 | &hf_nmea2000_fragment_overlap_conflicts,
92 | &hf_nmea2000_fragment_multiple_tails,
93 | &hf_nmea2000_fragment_too_long_fragment,
94 | &hf_nmea2000_fragment_error,
95 | &hf_nmea2000_fragment_count,
96 | /* Reassembled in field */
97 | &hf_nmea2000_reassembled_in,
98 | /* Reassembled length field */
99 | &hf_nmea2000_reassembled_length,
100 | /* Reassembled data field */
101 | NULL((void*)0),
102 | /* Tag */
103 | "Fast Message fragments"
104 | };
105 |
106 | #define NMEA2000_PGN_126996126996 126996
107 |
108 | /* MANUFACTURER_CODE (0 - 2047) */
109 |
110 |
111 | static const value_string nmea2000_manufacturer_code_vals[] = {
112 | { 69, "ARKS Enterprises, Inc." },
113 | { 78, "FW Murphy/Enovation Controls" },
114 | { 80, "Twin Disc" },
115 | { 85, "Kohler Power Systems" },
116 | { 88, "Hemisphere GPS Inc" },
117 | { 116, "BEP Marine" },
118 | { 135, "Airmar" },
119 | { 137, "Maretron" },
120 | { 140, "Lowrance" },
121 | { 144, "Mercury Marine" },
122 | { 147, "Nautibus Electronic GmbH" },
123 | { 148, "Blue Water Data" },
124 | { 154, "Westerbeke" },
125 | { 157, "ISSPRO Inc" },
126 | { 161, "Offshore Systems (UK) Ltd." },
127 | { 163, "Evinrude/BRP" },
128 | { 165, "CPAC Systems AB" },
129 | { 168, "Xantrex Technology Inc." },
130 | { 169, "Marlin Technologies, Inc." },
131 | { 172, "Yanmar Marine" },
132 | { 174, "Volvo Penta" },
133 | { 175, "Honda Marine" },
134 | { 176, "Carling Technologies Inc. (Moritz Aerospace)" },
135 | { 185, "Beede Instruments" },
136 | { 192, "Floscan Instrument Co. Inc." },
137 | { 193, "Nobletec" },
138 | { 198, "Mystic Valley Communications" },
139 | { 199, "Actia" },
140 | { 200, "Honda Marine" },
141 | { 201, "Disenos Y Technologia" },
142 | { 211, "Digital Switching Systems" },
143 | { 215, "Xintex/Atena" },
144 | { 224, "EMMI NETWORK S.L." },
145 | { 225, "Honda Marine" },
146 | { 228, "ZF" },
147 | { 229, "Garmin" },
148 | { 233, "Yacht Monitoring Solutions" },
149 | { 235, "Sailormade Marine Telemetry/Tetra Technology LTD" },
150 | { 243, "Eride" },
151 | { 250, "Honda Marine" },
152 | { 257, "Honda Motor Company LTD" },
153 | { 272, "Groco" },
154 | { 273, "Actisense" },
155 | { 274, "Amphenol LTW Technology" },
156 | { 275, "Navico" },
157 | { 283, "Hamilton Jet" },
158 | { 285, "Sea Recovery" },
159 | { 286, "Coelmo SRL Italy" },
160 | { 295, "BEP Marine" },
161 | { 304, "Empir Bus" },
162 | { 305, "NovAtel" },
163 | { 306, "Sleipner Motor AS" },
164 | { 307, "MBW Technologies" },
165 | { 311, "Fischer Panda" },
166 | { 315, "ICOM" },
167 | { 328, "Qwerty" },
168 | { 329, "Dief" },
169 | { 341, "Boening Automationstechnologie GmbH & Co. KG" },
170 | { 345, "Korean Maritime University" },
171 | { 351, "Thrane and Thrane" },
172 | { 355, "Mastervolt" },
173 | { 356, "Fischer Panda Generators" },
174 | { 358, "Victron Energy" },
175 | { 370, "Rolls Royce Marine" },
176 | { 373, "Electronic Design" },
177 | { 374, "Northern Lights" },
178 | { 378, "Glendinning" },
179 | { 381, "B & G" },
180 | { 384, "Rose Point Navigation Systems" },
181 | { 385, "Johnson Outdoors Marine Electronics Inc Geonav" },
182 | { 394, "Capi 2" },
183 | { 396, "Beyond Measure" },
184 | { 400, "Livorsi Marine" },
185 | { 404, "ComNav" },
186 | { 409, "Chetco" },
187 | { 419, "Fusion Electronics" },
188 | { 421, "Standard Horizon" },
189 | { 422, "True Heading AB" },
190 | { 426, "Egersund Marine Electronics AS" },
191 | { 427, "em-trak Marine Electronics" },
192 | { 431, "Tohatsu Co, JP" },
193 | { 437, "Digital Yacht" },
194 | { 438, "Comar Systems Limited" },
195 | { 440, "Cummins" },
196 | { 443, "VDO (aka Continental-Corporation)" },
197 | { 451, "Parker Hannifin aka Village Marine Tech" },
198 | { 459, "Alltek Marine Electronics Corp" },
199 | { 460, "SAN GIORGIO S.E.I.N" },
200 | { 466, "Veethree Electronics & Marine" },
201 | { 467, "Humminbird Marine Electronics" },
202 | { 470, "SI-TEX Marine Electronics" },
203 | { 471, "Sea Cross Marine AB" },
204 | { 475, "GME aka Standard Communications Pty LTD" },
205 | { 476, "Humminbird Marine Electronics" },
206 | { 478, "Ocean Sat BV" },
207 | { 481, "Chetco Digitial Instruments" },
208 | { 493, "Watcheye" },
209 | { 499, "Lcj Capteurs" },
210 | { 502, "Attwood Marine" },
211 | { 503, "Naviop S.R.L." },
212 | { 504, "Vesper Marine Ltd" },
213 | { 510, "Marinesoft Co. LTD" },
214 | { 513, "Simarine" },
215 | { 517, "NoLand Engineering" },
216 | { 518, "Transas USA" },
217 | { 529, "National Instruments Korea" },
218 | { 530, "National Marine Electronics Association" },
219 | { 532, "Onwa Marine" },
220 | { 540, "Webasto" },
221 | { 571, "Marinecraft (South Korea)" },
222 | { 573, "McMurdo Group aka Orolia LTD" },
223 | { 578, "Advansea" },
224 | { 579, "KVH" },
225 | { 580, "San Jose Technology" },
226 | { 583, "Yacht Control" },
227 | { 586, "Suzuki Motor Corporation" },
228 | { 591, "US Coast Guard" },
229 | { 595, "Ship Module aka Customware" },
230 | { 600, "Aquatic AV" },
231 | { 605, "Aventics GmbH" },
232 | { 606, "Intellian" },
233 | { 612, "SamwonIT" },
234 | { 614, "Arlt Tecnologies" },
235 | { 637, "Bavaria Yacts" },
236 | { 641, "Diverse Yacht Services" },
237 | { 644, "Wema U.S.A dba KUS" },
238 | { 645, "Garmin" },
239 | { 658, "Shenzhen Jiuzhou Himunication" },
240 | { 688, "Rockford Corp" },
241 | { 699, "Harman International" },
242 | { 704, "JL Audio" },
243 | { 708, "Lars Thrane" },
244 | { 715, "Autonnic" },
245 | { 717, "Yacht Devices" },
246 | { 734, "REAP Systems" },
247 | { 735, "Au Electronics Group" },
248 | { 739, "LxNav" },
249 | { 741, "Littelfuse, Inc (formerly Carling Technologies)" },
250 | { 743, "DaeMyung" },
251 | { 744, "Woosung" },
252 | { 748, "ISOTTA IFRA srl" },
253 | { 773, "Clarion US" },
254 | { 776, "HMI Systems" },
255 | { 777, "Ocean Signal" },
256 | { 778, "Seekeeper" },
257 | { 781, "Poly Planar" },
258 | { 785, "Fischer Panda DE" },
259 | { 795, "Broyda Industries" },
260 | { 796, "Canadian Automotive" },
261 | { 797, "Tides Marine" },
262 | { 798, "Lumishore" },
263 | { 799, "Still Water Designs and Audio" },
264 | { 802, "BJ Technologies (Beneteau)" },
265 | { 803, "Gill Sensors" },
266 | { 811, "Blue Water Desalination" },
267 | { 815, "FLIR" },
268 | { 824, "Undheim Systems" },
269 | { 826, "Lewmar Inc" },
270 | { 838, "TeamSurv" },
271 | { 844, "Fell Marine" },
272 | { 847, "Oceanvolt" },
273 | { 862, "Prospec" },
274 | { 868, "Data Panel Corp" },
275 | { 890, "L3 Technologies" },
276 | { 894, "Rhodan Marine Systems" },
277 | { 896, "Nexfour Solutions" },
278 | { 905, "ASA Electronics" },
279 | { 909, "Marines Co (South Korea)" },
280 | { 911, "Nautic-on" },
281 | { 917, "Sentinel" },
282 | { 929, "JL Marine ystems" },
283 | { 930, "Ecotronix" },
284 | { 944, "Zontisa Marine" },
285 | { 951, "EXOR International" },
286 | { 962, "Timbolier Industries" },
287 | { 963, "TJC Micro" },
288 | { 968, "Cox Powertrain" },
289 | { 969, "Blue Seas" },
290 | { 981, "Kobelt Manufacturing Co. Ltd" },
291 | { 992, "Blue Ocean IOT" },
292 | { 997, "Xenta Systems" },
293 | { 1004, "Ultraflex SpA" },
294 | { 1008, "Lintest SmartBoat" },
295 | { 1011, "Soundmax" },
296 | { 1020, "Team Italia Marine (Onyx Marine Automation s.r.l)" },
297 | { 1021, "Entratech" },
298 | { 1022, "ITC Inc." },
299 | { 1029, "The Marine Guardian LLC" },
300 | { 1047, "Sonic Corporation" },
301 | { 1051, "ProNav" },
302 | { 1053, "Vetus Maxwell INC." },
303 | { 1056, "Lithium Pros" },
304 | { 1059, "Boatrax" },
305 | { 1062, "Marol Co ltd" },
306 | { 1065, "CALYPSO Instruments" },
307 | { 1066, "Spot Zero Water" },
308 | { 1069, "Lithionics Battery LLC" },
309 | { 1070, "Quick-teck Electronics Ltd" },
310 | { 1075, "Uniden America" },
311 | { 1083, "Nauticoncept" },
312 | { 1084, "Shadow-Caster LED lighting LLC" },
313 | { 1085, "Wet Sounds, LLC" },
314 | { 1088, "E-T-A Circuit Breakers" },
315 | { 1092, "Scheiber" },
316 | { 1100, "Smart Yachts International Limited" },
317 | { 1109, "Dockmate" },
318 | { 1114, "Bobs Machine" },
319 | { 1118, "L3Harris ASV" },
320 | { 1119, "Balmar LLC" },
321 | { 1120, "Elettromedia spa" },
322 | { 1127, "Electromaax" },
323 | { 1140, "Across Oceans Systems Ltd." },
324 | { 1145, "Kiwi Yachting" },
325 | { 1150, "BSB Artificial Intelligence GmbH" },
326 | { 1151, "Orca Technologoes AS" },
327 | { 1154, "TBS Electronics BV" },
328 | { 1158, "Technoton Electroics" },
329 | { 1160, "MG Energy Systems B.V." },
330 | { 1169, "Sea Macine Robotics Inc." },
331 | { 1171, "Vista Manufacturing" },
332 | { 1183, "Zipwake" },
333 | { 1186, "Sailmon BV" },
334 | { 1192, "Airmoniq Pro Kft" },
335 | { 1194, "Sierra Marine" },
336 | { 1200, "Xinuo Information Technology (Xiamen)" },
337 | { 1218, "Septentrio" },
338 | { 1233, "NKE Marine Elecronics" },
339 | { 1238, "SuperTrack Aps" },
340 | { 1239, "Honda Electronics Co., LTD" },
341 | { 1245, "Raritan Engineering Company, Inc" },
342 | { 1249, "Integrated Power Solutions AG" },
343 | { 1260, "Interactive Technologies, Inc." },
344 | { 1283, "LTG-Tech" },
345 | { 1299, "Energy Solutions (UK) LTD." },
346 | { 1300, "WATT Fuel Cell Corp" },
347 | { 1302, "Pro Mainer" },
348 | { 1305, "Dragonfly Energy" },
349 | { 1306, "Koden Electronics Co., Ltd" },
350 | { 1311, "Humphree AB" },
351 | { 1316, "Hinkley Yachts" },
352 | { 1317, "Global Marine Management GmbH (GMM)" },
353 | { 1320, "Triskel Marine Ltd" },
354 | { 1330, "Warwick Control Technologies" },
355 | { 1331, "Dolphin Charger" },
356 | { 1337, "Barnacle Systems Inc" },
357 | { 1348, "Radian IoT, Inc." },
358 | { 1353, "Ocean LED Marine Ltd" },
359 | { 1359, "BluNav" },
360 | { 1361, "OVA (Nantong Saiyang Electronics Co., Ltd)" },
361 | { 1368, "RAD Propulsion" },
362 | { 1369, "Electric Yacht" },
363 | { 1372, "Elco Motor Yachts" },
364 | { 1384, "Tecnoseal Foundry S.r.l" },
365 | { 1385, "Pro Charging Systems, LLC" },
366 | { 1389, "EVEX Co., LTD" },
367 | { 1398, "Gobius Sensor Technology AB" },
368 | { 1403, "Arco Marine" },
369 | { 1408, "Lenco Marine Inc." },
370 | { 1413, "Naocontrol S.L." },
371 | { 1417, "Revatek" },
372 | { 1438, "Aeolionics" },
373 | { 1439, "PredictWind Ltd" },
374 | { 1440, "Egis Mobile Electric" },
375 | { 1445, "Starboard Yacht Group" },
376 | { 1446, "Roswell Marine" },
377 | { 1451, "ePropulsion (Guangdong ePropulsion Technology Ltd.)" },
378 | { 1452, "Micro-Air LLC" },
379 | { 1453, "Vital Battery" },
380 | { 1458, "Ride Controller LLC" },
381 | { 1460, "Tocaro Blue" },
382 | { 1461, "Vanquish Yachts" },
383 | { 1471, "FT Technologies" },
384 | { 1478, "Alps Alpine Co., Ltd." },
385 | { 1481, "E-Force Marine" },
386 | { 1482, "CMC Marine" },
387 | { 1483, "Nanjing Sandemarine Information Technology Co., Ltd." },
388 | { 1850, "Teleflex Marine (SeaStar Solutions)" },
389 | { 1851, "Raymarine" },
390 | { 1852, "Navionics" },
391 | { 1853, "Japan Radio Co" },
392 | { 1854, "Northstar Technologies" },
393 | { 1855, "Furuno" },
394 | { 1856, "Trimble" },
395 | { 1857, "Simrad" },
396 | { 1858, "Litton" },
397 | { 1859, "Kvasar AB" },
398 | { 1860, "MMP" },
399 | { 1861, "Vector Cantech" },
400 | { 1862, "Yamaha Marine" },
401 | { 1863, "Faria Instruments" },
402 | { 0, NULL((void*)0) }
403 | };
404 |
405 | /* INDUSTRY_CODE (0 - 7)*/
406 | static const value_string nmea2000_industry_code_vals[] = {
407 | { 0, "Global" },
408 | { 1, "Highway" },
409 | { 2, "Agriculture" },
410 | { 3, "Construction" },
411 | { 4, "Marine Industry" },
412 | { 5, "Industrial" },
413 | { 0, NULL((void*)0) }
414 | };
415 | /**
416 | * Generic fast packet dissection and reassembly
417 | * @param tvb tvb with packet data
418 | * @param pinfo packety info struct
419 | * @param tree the protocol tree or NULL
420 | * @param num_bytes the number of bytes needed to reassemble
421 | * @return msg_tvb A tvb holding the complete reassembled packet when/if reassembly completes or NULL.
422 | */
423 |
424 | static tvbuff_t *
425 | dissect_nmea2000_fast_pkt(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, uint32_t num_bytes)
426 | {
427 | int offset = 0;
428 | uint32_t frame_count, sequence_no, fragment_length = 7;
429 |
430 | fragment_head* fd_fast_pkt = NULL((void*)0);
431 | uint32_t fragment_id;
432 | bool_Bool more_frags = true1;
433 | bool_Bool save_fragmented = false0;
434 | tvbuff_t* msg_tvb = NULL((void*)0);
435 | uint32_t num_frag = num_bytes / 7 + 1;
436 |
437 | /*
438 | * Packet Type Fast Packet
439 | * The first byte in all frames contains a sequence counter in the high 3 bits and a frame counter in the lower 5 bits
440 | * The second byte in the first frame contains the total number of bytes in all packets that will be sent
441 | * (excluding the single header byte in each of the following packets).
442 | */
443 | proto_tree_add_item_ret_uint(tree, hf_nmea2000_seq, tvb, offset, 1, ENC_NA0x00000000, &sequence_no);
444 | proto_tree_add_item_ret_uint(tree, hf_nmea2000_f_cnt, tvb, offset, 1, ENC_NA0x00000000, &frame_count);
445 | fragment_id = (NMEA2000_PGN_126996126996 << 8) | sequence_no;
446 | offset++;
447 | if (frame_count == 0) {
448 | fragment_length = 6;
449 | proto_tree_add_item(tree, hf_nmea2000_num_bytes, tvb, offset, 1, ENC_NA0x00000000);
450 | offset++;
451 | }
452 | save_fragmented = pinfo->fragmented;
453 | pinfo->fragmented = true1;
454 | /* */
455 | if (frame_count == (num_frag-1)) {
456 | /* Number of fragments needed to get a full msg */
457 | more_frags = false0;
458 | }
459 | fd_fast_pkt = fragment_add_seq_check(&nmea2000_reassembly_table, tvb, offset,
460 | pinfo,
461 | fragment_id, /* uint32_t ID for fragments belonging together */
462 | NULL((void*)0), /* data? */
463 | frame_count, /* uint32_t fragment sequence number */
464 | fragment_length, /* uint32_t fragment length */
465 | more_frags); /* More fragments? */
466 |
467 | msg_tvb = process_reassembled_data(tvb, offset, pinfo,
468 | "Reassembled Fast Message", fd_fast_pkt, &nmea2000_frag_items,
469 | NULL((void*)0), tree);
470 |
471 | pinfo->fragmented = save_fragmented;
472 |
473 | if (fd_fast_pkt != NULL((void*)0)) { /* Reassembled */
474 | col_append_str(pinfo->cinfo, COL_INFO,
475 | " (Message Reassembled)");
476 | } else { /* Not last packet of reassembled Fast Message */
477 | col_append_fstr(pinfo->cinfo, COL_INFO,
478 | " (Message fragment %u(%u))", frame_count + 1, num_frag);
479 | }
480 |
481 | return msg_tvb;
482 | }
483 |
484 | /* 0xFF00-0xFFFF(65280 - 65535): Manufacturer Proprietary single-frame non-addressed */
485 |
486 | /* 0xFF3D: PGN 65341 - Simnet: Autopilot Angle */
487 | #define NMEA2000_PGN_6534165341 65341
488 | /*
489 | * Range Hex Range Dec PDU Step Number of possible PGNs Use Framing
490 | * 0x1ED00-0x1EE00 126208 - 126464 PDU1 256 2 Standardized (protocol) Fast packet
491 | */
492 |
493 | static const value_string nmea2000_ap_mode_vals[] = {
494 | { 2, "Heading" },
495 | { 3, "Wind" },
496 | { 10, "Nav" },
497 | { 11, "No Drift" },
498 | { 0, NULL((void*)0) }
499 | };
500 |
501 |
502 | static int
503 | dissect_nmea2000_65341(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U___attribute__((unused)))
504 | {
505 | proto_item* ti;
506 | proto_tree* nmea2000_tree, * top_tree = proto_tree_get_root(tree);
507 |
508 | int bit_offset = 0;
509 |
510 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "nmea2000");
511 | ti = proto_tree_add_item(top_tree, proto_nmea2000, tvb, 0, -1, ENC_NA0x00000000);
512 | nmea2000_tree = proto_item_add_subtree(ti, ett_nmea2000);
513 |
514 | /* Manufacturer Code 1857: Simrad 0 .. 2044 11 bits lookup MANUFACTURER_CODE */
515 | proto_tree_add_bits_item(nmea2000_tree, hf_nmea2000_man_code, tvb, bit_offset, 11, ENC_LITTLE_ENDIAN0x80000000);
516 | bit_offset += 11;
517 | /* Reserved 2 bits RESERVED */
518 | proto_tree_add_bits_item(nmea2000_tree, hf_nmea2000_reserved_b4b3, tvb, bit_offset, 2, ENC_LITTLE_ENDIAN0x80000000);
519 | bit_offset += 2;
520 | /* Industry Code 4: Marine Industry 0 .. 6 3 bits lookup INDUSTRY_CODE */
521 | proto_tree_add_bits_item(nmea2000_tree, hf_nmea2000_ind_code, tvb, bit_offset, 3, ENC_LITTLE_ENDIAN0x80000000);
522 | bit_offset += 3;
523 | /* Reserved 16 bits RESERVED */
524 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_reserved16, tvb, bit_offset>>3, 2, ENC_LITTLE_ENDIAN0x80000000);
525 | bit_offset += 16;
526 | /* Mode 0 .. 252 8 bits lookup SIMNET_AP_MODE*/
527 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_ap_mode, tvb, bit_offset >> 3, 1, ENC_LITTLE_ENDIAN0x80000000);
528 | bit_offset += 8;
529 | /* Reserved 8 bits RESERVED */
530 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_reserved8, tvb, bit_offset>>3, 1, ENC_LITTLE_ENDIAN0x80000000);
531 | bit_offset += 8;
532 | /* Angle 0.0001 rad0 .. 6.2831852 16 bits unsigned NUMBER*/
533 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_angle, tvb, bit_offset >> 3, 2, ENC_LITTLE_ENDIAN0x80000000);
534 | //bit_offset += 16;
535 |
536 | return tvb_captured_length(tvb);
537 |
538 | }
539 |
540 | static const value_string nmea2000_cert_lev_vals[] = {
541 | { 0x0, "Level A" },
542 | { 0x1, "Level B" },
543 | { 0, NULL((void*)0) }
544 | };
545 |
546 | /*
547 | * 0x1F105: PGN 127237 - Heading/Track control
548 | * This fast-packet PGN is 21 bytes long and contains 18 fields.
549 | */
550 | #define NMEA2000_PGN_127237127237 127237
551 | static int
552 | dissect_nmea2000_127237(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U___attribute__((unused)))
553 | {
554 | proto_item* ti;
555 | proto_tree* nmea2000_tree, * top_tree = proto_tree_get_root(tree);
556 |
557 | tvbuff_t* msg_tvb;
558 | //int offset = 0;
559 |
560 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "nmea2000");
561 | ti = proto_tree_add_item(top_tree, proto_nmea2000, tvb, 0, -1, ENC_NA0x00000000);
562 | nmea2000_tree = proto_item_add_subtree(ti, ett_nmea2000);
563 |
564 | msg_tvb = dissect_nmea2000_fast_pkt(tvb, pinfo, nmea2000_tree, 21);
565 |
566 | if (msg_tvb) { /* Reassembled */
567 |
568 | }
569 |
570 | return tvb_captured_length(tvb);
571 | }
572 |
573 | /*
574 | * 0x1F014: PGN 126996 - Product Information
575 | * This fast-packet PGN is 134 bytes long and contains 8 fields.
576 | */
577 |
578 | static int
579 | dissect_nmea2000_126996(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U___attribute__((unused)))
580 | {
581 | proto_item* ti;
582 | proto_tree* nmea2000_tree, *top_tree = proto_tree_get_root(tree);
583 |
584 | tvbuff_t* msg_tvb;
585 | int offset = 0;
586 |
587 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "nmea2000");
588 | ti = proto_tree_add_item(top_tree, proto_nmea2000, tvb, 0, -1, ENC_NA0x00000000);
589 | nmea2000_tree = proto_item_add_subtree(ti, ett_nmea2000);
590 |
591 | msg_tvb = dissect_nmea2000_fast_pkt(tvb, pinfo, nmea2000_tree, 134);
592 |
593 | if (msg_tvb) { /* Reassembled */
594 | /* NMEA 2000 Version, 16 bits unsigned NUMBER, Unit 0.001*/
595 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_version, msg_tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
596 | offset += 2;
597 | /* Product Code 16 bits unsigned NUMBER */
598 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_prod_code, msg_tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
599 | offset += 2;
600 | /* Model ID 256 bits STRING_FIX*/
601 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_model_id, msg_tvb, offset, 32, ENC_ASCII0x00000000);
602 | offset += 32;
603 | /* Software Version Code 256 bits STRING_FIX */
604 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_sw_ver_code, msg_tvb, offset, 32, ENC_ASCII0x00000000);
605 | offset += 32;
606 | /* Model Version 256 bits STRING_FIX */
607 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_model_ver, msg_tvb, offset, 32, ENC_ASCII0x00000000);
608 | offset += 32;
609 | /* Model Serial Code 256 bits STRING_FIX */
610 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_model_ser_code, msg_tvb, offset, 32, ENC_ASCII0x00000000);
611 | offset += 32;
612 | /* Certification Level 8 bits lookup CERTIFICATION_LEVEL */
613 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_cert_lev, msg_tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
614 | offset += 1;
615 | /* Load Equivalency 8 bits unsigned NUMBER */
616 | proto_tree_add_item(nmea2000_tree, hf_nmea2000_load_eq, msg_tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
617 | offset += 1;
| Value stored to 'offset' is never read
618 | }
619 |
620 | return tvb_captured_length(tvb);
621 | }
622 |
623 | static int
624 | dissect_nmea2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused)))
625 | {
626 | //proto_item *ti;
627 | //proto_tree *nmea2000_tree;
628 |
629 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "nmea2000");
630 |
631 | #if 0
632 | /* If you will be fetching any data from the packet before filling in
633 | * the Info column, clear that column first in case the calls to fetch
634 | * data from the packet throw an exception so that the Info column doesn't
635 | * contain data left over from the previous dissector: */
636 | col_clear(pinfo->cinfo, COL_INFO);
637 | #endif
638 |
639 | /*ti = */proto_tree_add_item(tree, proto_nmea2000, tvb, 0, -1, ENC_NA0x00000000);
640 | /*nmea2000_tree = proto_item_add_subtree(ti, ett_nmea2000);*/
641 |
642 |
643 | /* Return the amount of data this dissector was able to dissect (which may
644 | * or may not be the total captured packet as we return here). */
645 | return tvb_captured_length(tvb);
646 | }
647 |
648 | /*
649 | * Register the protocol with Wireshark.
650 | */
651 | void
652 | proto_register_nmea2000(void)
653 | {
654 |
655 | static hf_register_info hf[] = {
656 | { &hf_nmea2000_seq,
657 | { "Sequence number", "nmea2000.seq",
658 | FT_UINT8, BASE_DEC, NULL((void*)0), 0xe0,
659 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
660 | },
661 | { &hf_nmea2000_f_cnt,
662 | { "Frame counter", "nmea2000.f_cnt",
663 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x1f,
664 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
665 | },
666 | { &hf_nmea2000_num_bytes,
667 | { "Number of bytes", "nmea2000.num_bytes",
668 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
669 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
670 | },
671 | { &hf_nmea2000_version,
672 | { "Version", "nmea2000.version",
673 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
674 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
675 | },
676 | { &hf_nmea2000_prod_code,
677 | { "Product Code", "nmea2000.prod_code",
678 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
679 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
680 | },
681 | { &hf_nmea2000_model_id,
682 | { "Model ID", "nmea2000.model_id",
683 | FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
684 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
685 | },
686 | { &hf_nmea2000_sw_ver_code,
687 | { "Software Version Code", "nmea2000.sw_ver_code",
688 | FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
689 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
690 | },
691 | { &hf_nmea2000_model_ver,
692 | { "Model Version", "nmea2000.model_ver",
693 | FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
694 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
695 | },
696 | { &hf_nmea2000_model_ser_code,
697 | { "Model Serial Code", "nmea2000.model_ser_code",
698 | FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
699 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
700 | },
701 | { &hf_nmea2000_cert_lev,
702 | { "Certification Level", "nmea2000.cert_lev",
703 | FT_UINT16, BASE_DEC, VALS(nmea2000_cert_lev_vals)((0 ? (const struct _value_string*)0 : ((nmea2000_cert_lev_vals )))), 0x0,
704 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
705 | },
706 | { &hf_nmea2000_load_eq,
707 | { "Load Equivalency", "nmea2000.load_eq",
708 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
709 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
710 | },
711 | /*
712 | * Fast Message fragment reassembly
713 | */
714 | { &hf_nmea2000_fragments,
715 | { "Fast Message fragments", "nmea2000.fragments",
716 | FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
717 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
718 | },
719 | { &hf_nmea2000_fragment,
720 | { "Fast Message fragment", "nmea2000.fragment",
721 | FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
722 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
723 | },
724 | { &hf_nmea2000_fragment_overlap,
725 | { "Fast Message fragment overlap", "nmea2000.fragment.overlap",
726 | FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
727 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
728 | },
729 | { &hf_nmea2000_fragment_overlap_conflicts,
730 | { "Fast Message fragment overlapping with conflicting data", "nmea2000.fragment.overlap.conflicts",
731 | FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
732 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
733 | },
734 | { &hf_nmea2000_fragment_multiple_tails,
735 | { "Fast Message has multiple tail fragments", "nmea2000.fragment.multiple_tails",
736 | FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
737 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
738 | },
739 | { &hf_nmea2000_fragment_too_long_fragment,
740 | { "Fast Message fragment too long", "nmea2000.fragment.too_long_fragment",
741 | FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
742 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
743 | },
744 | { &hf_nmea2000_fragment_error,
745 | { "Fast Message defragmentation error", "nmea2000.fragment.error",
746 | FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
747 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
748 | },
749 | { &hf_nmea2000_fragment_count,
750 | { "Fast Message fragment count", "nmea2000.fragment.count",
751 | FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
752 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
753 | },
754 | { &hf_nmea2000_reassembled_in,
755 | { "Reassembled in", "nmea2000.reassembled.in",
756 | FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
757 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
758 | },
759 | { &hf_nmea2000_reassembled_length,
760 | { "Reassembled Fast Message length", "nmea2000.reassembled.length",
761 | FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
762 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
763 | },
764 | { &hf_nmea2000_man_code,
765 | { "Manufacturer Code", "nmea2000.man_code",
766 | FT_UINT16, BASE_DEC, VALS(nmea2000_manufacturer_code_vals)((0 ? (const struct _value_string*)0 : ((nmea2000_manufacturer_code_vals )))), 0x0,
767 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
768 | },
769 | { &hf_nmea2000_reserved_b4b3,
770 | { "Reserved", "nmea2000.reserved_b4b3",
771 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
772 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
773 | },
774 | { &hf_nmea2000_ind_code,
775 | { "Industry Code", "nmea2000.ind_code",
776 | FT_UINT16, BASE_DEC, VALS(nmea2000_industry_code_vals)((0 ? (const struct _value_string*)0 : ((nmea2000_industry_code_vals )))), 0x0,
777 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
778 | },
779 | { &hf_nmea2000_reserved16,
780 | { "Reserved", "nmea2000.reserved16",
781 | FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
782 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
783 | },
784 | { &hf_nmea2000_ap_mode,
785 | { "Mode", "nmea2000.ap_mode",
786 | FT_UINT8, BASE_DEC, VALS(nmea2000_ap_mode_vals)((0 ? (const struct _value_string*)0 : ((nmea2000_ap_mode_vals )))), 0x0,
787 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
788 | },
789 | { &hf_nmea2000_reserved8,
790 | { "Reserved", "nmea2000.reserved8",
791 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
792 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
793 | },
794 | { &hf_nmea2000_angle,
795 | { "Angle", "nmea2000.angle",
796 | FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
797 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
798 | },
799 | };
800 |
801 | /* Setup protocol subtree array */
802 | static int *ett[] = {
803 | &ett_nmea2000,
804 | &ett_nmea2000_fragment,
805 | &ett_nmea2000_fragments
806 | };
807 |
808 |
809 | /* Register the protocol name and description */
810 | proto_nmea2000 = proto_register_protocol("NMEA 2000", "nmea2000", "nmea2000");
811 |
812 | /* Required function calls to register the header fields and subtrees */
813 | proto_register_field_array(proto_nmea2000, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
814 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
815 |
816 |
817 | nmea2000_handle = register_dissector("nmea2000", dissect_nmea2000, proto_nmea2000);
818 |
819 |
820 | }
821 |
822 |
823 | void
824 | proto_reg_handoff_nmea2000(void)
825 | {
826 | reassembly_table_register(&nmea2000_reassembly_table, &addresses_reassembly_table_functions);
827 |
828 | dissector_add_uint("j1939.pgn", NMEA2000_PGN_6534165341, create_dissector_handle(dissect_nmea2000_65341, proto_nmea2000));
829 |
830 |
831 | dissector_add_uint("j1939.pgn", NMEA2000_PGN_127237127237, create_dissector_handle(dissect_nmea2000_127237, proto_nmea2000));
832 |
833 | dissector_add_uint("j1939.pgn", NMEA2000_PGN_126996126996, create_dissector_handle(dissect_nmea2000_126996, proto_nmea2000));
834 | }
835 |
836 |
837 |
838 | /*
839 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
840 | *
841 | * Local variables:
842 | * c-basic-offset: 4
843 | * tab-width: 8
844 | * indent-tabs-mode: nil
845 | * End:
846 | *
847 | * vi: set shiftwidth=4 tabstop=8 expandtab:
848 | * :indentSize=4:tabSize=8:noTabs=true:
849 | */