2009-03-18 07:29:36 +00:00
/* packet-vcdu.c
* Routines for VCDU dissection
* Copyright 2000 , Scott Hovis scott . hovis @ ums . msfc . nasa . gov
* Enhanced 2008 , Matt Dunkle Matthew . L . Dunkle @ nasa . gov
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . com >
* Copyright 1998 Gerald Combs
*
2018-02-12 11:23:27 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2009-03-18 07:29:36 +00:00
*/
2012-09-20 02:03:38 +00:00
# include "config.h"
2009-03-18 07:29:36 +00:00
# include <epan/packet.h>
2014-11-24 04:06:34 +00:00
# include <epan/expert.h>
2011-06-04 13:50:38 +00:00
# include <epan/prefs.h>
2013-12-21 17:23:17 +00:00
# include <epan/to_str.h>
2011-06-04 13:50:38 +00:00
# include <epan/uat.h>
2009-03-18 07:29:36 +00:00
2013-12-07 08:34:39 +00:00
void proto_register_vcdu ( void ) ;
void proto_reg_handoff_vcdu ( void ) ;
2009-03-18 07:29:36 +00:00
/* Initialize the protocol and registered fields */
static int proto_vcdu = - 1 ;
static int hf_smex_gsc = - 1 ;
2013-01-26 18:54:53 +00:00
/* static int hf_smex_unused = -1; */
2009-03-18 07:29:36 +00:00
static int hf_smex_version = - 1 ;
static int hf_smex_framelen = - 1 ;
static int hf_smex_rs_error = - 1 ;
static int hf_smex_rs_enable = - 1 ;
static int hf_smex_crc_enable = - 1 ;
static int hf_smex_crc_error = - 1 ;
static int hf_smex_mcs_enable = - 1 ;
static int hf_smex_mcs_num_error = - 1 ;
static int hf_smex_data_inv = - 1 ;
static int hf_smex_frame_sync = - 1 ;
static int hf_smex_data_dir = - 1 ;
static int hf_smex_data_class = - 1 ;
static int hf_smex_pb5 = - 1 ;
static int hf_smex_jday = - 1 ;
static int hf_smex_seconds = - 1 ;
static int hf_smex_msec = - 1 ;
2013-01-26 18:54:53 +00:00
/* static int hf_smex_spare = -1; */
2009-03-18 07:29:36 +00:00
static int hf_vcdu_version = - 1 ;
static int hf_vcdu_sp_id = - 1 ;
static int hf_vcdu_vc_id = - 1 ;
static int hf_vcdu_seq = - 1 ;
static int hf_vcdu_replay = - 1 ;
2014-11-24 04:06:34 +00:00
/* Generated from convert_proto_tree_add_text.pl */
static int hf_vcdu_data = - 1 ;
static int hf_vcdu_ground_receipt_time = - 1 ;
static int hf_vcdu_ccsds_all_fill = - 1 ;
static int hf_vcdu_bitream_all_fill = - 1 ;
static int hf_vcdu_bitream_all_data = - 1 ;
static int hf_vcdu_bitream_all_data_anomaly = - 1 ;
static int hf_vcdu_ccsds_continuation_packet = - 1 ;
2009-03-18 07:29:36 +00:00
/* although technically not part of the vcdu header, the
* first header pointer ( for ccsds ) , and the last bit
* pointer ( for bitstream ) , are more easily processed by
* simply adding them to the tail end of the vcdu header
* branch rather than creating a distinct branch for them
*/
static int hf_vcdu_fhp = - 1 ;
static int hf_vcdu_lbp = - 1 ;
2013-08-05 18:09:43 +00:00
static dissector_handle_t vcdu_handle ;
2009-03-19 01:54:09 +00:00
static dissector_handle_t ccsds_handle ;
2009-03-18 07:29:36 +00:00
/* Initialize the subtree pointers */
2013-01-26 18:54:53 +00:00
static gint ett_vcdu = - 1 ;
static gint ett_smex = - 1 ;
2009-03-18 07:29:36 +00:00
static gint ett_vcduh = - 1 ;
2014-11-24 04:06:34 +00:00
static expert_field ei_vcdu_fhp_too_close_to_end_of_vcdu = EI_INIT ;
2009-03-18 07:29:36 +00:00
/*
* Bits in the first 16 - bit header word
*/
2013-01-26 18:54:53 +00:00
# define SMEX_VERSION 0xc000
# define SMEX_FRAMELEN 0x3fff
2009-03-18 07:29:36 +00:00
/* some basic sizing parameters */
2013-01-26 18:54:53 +00:00
# define IP_HEADER_LENGTH 48
# define SMEX_HEADER_LENGTH 20
# define VCDU_HEADER_LENGTH 6
# define CCSDS_PRIMARY_HEADER_LENGTH 6
2009-03-18 07:29:36 +00:00
# define CCSDS_SECONDARY_HEADER_LENGTH 10
2013-01-26 18:54:53 +00:00
# define PB5_JULIAN_DAY_MASK 0x7ffe
# define PB5_SECONDS_MASK 0x01ffff
2009-03-18 07:29:36 +00:00
# define PB5_MILLISECONDS_MASK 0xffc0
2013-01-26 18:54:53 +00:00
# define LBP_ALL_DATA 0x3fff
# define LBP_ALL_DATA_ANOMALY 0x7ff
# define LBP_ALL_FILL 0x3ffe
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
# define FHP_ALL_FILL 0x7fe
# define FHP_CONTINUATION 0x7ff
2009-03-18 07:29:36 +00:00
# define LBP_MASK 0x3fff
# define FHP_MASK 0x7ff
/* leap year macro */
# ifndef Leap
# define Leap(yr) ( ( 0 == (yr)%4 && 0 != (yr)%100 ) || ( 0 == (yr)%400 ) )
# endif
static const value_string smex_data_inversion_type [ ] = {
2013-01-26 18:54:53 +00:00
{ 0 , " Data True (not inverted) " } ,
{ 1 , " Data Inverted (not corrected) " } ,
{ 2 , " Data Inversion State UNDEFINED " } ,
{ 3 , " Data Inverted (and corrected) " } ,
{ 0 , NULL }
2009-03-18 07:29:36 +00:00
} ;
static const value_string smex_frame_sync_mode [ ] = {
2013-01-26 18:54:53 +00:00
{ 0 , " Search " } ,
{ 1 , " Check " } ,
{ 2 , " Lock " } ,
{ 3 , " Flywheel " } ,
{ 0 , NULL }
2009-03-18 07:29:36 +00:00
} ;
static const value_string smex_data_direction [ ] = {
2013-01-26 18:54:53 +00:00
{ 0 , " Forward " } ,
{ 1 , " Reverse " } ,
{ 0 , NULL }
2009-03-18 07:29:36 +00:00
} ;
static const value_string smex_data_class [ ] = {
2013-01-26 18:54:53 +00:00
{ 0 , " Data Class UNDEFINED " } ,
{ 1 , " CCSDS Frame " } ,
{ 2 , " CCSDS Packet " } ,
{ 3 , " TDM Frame " } ,
{ 4 , " Stopped TDM Frame " } ,
{ 0 , NULL }
2009-03-18 07:29:36 +00:00
} ;
2011-06-04 13:50:38 +00:00
/* default bitstream channel assignments:
* the audio channels 4 - 6 are designated as bitstream channels
* the standard bitstream channels are 12 through 19
* the video channels 28 - 30 are designated as bitstream channels
* the fill channel 63 is designated as bitstream
*/
static int bitstream_channels [ ] =
{
2013-01-26 18:54:53 +00:00
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* channels 0-9 */
0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , /* channels 10-19 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* channels 20-29 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* channels 30-39 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* channels 40-49 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* channels 50-59 */
0 , 0 , 0 , 1 /* channels 60-63 */
2011-06-04 13:50:38 +00:00
} ;
typedef struct {
2013-01-26 18:54:53 +00:00
guint channel ;
2011-06-04 13:50:38 +00:00
} uat_channel_t ;
2013-01-26 18:54:53 +00:00
static uat_channel_t * uat_bitchannels = NULL ;
static uat_t * vcdu_uat = NULL ;
static guint num_channels_uat = 0 ;
2009-03-18 07:29:36 +00:00
2011-06-04 13:50:38 +00:00
UAT_DEC_CB_DEF ( uat_bitchannels , channel , uat_channel_t )
2015-02-18 00:40:28 +00:00
static gboolean
2015-01-13 20:13:45 +00:00
vcdu_uat_data_update_cb ( void * p , char * * err ) {
2013-03-19 22:03:00 +00:00
uat_channel_t * ud = ( uat_channel_t * ) p ;
2011-06-04 13:50:38 +00:00
2013-01-26 18:54:53 +00:00
if ( ud - > channel > = 64 ) {
2013-10-25 22:14:25 +00:00
* err = g_strdup ( " Channel must be between 0-63. " ) ;
2015-02-18 00:40:28 +00:00
return FALSE ;
2013-01-26 18:54:53 +00:00
}
2015-02-18 00:40:28 +00:00
return TRUE ;
2011-06-04 13:50:38 +00:00
}
2013-08-29 02:20:49 +00:00
static void
vcdu_prefs_apply_cb ( void )
2011-06-04 13:50:38 +00:00
{
2013-01-26 18:54:53 +00:00
guint i ;
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
if ( num_channels_uat > 0 )
{
2013-08-29 02:20:49 +00:00
memset ( bitstream_channels , 0 , sizeof ( bitstream_channels ) ) ;
2011-06-04 13:50:38 +00:00
2013-01-26 18:54:53 +00:00
for ( i = 0 ; i < num_channels_uat ; i + + )
{
bitstream_channels [ uat_bitchannels [ i ] . channel ] = 1 ;
}
}
2011-06-04 13:50:38 +00:00
}
2009-03-18 07:29:36 +00:00
/* convert smex PB5 header time to a human readable string - NOT THREAD SAFE
*
* note : this is not true PB5 time either , but a tsi specific version , although it is similar
*/
2013-08-29 02:20:49 +00:00
static const char *
smex_time_to_string ( int pb5_days_since_midnight_9_10_oct_1995 , int pb5_seconds , int pb5_milliseconds )
2009-03-18 07:29:36 +00:00
{
2013-01-26 18:54:53 +00:00
static int utcdiff = 0 ;
nstime_t t ;
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
static int Days [ 2 ] [ 13 ] =
2009-03-18 07:29:36 +00:00
{
2013-01-26 18:54:53 +00:00
{ 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ,
{ 0 , 31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }
2009-03-18 07:29:36 +00:00
} ;
2013-01-26 18:54:53 +00:00
int yr ;
int ix , days , month ;
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
/* compute the static constant difference in seconds
* between midnight 9 - 10 October 1995 ( PB5 time ) and
* seconds since 1 / 1 / 1970 ( UTC time ) just this once
*/
2013-08-29 02:20:49 +00:00
if ( 0 = = utcdiff )
2013-01-26 18:54:53 +00:00
{
2013-08-29 02:20:49 +00:00
for ( yr = 1970 ; yr < 1995 ; + + yr )
2009-03-18 07:29:36 +00:00
{
2013-08-29 02:20:49 +00:00
utcdiff + = ( Leap ( yr ) ? 366 : 365 ) * 24 * 60 * 60 ;
2013-01-26 18:54:53 +00:00
}
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
days = 0 ;
2013-08-29 02:20:49 +00:00
ix = ( Leap ( 1995 ) ? 1 : 0 ) ;
2009-03-18 07:29:36 +00:00
2013-08-29 02:20:49 +00:00
for ( month = 1 ; month < 10 ; + + month )
2013-01-26 18:54:53 +00:00
{
2009-03-18 07:29:36 +00:00
days + = Days [ ix ] [ month ] ;
2013-01-26 18:54:53 +00:00
}
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
days + = 9 ; /* this gets us up to midnight october 9-10 */
2009-03-18 07:29:36 +00:00
2013-01-26 18:54:53 +00:00
utcdiff + = days * 24 * 60 * 60 ; /* add days in 1995 prior to October 10 */
}
2009-03-18 07:29:36 +00:00
2013-08-29 02:20:49 +00:00
t . secs = ( pb5_days_since_midnight_9_10_oct_1995 * 86400 ) + pb5_seconds + utcdiff ;
2013-01-26 18:54:53 +00:00
t . nsecs = pb5_milliseconds * 1000000 ; /* msecs to nsecs */
2009-03-18 07:29:36 +00:00
2014-06-16 06:42:14 +00:00
return abs_time_to_str ( wmem_packet_scope ( ) , & t , ABSOLUTE_TIME_DOY_UTC , TRUE ) ;
2009-03-18 07:29:36 +00:00
}
2015-11-09 01:15:22 +00:00
static int
dissect_vcdu ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2009-03-18 07:29:36 +00:00
{
2013-01-26 18:54:53 +00:00
int offset = 0 ;
2015-01-21 20:33:36 +00:00
gboolean ccsds_tree_added = FALSE ;
2013-01-26 18:54:53 +00:00
2014-07-06 18:21:40 +00:00
proto_item * smex_header ;
proto_tree * smex_tree ;
2013-01-26 18:54:53 +00:00
2014-07-06 18:21:40 +00:00
proto_tree * vcdu_tree ;
2015-01-21 20:33:36 +00:00
proto_item * vcdu_item ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
guint16 first_word ;
guint32 long_word ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
int vcid , pb5_days , pb5_seconds , pb5_milliseconds ;
const char * time_string ;
2013-01-26 18:54:53 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " VCDU " ) ;
col_set_str ( pinfo - > cinfo , COL_INFO , " Virtual Channel Data Unit " ) ;
2015-01-21 20:33:36 +00:00
/* build the smex header tree */
smex_tree = proto_tree_add_subtree ( tree , tvb , offset , SMEX_HEADER_LENGTH , ett_smex , & smex_header , " SMEX Header " ) ;
proto_tree_add_item ( smex_tree , hf_smex_gsc , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
/* proto_tree_add_item(smex_tree, hf_smex_unused, tvb, offset, 2, ENC_BIG_ENDIAN); */
offset + = 2 ;
first_word = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_uint ( smex_tree , hf_smex_version , tvb , offset , 2 , first_word ) ;
proto_tree_add_uint ( smex_tree , hf_smex_framelen , tvb , offset , 2 , first_word ) ;
offset + = 2 ;
proto_tree_add_item ( smex_tree , hf_smex_rs_enable , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_rs_error , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_crc_enable , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_crc_error , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_mcs_enable , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_mcs_num_error , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_data_inv , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item ( smex_tree , hf_smex_frame_sync , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_data_dir , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_data_class , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
/* extract smex ground receipt time tag */
long_word = tvb_get_ntohl ( tvb , offset ) ;
pb5_days = ( long_word > > 17 ) & PB5_JULIAN_DAY_MASK ;
pb5_seconds = ( long_word & PB5_SECONDS_MASK ) ;
first_word = tvb_get_ntohs ( tvb , offset + 4 ) ;
pb5_milliseconds = ( first_word & PB5_MILLISECONDS_MASK ) > > 6 ;
proto_tree_add_item ( smex_tree , hf_smex_pb5 , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( smex_tree , hf_smex_jday , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item ( smex_tree , hf_smex_seconds , tvb , offset , 3 , ENC_BIG_ENDIAN ) ;
offset + = 3 ;
proto_tree_add_item ( smex_tree , hf_smex_msec , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
/* proto_tree_add_item(smex_tree, hf_smex_spare, tvb, offset, 2, ENC_BIG_ENDIAN); */
offset + = 2 ;
/* format ground receipt time into human readable time format for display */
time_string = smex_time_to_string ( pb5_days , pb5_seconds , pb5_milliseconds ) ;
proto_tree_add_string ( smex_tree , hf_vcdu_ground_receipt_time , tvb , offset - 6 , 6 , time_string ) ;
proto_item_set_end ( smex_header , tvb , offset ) ;
/* build the vcdu header tree */
vcdu_tree = proto_tree_add_subtree ( tree , tvb , offset , VCDU_HEADER_LENGTH , ett_vcdu , & vcdu_item , " VCDU Header " ) ;
/* extract the virtual channel for use later on */
first_word = tvb_get_ntohs ( tvb , offset ) ;
vcid = first_word & 0x3f ;
proto_tree_add_item ( vcdu_tree , hf_vcdu_version , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( vcdu_tree , hf_vcdu_sp_id , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( vcdu_tree , hf_vcdu_vc_id , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
proto_tree_add_item ( vcdu_tree , hf_vcdu_seq , tvb , offset , 3 , ENC_BIG_ENDIAN ) ;
offset + = 3 ;
proto_tree_add_item ( vcdu_tree , hf_vcdu_replay , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
/* extract mpdu/bpdu header word */
first_word = tvb_get_ntohs ( tvb , offset ) ;
/* do bitstream channel processing */
if ( bitstream_channels [ vcid ] )
2013-01-26 18:54:53 +00:00
{
2015-01-21 20:33:36 +00:00
guint16 new_ptr ;
/* extract last bit pointer for bitstream channels */
new_ptr = first_word & LBP_MASK ;
/* add last bit pointer to display tree */
proto_tree_add_item ( vcdu_tree , hf_vcdu_lbp , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
switch ( new_ptr )
2013-01-26 18:54:53 +00:00
{
2015-01-21 20:33:36 +00:00
case LBP_ALL_DATA :
proto_tree_add_item ( vcdu_tree , hf_vcdu_bitream_all_data , tvb , 0 , - 1 , ENC_NA ) ;
break ;
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
case LBP_ALL_DATA_ANOMALY :
proto_tree_add_item ( vcdu_tree , hf_vcdu_bitream_all_data_anomaly , tvb , 0 , - 1 , ENC_NA ) ;
break ;
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
case LBP_ALL_FILL :
proto_tree_add_item ( vcdu_tree , hf_vcdu_bitream_all_fill , tvb , 0 , - 1 , ENC_NA ) ;
break ;
default :
break ;
}
} /* end of bitstream channel processing */
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
/* do ccsds channel processing */
else
{
guint16 new_ptr ;
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
/* extract first header pointer for ccsds channels */
new_ptr = first_word & FHP_MASK ;
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
/* add first header pointer to display tree */
proto_tree_add_item ( vcdu_tree , hf_vcdu_fhp , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
/* process special cases of first header pointer */
if ( FHP_ALL_FILL = = new_ptr )
2013-01-26 18:54:53 +00:00
{
2015-01-21 20:33:36 +00:00
proto_tree_add_item ( vcdu_tree , hf_vcdu_ccsds_all_fill , tvb , 0 , - 1 , ENC_NA ) ;
}
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
else if ( FHP_CONTINUATION = = new_ptr )
{
proto_tree_add_item ( vcdu_tree , hf_vcdu_ccsds_continuation_packet , tvb , 0 , - 1 , ENC_NA ) ;
}
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
/* process as many ccsds packet headers as we can using the ccsds packet dissector */
else
{
int packet_boundary ;
int new_offset ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
/* compute offset and packet boundary lengths for ccsds dissector loop */
new_offset = offset + 2 + new_ptr ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
packet_boundary =
tvb_reported_length ( tvb ) - VCDU_HEADER_LENGTH
- CCSDS_PRIMARY_HEADER_LENGTH - CCSDS_SECONDARY_HEADER_LENGTH ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
while ( ( ( new_offset - offset + 2 ) < packet_boundary ) & & ( ( new_offset - offset + 2 ) > = 4 ) )
{
int ccsds_len ;
tvbuff_t * new_tvb ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
ccsds_tree_added = TRUE ;
ccsds_len = tvb_get_ntohs ( tvb , new_offset + 4 ) ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
new_tvb = tvb_new_subset_remaining ( tvb , new_offset ) ;
call_dissector ( ccsds_handle , new_tvb , pinfo , vcdu_tree ) ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
new_offset = new_offset + ccsds_len + 7 ;
}
2009-03-18 07:29:36 +00:00
2015-01-21 20:33:36 +00:00
if ( ! ccsds_tree_added )
{
proto_tree_add_expert ( vcdu_tree , pinfo , & ei_vcdu_fhp_too_close_to_end_of_vcdu , tvb , 0 , - 1 ) ;
2013-01-26 18:54:53 +00:00
}
2015-01-21 20:33:36 +00:00
}
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
} /* end of ccsds channel processing */
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
/* don't include the mpdu/bpdu header in the vcdu header highlighting.
* by skipping the offset bump the vcdu header highlighting will show
* just 6 bytes as it really should , and the fhp / lbp will be included
* in the data zone , which is technically more correct .
*/
/* offset += 2; */
proto_item_set_end ( vcdu_item , tvb , offset ) ;
2013-01-26 18:54:53 +00:00
2015-01-21 20:33:36 +00:00
if ( ! ccsds_tree_added )
{
/* add "Data" section if ccsds parsing did not do so already */
proto_tree_add_item ( vcdu_tree , hf_vcdu_data , tvb , offset , - 1 , ENC_NA ) ;
2013-01-26 18:54:53 +00:00
}
2015-11-09 01:15:22 +00:00
return tvb_captured_length ( tvb ) ;
2009-03-18 07:29:36 +00:00
}
void
proto_register_vcdu ( void )
2013-01-26 18:54:53 +00:00
{
module_t * vcdu_module ;
/* Setup list of header fields See Section 1.6.1 for details*/
static hf_register_info hf [ ] = {
{ & hf_smex_gsc ,
{ " Ground Sequence Counter " , " vcdu.smex.gsc " ,
FT_UINT64 , BASE_DEC , NULL , 0x0 ,
" SMEX Ground Sequence Counter " , HFILL }
} ,
2013-01-31 18:31:28 +00:00
#if 0
2013-01-26 18:54:53 +00:00
{ & hf_smex_unused ,
{ " Unused " , " vcdu.smex.unused " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" SMEX Unused " , HFILL }
} ,
2013-01-31 18:31:28 +00:00
# endif
2013-01-26 18:54:53 +00:00
{ & hf_smex_version ,
{ " Version " , " vcdu.smex.version " ,
FT_UINT16 , BASE_DEC , NULL , SMEX_VERSION ,
" SMEX Version " , HFILL }
} ,
{ & hf_smex_framelen ,
{ " Frame Length " , " vcdu.smex.frame_len " ,
FT_UINT16 , BASE_DEC , NULL , SMEX_FRAMELEN ,
" SMEX Frame Length " , HFILL }
} ,
{ & hf_smex_rs_enable ,
{ " RS Enable " , " vcdu.smex.rs_enable " ,
FT_BOOLEAN , 8 , NULL , 0x80 ,
" SMEX RS Enable " , HFILL }
} ,
{ & hf_smex_rs_error ,
{ " RS Error " , " vcdu.smex.rs_error " ,
FT_BOOLEAN , 8 , NULL , 0x40 ,
" SMEX RS Error " , HFILL }
} ,
{ & hf_smex_crc_enable ,
{ " CRC Enable " , " vcdu.smex.crc_enable " ,
FT_BOOLEAN , 8 , NULL , 0x20 ,
" SMEX CRC Enable " , HFILL }
} ,
{ & hf_smex_crc_error ,
{ " CRC Error " , " vcdu.smex.crc_error " ,
FT_BOOLEAN , 8 , NULL , 0x10 ,
" SMEX CRC Error " , HFILL }
} ,
{ & hf_smex_mcs_enable ,
{ " MCS Enable " , " vcdu.smex.mcs_enable " ,
FT_BOOLEAN , 8 , NULL , 0x08 ,
" SMEX MCS Enable " , HFILL }
} ,
{ & hf_smex_mcs_num_error ,
{ " MCS Number Error " , " vcdu.smex.mcs_numerr " ,
FT_BOOLEAN , 8 , NULL , 0x04 ,
" SMEX MCS Number Error " , HFILL }
} ,
{ & hf_smex_data_inv ,
{ " Data Inversion " , " vcdu.smex.data_inv " ,
FT_UINT16 , BASE_DEC , VALS ( smex_data_inversion_type ) , 0x03 ,
" SMEX Data Inversion " , HFILL }
} ,
{ & hf_smex_frame_sync ,
{ " Frame Sync " , " vcdu.smex.frame_sync " ,
FT_UINT16 , BASE_DEC , VALS ( smex_frame_sync_mode ) , 0xc0 ,
" SMEX Frame Sync Flag " , HFILL }
} ,
{ & hf_smex_data_dir ,
{ " Data Direction " , " vcdu.smex.data_dir " ,
FT_UINT16 , BASE_DEC , VALS ( smex_data_direction ) , 0x20 ,
" SMEX Data Direction flag " , HFILL }
} ,
{ & hf_smex_data_class ,
{ " Data Class " , " vcdu.smex.data_class " ,
FT_UINT16 , BASE_DEC , VALS ( smex_data_class ) , 0x1f ,
" SMEX Data Class " , HFILL }
} ,
{ & hf_smex_pb5 ,
{ " PB5 Flag " , " vcdu.smex.pb5 " ,
FT_UINT16 , BASE_DEC , NULL , 0x8000 ,
" SMEX PB5 Flag " , HFILL }
} ,
{ & hf_smex_jday ,
{ " Julian Day " , " vcdu.smex.jday " ,
FT_UINT16 , BASE_DEC , NULL , PB5_JULIAN_DAY_MASK ,
" SMEX Julian Day " , HFILL }
} ,
{ & hf_smex_seconds ,
{ " Seconds " , " vcdu.smex.seconds " ,
FT_UINT24 , BASE_DEC , NULL , PB5_SECONDS_MASK ,
" SMEX Seconds " , HFILL }
} ,
{ & hf_smex_msec ,
{ " Milliseconds " , " vcdu.smex.msec " ,
FT_UINT16 , BASE_DEC , NULL , PB5_MILLISECONDS_MASK ,
" SMEX Milliseconds " , HFILL }
} ,
2013-01-31 18:31:28 +00:00
#if 0
2013-01-26 18:54:53 +00:00
{ & hf_smex_spare ,
{ " Spare " , " vcdu.smex.spare " ,
FT_UINT16 , BASE_DEC , NULL , 0x03f ,
" SMEX Spare " , HFILL }
} ,
2013-01-31 18:31:28 +00:00
# endif
2013-01-26 18:54:53 +00:00
{ & hf_vcdu_version ,
{ " Version " , " vcdu.version " ,
FT_UINT16 , BASE_DEC , NULL , 0xc0 ,
" VCDU Version " , HFILL }
} ,
{ & hf_vcdu_sp_id ,
{ " Space Craft ID " , " vcdu.spid " ,
FT_UINT16 , BASE_DEC , NULL , 0x3fc0 ,
" VCDU Space Craft ID " , HFILL }
} ,
{ & hf_vcdu_vc_id ,
{ " Virtual Channel ID " , " vcdu.vcid " ,
FT_UINT16 , BASE_DEC , NULL , 0x3f ,
" VCDU Virtual Channel ID " , HFILL }
} ,
{ & hf_vcdu_seq ,
{ " Sequence Count " , " vcdu.seq " ,
FT_UINT16 , BASE_DEC , NULL , 0xffffff ,
" VCDU Sequence Count " , HFILL }
} ,
{ & hf_vcdu_replay ,
{ " Replay Flag " , " vcdu.replay " ,
FT_BOOLEAN , 8 , NULL , 0x80 ,
" VCDU Replay Flag " , HFILL }
} ,
2014-11-24 04:06:34 +00:00
/* Generated from convert_proto_tree_add_text.pl */
{ & hf_vcdu_ground_receipt_time , { " Ground Receipt Time " , " vcdu.ground_receipt_time " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_bitream_all_data , { " Bitream ALL Data " , " vcdu.bitream.all_data " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_bitream_all_data_anomaly , { " Bitream ALL Data (Anomaly) " , " vcdu.bitream.all_data_anomaly " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_bitream_all_fill , { " Bitream ALL Fill " , " vcdu.bitream.all_fill " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_ccsds_all_fill , { " Ccsds ALL Fill " , " vcdu.ccsds.all_fill " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_ccsds_continuation_packet , { " Ccsds Continuation Packet " , " vcdu.ccsds_continuation_packet " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vcdu_data , { " Data " , " vcdu.data " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2013-01-26 18:54:53 +00:00
/* not really part of the vcdu header, but it's easier this way */
{ & hf_vcdu_fhp ,
{ " First Header Pointer " , " vcdu.fhp " ,
FT_UINT16 , BASE_DEC , NULL , FHP_MASK ,
" VCDU/MPDU First Header Pointer " , HFILL }
} ,
{ & hf_vcdu_lbp ,
{ " Last Bit Pointer " , " vcdu.lbp " ,
FT_UINT16 , BASE_DEC , NULL , LBP_MASK ,
" VCDU/BPDU Last Bit Pointer " , HFILL }
}
} ;
static uat_field_t vcdu_uat_flds [ ] = {
UAT_FLD_DEC ( uat_bitchannels , channel , " Bitstream Channel " , " Bitstream Channel " ) ,
UAT_END_FIELDS
} ;
/* Setup protocol subtree array */
static gint * ett [ ] = {
& ett_vcdu ,
& ett_smex ,
& ett_vcduh ,
} ;
2014-11-24 04:06:34 +00:00
static ei_register_info ei [ ] = {
{ & 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 } } ,
} ;
expert_module_t * expert_vcdu ;
2013-01-26 18:54:53 +00:00
/* Register the protocol name and description */
proto_vcdu = proto_register_protocol ( " VCDU " , " VCDU " , " vcdu " ) ;
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array ( proto_vcdu , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2014-11-24 04:06:34 +00:00
expert_vcdu = expert_register_protocol ( proto_vcdu ) ;
expert_register_field_array ( expert_vcdu , ei , array_length ( ei ) ) ;
2013-01-26 18:54:53 +00:00
/* XX: Does this dissector need to be publicly registered ?? */
2015-12-09 04:04:01 +00:00
vcdu_handle = register_dissector ( " vcdu " , dissect_vcdu , proto_vcdu ) ;
2013-01-26 18:54:53 +00:00
vcdu_module = prefs_register_protocol ( proto_vcdu , vcdu_prefs_apply_cb ) ;
vcdu_uat = uat_new ( " Bitstream Channel Table " ,
sizeof ( uat_channel_t ) ,
" vcdu_bitstream_channels " ,
TRUE ,
2014-01-30 17:43:52 +00:00
& uat_bitchannels ,
2013-01-26 18:54:53 +00:00
& num_channels_uat ,
UAT_AFFECTS_DISSECTION , /* affects dissection of packets, but not set of named fields */
NULL ,
NULL ,
vcdu_uat_data_update_cb ,
NULL ,
NULL ,
2016-12-21 10:50:47 +00:00
NULL ,
2013-01-26 18:54:53 +00:00
vcdu_uat_flds ) ;
prefs_register_uat_preference ( vcdu_module ,
" bitstream_channels " ,
" Bitstream Channel Table " ,
" Bitstream Channel Table " ,
vcdu_uat ) ;
2011-06-04 13:50:38 +00:00
2009-03-18 07:29:36 +00:00
}
void
proto_reg_handoff_vcdu ( void )
{
2016-10-05 20:33:54 +00:00
dissector_add_for_decode_as_with_preference ( " udp.port " , vcdu_handle ) ;
2016-03-16 13:02:52 +00:00
ccsds_handle = find_dissector_add_dependency ( " ccsds " , proto_vcdu ) ;
2009-03-18 07:29:36 +00:00
}
2014-09-29 18:07:49 +00:00
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* vi : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/