Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-vcdu.c
blob8a43649f61636b68629a1f25a03278503f49e249
1 /* packet-vcdu.c
2 * Routines for VCDU dissection
3 * Copyright 2000, Scott Hovis scott.hovis@ums.msfc.nasa.gov
4 * Enhanced 2008, Matt Dunkle Matthew.L.Dunkle@nasa.gov
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.com>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/to_str.h>
19 #include <epan/uat.h>
21 void proto_register_vcdu(void);
22 void proto_reg_handoff_vcdu(void);
24 /* Initialize the protocol and registered fields */
25 static int proto_vcdu;
27 static int hf_smex_gsc;
28 /* static int hf_smex_unused; */
29 static int hf_smex_version;
30 static int hf_smex_framelen;
31 static int hf_smex_rs_error;
32 static int hf_smex_rs_enable;
33 static int hf_smex_crc_enable;
34 static int hf_smex_crc_error;
35 static int hf_smex_mcs_enable;
36 static int hf_smex_mcs_num_error;
37 static int hf_smex_data_inv;
38 static int hf_smex_frame_sync;
39 static int hf_smex_data_dir;
40 static int hf_smex_data_class;
41 static int hf_smex_pb5;
42 static int hf_smex_jday;
43 static int hf_smex_seconds;
44 static int hf_smex_msec;
45 /* static int hf_smex_spare; */
47 static int hf_vcdu_version;
48 static int hf_vcdu_sp_id;
49 static int hf_vcdu_vc_id;
50 static int hf_vcdu_seq;
51 static int hf_vcdu_replay;
53 /* Generated from convert_proto_tree_add_text.pl */
54 static int hf_vcdu_data;
55 static int hf_vcdu_ground_receipt_time;
56 static int hf_vcdu_ccsds_all_fill;
57 static int hf_vcdu_bitream_all_fill;
58 static int hf_vcdu_bitream_all_data;
59 static int hf_vcdu_bitream_all_data_anomaly;
60 static int hf_vcdu_ccsds_continuation_packet;
62 /* although technically not part of the vcdu header, the
63 * first header pointer (for ccsds), and the last bit
64 * pointer (for bitstream), are more easily processed by
65 * simply adding them to the tail end of the vcdu header
66 * branch rather than creating a distinct branch for them
68 static int hf_vcdu_fhp;
69 static int hf_vcdu_lbp;
71 static dissector_handle_t vcdu_handle;
73 static dissector_handle_t ccsds_handle;
75 /* Initialize the subtree pointers */
76 static int ett_vcdu;
77 static int ett_smex;
78 static int ett_vcduh;
80 static expert_field ei_vcdu_fhp_too_close_to_end_of_vcdu;
83 * Bits in the first 16-bit header word
85 #define SMEX_VERSION 0xc000
86 #define SMEX_FRAMELEN 0x3fff
88 /* some basic sizing parameters */
89 #define IP_HEADER_LENGTH 48
90 #define SMEX_HEADER_LENGTH 20
91 #define VCDU_HEADER_LENGTH 6
92 #define CCSDS_PRIMARY_HEADER_LENGTH 6
93 #define CCSDS_SECONDARY_HEADER_LENGTH 10
95 #define PB5_JULIAN_DAY_MASK 0x7ffe
96 #define PB5_SECONDS_MASK 0x01ffff
97 #define PB5_MILLISECONDS_MASK 0xffc0
99 #define LBP_ALL_DATA 0x3fff
100 #define LBP_ALL_DATA_ANOMALY 0x7ff
101 #define LBP_ALL_FILL 0x3ffe
103 #define FHP_ALL_FILL 0x7fe
104 #define FHP_CONTINUATION 0x7ff
106 #define LBP_MASK 0x3fff
107 #define FHP_MASK 0x07ff
109 /* leap year macro */
110 #ifndef Leap
111 # define Leap(yr) ( ( 0 == (yr)%4 && 0 != (yr)%100 ) || ( 0 == (yr)%400 ) )
112 #endif
115 static const value_string smex_data_inversion_type[] = {
116 { 0, "Data True (not inverted)" },
117 { 1, "Data Inverted (not corrected)" },
118 { 2, "Data Inversion State UNDEFINED" },
119 { 3, "Data Inverted (and corrected)" },
120 { 0, NULL }
123 static const value_string smex_frame_sync_mode[] = {
124 { 0, "Search" },
125 { 1, "Check" },
126 { 2, "Lock" },
127 { 3, "Flywheel" },
128 { 0, NULL }
131 static const value_string smex_data_direction[] = {
132 { 0, "Forward" },
133 { 1, "Reverse" },
134 { 0, NULL }
137 static const value_string smex_data_class[] = {
138 { 0, "Data Class UNDEFINED" },
139 { 1, "CCSDS Frame" },
140 { 2, "CCSDS Packet" },
141 { 3, "TDM Frame" },
142 { 4, "Stopped TDM Frame" },
143 { 0, NULL }
146 /* default bitstream channel assignments:
147 * the audio channels 4-6 are designated as bitstream channels
148 * the standard bitstream channels are 12 through 19
149 * the video channels 28-30 are designated as bitstream channels
150 * the fill channel 63 is designated as bitstream
152 static int bitstream_channels[] =
154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* channels 0-9 */
155 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* channels 10-19 */
156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* channels 20-29 */
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* channels 30-39 */
158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* channels 40-49 */
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* channels 50-59 */
160 0, 0, 0, 1 /* channels 60-63 */
163 typedef struct {
164 unsigned channel;
165 } uat_channel_t;
167 static uat_channel_t *uat_bitchannels;
168 static uat_t *vcdu_uat;
169 static unsigned num_channels_uat;
171 UAT_DEC_CB_DEF(uat_bitchannels, channel, uat_channel_t)
173 static bool
174 vcdu_uat_data_update_cb(void *p, char **err) {
175 uat_channel_t *ud = (uat_channel_t *)p;
177 if (ud->channel >= 64) {
178 *err = g_strdup("Channel must be between 0-63.");
179 return false;
181 return true;
184 static void
185 vcdu_prefs_apply_cb(void)
187 unsigned i;
189 if (num_channels_uat > 0)
191 memset(bitstream_channels, 0, sizeof(bitstream_channels));
193 for (i = 0; i < num_channels_uat; i++)
195 bitstream_channels[uat_bitchannels[i].channel] = 1;
200 /* convert smex PB5 header time to a human readable string - NOT THREAD SAFE
202 * note: this is not true PB5 time either, but a tsi specific version, although it is similar
204 static const char *
205 smex_time_to_string (wmem_allocator_t *pool, int pb5_days_since_midnight_9_10_oct_1995, int pb5_seconds, int pb5_milliseconds)
207 static int utcdiff = 0;
208 nstime_t t;
210 static int Days[2][13] =
212 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
213 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
216 int yr;
217 int ix, days, month;
219 /* compute the static constant difference in seconds
220 * between midnight 9-10 October 1995 (PB5 time) and
221 * seconds since 1/1/1970 (UTC time) just this once
223 if (0 == utcdiff)
225 for (yr=1970; yr < 1995; ++yr)
227 utcdiff += (Leap(yr) ? 366 : 365) * 24 * 60 * 60;
230 days = 0;
231 ix = (Leap(1995) ? 1 : 0);
233 for (month=1; month < 10; ++month)
235 days += Days[ix][month];
238 days += 9; /* this gets us up to midnight october 9-10 */
240 utcdiff += days * 24 * 60 * 60; /* add days in 1995 prior to October 10 */
243 t.secs = (pb5_days_since_midnight_9_10_oct_1995 * 86400) + pb5_seconds + utcdiff;
244 t.nsecs = pb5_milliseconds*1000000; /* msecs to nsecs */
246 return abs_time_to_str(pool, &t, ABSOLUTE_TIME_DOY_UTC, true);
250 static int
251 dissect_vcdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
253 int offset = 0;
254 bool ccsds_tree_added = false;
256 proto_item *smex_header;
257 proto_tree *smex_tree;
259 proto_tree *vcdu_tree;
260 proto_item *vcdu_item;
262 uint16_t first_word;
263 uint32_t long_word;
265 int vcid, pb5_days, pb5_seconds, pb5_milliseconds;
266 const char *time_string;
268 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VCDU");
269 col_set_str(pinfo->cinfo, COL_INFO, "Virtual Channel Data Unit");
271 /* build the smex header tree */
272 smex_tree = proto_tree_add_subtree(tree, tvb, offset, SMEX_HEADER_LENGTH, ett_smex, &smex_header, "SMEX Header");
274 proto_tree_add_item(smex_tree, hf_smex_gsc, tvb, offset, 8, ENC_BIG_ENDIAN);
275 offset += 8;
276 /* proto_tree_add_item(smex_tree, hf_smex_unused, tvb, offset, 2, ENC_BIG_ENDIAN); */
277 offset += 2;
279 first_word = tvb_get_ntohs(tvb, offset);
280 proto_tree_add_uint(smex_tree, hf_smex_version, tvb, offset, 2, first_word);
281 proto_tree_add_uint(smex_tree, hf_smex_framelen, tvb, offset, 2, first_word);
282 offset += 2;
284 proto_tree_add_item(smex_tree, hf_smex_rs_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
285 proto_tree_add_item(smex_tree, hf_smex_rs_error, tvb, offset, 1, ENC_BIG_ENDIAN);
286 proto_tree_add_item(smex_tree, hf_smex_crc_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
287 proto_tree_add_item(smex_tree, hf_smex_crc_error, tvb, offset, 1, ENC_BIG_ENDIAN);
288 proto_tree_add_item(smex_tree, hf_smex_mcs_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
289 proto_tree_add_item(smex_tree, hf_smex_mcs_num_error, tvb, offset, 1, ENC_BIG_ENDIAN);
290 proto_tree_add_item(smex_tree, hf_smex_data_inv, tvb, offset, 1, ENC_BIG_ENDIAN);
291 offset += 1;
293 proto_tree_add_item(smex_tree, hf_smex_frame_sync, tvb, offset, 1, ENC_BIG_ENDIAN);
294 proto_tree_add_item(smex_tree, hf_smex_data_dir, tvb, offset, 1, ENC_BIG_ENDIAN);
295 proto_tree_add_item(smex_tree, hf_smex_data_class, tvb, offset, 1, ENC_BIG_ENDIAN);
296 offset += 1;
298 /* extract smex ground receipt time tag */
299 long_word = tvb_get_ntohl(tvb, offset);
300 pb5_days = (long_word >> 17) & PB5_JULIAN_DAY_MASK;
301 pb5_seconds = (long_word & PB5_SECONDS_MASK);
303 first_word = tvb_get_ntohs(tvb, offset+4);
304 pb5_milliseconds = (first_word & PB5_MILLISECONDS_MASK) >> 6;
306 proto_tree_add_item(smex_tree, hf_smex_pb5, tvb, offset, 2, ENC_BIG_ENDIAN);
307 proto_tree_add_item(smex_tree, hf_smex_jday, tvb, offset, 2, ENC_BIG_ENDIAN);
308 offset += 1;
309 proto_tree_add_item(smex_tree, hf_smex_seconds, tvb, offset, 3, ENC_BIG_ENDIAN);
310 offset += 3;
312 proto_tree_add_item(smex_tree, hf_smex_msec, tvb, offset, 2, ENC_BIG_ENDIAN);
313 /* proto_tree_add_item(smex_tree, hf_smex_spare, tvb, offset, 2, ENC_BIG_ENDIAN); */
314 offset += 2;
316 /* format ground receipt time into human readable time format for display */
317 time_string = smex_time_to_string(pinfo->pool, pb5_days, pb5_seconds, pb5_milliseconds);
318 proto_tree_add_string(smex_tree, hf_vcdu_ground_receipt_time, tvb, offset-6, 6, time_string);
320 proto_item_set_end(smex_header, tvb, offset);
323 /* build the vcdu header tree */
324 vcdu_tree = proto_tree_add_subtree(tree, tvb, offset, VCDU_HEADER_LENGTH, ett_vcdu, &vcdu_item, "VCDU Header");
326 /* extract the virtual channel for use later on */
327 first_word = tvb_get_ntohs(tvb, offset);
328 vcid = first_word & 0x3f;
330 proto_tree_add_item(vcdu_tree, hf_vcdu_version, tvb, offset, 2, ENC_BIG_ENDIAN);
331 proto_tree_add_item(vcdu_tree, hf_vcdu_sp_id, tvb, offset, 2, ENC_BIG_ENDIAN);
332 proto_tree_add_item(vcdu_tree, hf_vcdu_vc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
333 offset += 2;
334 proto_tree_add_item(vcdu_tree, hf_vcdu_seq, tvb, offset, 3, ENC_BIG_ENDIAN);
335 offset += 3;
336 proto_tree_add_item(vcdu_tree, hf_vcdu_replay, tvb, offset, 1, ENC_BIG_ENDIAN);
337 offset += 1;
339 /* extract mpdu/bpdu header word */
340 first_word = tvb_get_ntohs(tvb, offset);
342 /* do bitstream channel processing */
343 if (bitstream_channels[vcid])
345 uint16_t new_ptr;
347 /* extract last bit pointer for bitstream channels */
348 new_ptr = first_word & LBP_MASK;
350 /* add last bit pointer to display tree */
351 proto_tree_add_item(vcdu_tree, hf_vcdu_lbp, tvb, offset, 2, ENC_BIG_ENDIAN);
353 switch (new_ptr)
355 case LBP_ALL_DATA:
356 proto_tree_add_item(vcdu_tree, hf_vcdu_bitream_all_data, tvb, 0, -1, ENC_NA);
357 break;
359 case LBP_ALL_DATA_ANOMALY:
360 proto_tree_add_item(vcdu_tree, hf_vcdu_bitream_all_data_anomaly, tvb, 0, -1, ENC_NA);
361 break;
363 case LBP_ALL_FILL:
364 proto_tree_add_item(vcdu_tree, hf_vcdu_bitream_all_fill, tvb, 0, -1, ENC_NA);
365 break;
367 default:
368 break;
370 } /* end of bitstream channel processing */
372 /* do ccsds channel processing */
373 else
375 uint16_t new_ptr;
377 /* extract first header pointer for ccsds channels */
378 new_ptr = first_word & FHP_MASK;
380 /* add first header pointer to display tree */
381 proto_tree_add_item(vcdu_tree, hf_vcdu_fhp, tvb, offset, 2, ENC_BIG_ENDIAN);
383 /* process special cases of first header pointer */
384 if (FHP_ALL_FILL == new_ptr)
386 proto_tree_add_item(vcdu_tree, hf_vcdu_ccsds_all_fill, tvb, 0, -1, ENC_NA);
389 else if (FHP_CONTINUATION == new_ptr)
391 proto_tree_add_item(vcdu_tree, hf_vcdu_ccsds_continuation_packet, tvb, 0, -1, ENC_NA);
394 /* process as many ccsds packet headers as we can using the ccsds packet dissector */
395 else
397 int packet_boundary;
398 int new_offset;
400 /* compute offset and packet boundary lengths for ccsds dissector loop */
401 new_offset = offset + 2 + new_ptr;
403 packet_boundary =
404 tvb_reported_length(tvb) - VCDU_HEADER_LENGTH
405 - CCSDS_PRIMARY_HEADER_LENGTH - CCSDS_SECONDARY_HEADER_LENGTH;
407 while ( ((new_offset-offset+2) < packet_boundary) && ((new_offset-offset+2) >= 4) )
409 int ccsds_len;
410 tvbuff_t *new_tvb;
412 ccsds_tree_added = true;
413 ccsds_len = tvb_get_ntohs(tvb, new_offset+4);
415 new_tvb = tvb_new_subset_remaining(tvb, new_offset);
416 call_dissector(ccsds_handle, new_tvb, pinfo, vcdu_tree);
418 new_offset = new_offset + ccsds_len + 7;
421 if (! ccsds_tree_added)
423 proto_tree_add_expert(vcdu_tree, pinfo, &ei_vcdu_fhp_too_close_to_end_of_vcdu, tvb, 0, -1);
427 } /* end of ccsds channel processing */
429 /* don't include the mpdu/bpdu header in the vcdu header highlighting.
430 * by skipping the offset bump the vcdu header highlighting will show
431 * just 6 bytes as it really should, and the fhp/lbp will be included
432 * in the data zone, which is technically more correct.
434 /* offset += 2; */
435 proto_item_set_end(vcdu_item, tvb, offset);
437 if (! ccsds_tree_added)
439 /* add "Data" section if ccsds parsing did not do so already */
440 proto_tree_add_item(vcdu_tree, hf_vcdu_data, tvb, offset, -1, ENC_NA);
443 return tvb_captured_length(tvb);
447 void
448 proto_register_vcdu(void)
450 module_t *vcdu_module;
452 /* Setup list of header fields See Section 1.6.1 for details*/
453 static hf_register_info hf[] = {
454 { &hf_smex_gsc,
455 { "Ground Sequence Counter", "vcdu.smex.gsc",
456 FT_UINT64, BASE_DEC, NULL, 0x0,
457 "SMEX Ground Sequence Counter", HFILL }
459 #if 0
460 { &hf_smex_unused,
461 { "Unused", "vcdu.smex.unused",
462 FT_UINT16, BASE_DEC, NULL, 0x0,
463 "SMEX Unused", HFILL }
465 #endif
466 { &hf_smex_version,
467 { "Version", "vcdu.smex.version",
468 FT_UINT16, BASE_DEC, NULL, SMEX_VERSION,
469 "SMEX Version", HFILL }
471 { &hf_smex_framelen,
472 { "Frame Length", "vcdu.smex.frame_len",
473 FT_UINT16, BASE_DEC, NULL, SMEX_FRAMELEN,
474 "SMEX Frame Length", HFILL }
476 { &hf_smex_rs_enable,
477 { "RS Enable", "vcdu.smex.rs_enable",
478 FT_BOOLEAN, 8, NULL, 0x80,
479 "SMEX RS Enable", HFILL }
481 { &hf_smex_rs_error,
482 { "RS Error", "vcdu.smex.rs_error",
483 FT_BOOLEAN, 8, NULL, 0x40,
484 "SMEX RS Error", HFILL }
486 { &hf_smex_crc_enable,
487 { "CRC Enable", "vcdu.smex.crc_enable",
488 FT_BOOLEAN, 8, NULL, 0x20,
489 "SMEX CRC Enable", HFILL }
491 { &hf_smex_crc_error,
492 { "CRC Error", "vcdu.smex.crc_error",
493 FT_BOOLEAN, 8, NULL, 0x10,
494 "SMEX CRC Error", HFILL }
496 { &hf_smex_mcs_enable,
497 { "MCS Enable", "vcdu.smex.mcs_enable",
498 FT_BOOLEAN, 8, NULL, 0x08,
499 "SMEX MCS Enable", HFILL }
501 { &hf_smex_mcs_num_error,
502 { "MCS Number Error", "vcdu.smex.mcs_numerr",
503 FT_BOOLEAN, 8, NULL, 0x04,
504 "SMEX MCS Number Error", HFILL }
506 { &hf_smex_data_inv,
507 { "Data Inversion", "vcdu.smex.data_inv",
508 FT_UINT16, BASE_DEC, VALS(smex_data_inversion_type), 0x03,
509 "SMEX Data Inversion", HFILL }
511 { &hf_smex_frame_sync,
512 { "Frame Sync", "vcdu.smex.frame_sync",
513 FT_UINT16, BASE_DEC, VALS(smex_frame_sync_mode), 0xc0,
514 "SMEX Frame Sync Flag", HFILL }
516 { &hf_smex_data_dir,
517 { "Data Direction", "vcdu.smex.data_dir",
518 FT_UINT16, BASE_DEC, VALS(smex_data_direction), 0x20,
519 "SMEX Data Direction flag", HFILL }
521 { &hf_smex_data_class,
522 { "Data Class", "vcdu.smex.data_class",
523 FT_UINT16, BASE_DEC, VALS(smex_data_class), 0x1f,
524 "SMEX Data Class", HFILL }
526 { &hf_smex_pb5,
527 { "PB5 Flag", "vcdu.smex.pb5",
528 FT_UINT16, BASE_DEC, NULL, 0x8000,
529 "SMEX PB5 Flag", HFILL }
531 { &hf_smex_jday,
532 { "Julian Day", "vcdu.smex.jday",
533 FT_UINT16, BASE_DEC, NULL, PB5_JULIAN_DAY_MASK,
534 "SMEX Julian Day", HFILL }
536 { &hf_smex_seconds,
537 { "Seconds", "vcdu.smex.seconds",
538 FT_UINT24, BASE_DEC, NULL, PB5_SECONDS_MASK,
539 "SMEX Seconds", HFILL }
541 { &hf_smex_msec,
542 { "Milliseconds", "vcdu.smex.msec",
543 FT_UINT16, BASE_DEC, NULL, PB5_MILLISECONDS_MASK,
544 "SMEX Milliseconds", HFILL }
546 #if 0
547 { &hf_smex_spare,
548 { "Spare", "vcdu.smex.spare",
549 FT_UINT16, BASE_DEC, NULL, 0x003f,
550 "SMEX Spare", HFILL }
552 #endif
554 { &hf_vcdu_version,
555 { "Version", "vcdu.version",
556 FT_UINT16, BASE_DEC, NULL, 0xc0,
557 "VCDU Version", HFILL }
559 { &hf_vcdu_sp_id,
560 { "Space Craft ID", "vcdu.spid",
561 FT_UINT16, BASE_DEC, NULL, 0x3fc0,
562 "VCDU Space Craft ID", HFILL }
564 { &hf_vcdu_vc_id,
565 { "Virtual Channel ID", "vcdu.vcid",
566 FT_UINT16, BASE_DEC, NULL, 0x3f,
567 "VCDU Virtual Channel ID", HFILL }
569 { &hf_vcdu_seq,
570 { "Sequence Count", "vcdu.seq",
571 FT_UINT24, BASE_DEC, NULL, 0x0,
572 "VCDU Sequence Count", HFILL }
574 { &hf_vcdu_replay,
575 { "Replay Flag", "vcdu.replay",
576 FT_BOOLEAN, 8, NULL, 0x80,
577 "VCDU Replay Flag", HFILL }
580 /* Generated from convert_proto_tree_add_text.pl */
581 { &hf_vcdu_ground_receipt_time, { "Ground Receipt Time", "vcdu.ground_receipt_time", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
582 { &hf_vcdu_bitream_all_data, { "Bitream ALL Data", "vcdu.bitream.all_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
583 { &hf_vcdu_bitream_all_data_anomaly, { "Bitream ALL Data (Anomaly)", "vcdu.bitream.all_data_anomaly", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
584 { &hf_vcdu_bitream_all_fill, { "Bitream ALL Fill", "vcdu.bitream.all_fill", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
585 { &hf_vcdu_ccsds_all_fill, { "Ccsds ALL Fill", "vcdu.ccsds.all_fill", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
586 { &hf_vcdu_ccsds_continuation_packet, { "Ccsds Continuation Packet", "vcdu.ccsds_continuation_packet", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
587 { &hf_vcdu_data, { "Data", "vcdu.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
589 /* not really part of the vcdu header, but it's easier this way */
590 { &hf_vcdu_fhp,
591 { "First Header Pointer", "vcdu.fhp",
592 FT_UINT16, BASE_DEC, NULL, FHP_MASK,
593 "VCDU/MPDU First Header Pointer", HFILL }
595 { &hf_vcdu_lbp,
596 { "Last Bit Pointer", "vcdu.lbp",
597 FT_UINT16, BASE_DEC, NULL, LBP_MASK,
598 "VCDU/BPDU Last Bit Pointer", HFILL }
602 static uat_field_t vcdu_uat_flds[] = {
603 UAT_FLD_DEC(uat_bitchannels, channel, "Bitstream Channel", "Bitstream Channel"),
604 UAT_END_FIELDS
607 /* Setup protocol subtree array */
608 static int *ett[] = {
609 &ett_vcdu,
610 &ett_smex,
611 &ett_vcduh,
614 static ei_register_info ei[] = {
615 { &ei_vcdu_fhp_too_close_to_end_of_vcdu, { "vcdu.fhp_too_close_to_end_of_vcdu", PI_PROTOCOL, PI_WARN, "FHP too close to end of VCDU. Incomplete Hdr Info Available - Unable to format CCSDS Hdr(s).", EXPFILL }},
618 expert_module_t* expert_vcdu;
620 /* Register the protocol name and description */
621 proto_vcdu = proto_register_protocol("VCDU", "VCDU", "vcdu");
623 /* Required function calls to register the header fields and subtrees used */
624 proto_register_field_array(proto_vcdu, hf, array_length(hf));
625 proto_register_subtree_array(ett, array_length(ett));
626 expert_vcdu = expert_register_protocol(proto_vcdu);
627 expert_register_field_array(expert_vcdu, ei, array_length(ei));
629 /* XX: Does this dissector need to be publicly registered ?? */
630 vcdu_handle = register_dissector("vcdu", dissect_vcdu, proto_vcdu);
632 vcdu_module = prefs_register_protocol(proto_vcdu, vcdu_prefs_apply_cb);
634 vcdu_uat = uat_new("Bitstream Channel Table",
635 sizeof(uat_channel_t),
636 "vcdu_bitstream_channels",
637 true,
638 &uat_bitchannels,
639 &num_channels_uat,
640 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
641 NULL,
642 NULL,
643 vcdu_uat_data_update_cb,
644 NULL,
645 NULL,
646 NULL,
647 vcdu_uat_flds);
649 prefs_register_uat_preference(vcdu_module,
650 "bitstream_channels",
651 "Bitstream Channel Table",
652 "Bitstream Channel Table",
653 vcdu_uat);
658 void
659 proto_reg_handoff_vcdu(void)
661 dissector_add_for_decode_as_with_preference("udp.port", vcdu_handle);
662 ccsds_handle = find_dissector_add_dependency("ccsds", proto_vcdu);
666 * Editor modelines - https://www.wireshark.org/tools/modelines.html
668 * Local variables:
669 * c-basic-offset: 4
670 * tab-width: 8
671 * indent-tabs-mode: nil
672 * End:
674 * vi: set shiftwidth=4 tabstop=8 expandtab:
675 * :indentSize=4:tabSize=8:noTabs=true: