2016-01-26 01:17:21 +00:00
/* wtap_opttypes.c
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 2001 Gerald Combs
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include "config.h"
# include <glib.h>
# include <string.h>
# include "wtap.h"
# include "wtap_opttypes.h"
# include "wtap-int.h"
# include "pcapng.h"
2016-03-04 13:52:48 +00:00
# include "pcapng_module.h"
#if 0
# define wtap_debug(...) g_warning(__VA_ARGS__)
# else
# define wtap_debug(...)
# endif
2016-01-26 01:17:21 +00:00
2016-03-02 14:13:08 +00:00
typedef struct wtap_opt_register
2016-01-26 01:17:21 +00:00
{
const char * name ; /**< name of block */
const char * description ; /**< human-readable description of block */
2016-03-02 14:13:08 +00:00
wtap_block_create_func create ;
2016-03-04 13:52:48 +00:00
wtap_write_func write ;
2016-03-02 14:13:08 +00:00
wtap_mand_free_func free_mand ;
wtap_mand_copy_func copy_mand ;
} wtap_opt_register_t ;
2016-03-04 13:52:48 +00:00
typedef struct wtap_optblock_internal {
const char * name ; /**< name of option */
const char * description ; /**< human-readable description of option */
guint number ; /**< Option index */
wtap_opttype_e type ; /**< type of that option */
wtap_opttype_option_write_size write_size ; /**< Number of bytes to write to file (0 for don't write) */
wtap_opttype_option_write write_data ; /**< write option data to dumper */
} wtap_optblock_internal_t ;
typedef struct wtap_optblock_value {
wtap_optblock_internal_t * info ;
wtap_option_type option ; /**< pointer to variable storing the value */
wtap_option_type default_val ; /**< the default value of the option */
} wtap_optblock_value_t ;
2016-03-02 14:13:08 +00:00
struct wtap_optionblock
{
wtap_opt_register_t * info ;
2016-01-26 01:17:21 +00:00
void * mandatory_data ;
2016-03-04 13:52:48 +00:00
GArray * option_infos ; /* Only want to keep 1 copy of "static" option information */
GArray * option_values ;
2016-01-26 01:17:21 +00:00
} ;
2016-05-18 02:50:51 +00:00
# define MAX_WTAP_OPTION_BLOCK_CUSTOM 10
# define MAX_WTAP_OPTION_BLOCK_TYPE_VALUE (WTAP_OPTION_BLOCK_END_OF_LIST+MAX_WTAP_OPTION_BLOCK_CUSTOM)
2016-03-02 14:13:08 +00:00
/* Keep track of wtap_opt_register_t's via their id number */
2016-05-18 02:50:51 +00:00
static wtap_opt_register_t * block_list [ MAX_WTAP_OPTION_BLOCK_TYPE_VALUE ] ;
static guint num_custom_blocks ;
static wtap_opt_register_t custom_block_list [ MAX_WTAP_OPTION_BLOCK_CUSTOM ] ;
2016-03-02 14:13:08 +00:00
static void wtap_opttype_block_register ( int block_type , wtap_opt_register_t * block )
2016-01-26 01:17:21 +00:00
{
2016-03-02 14:13:08 +00:00
/* Check input */
2016-05-18 02:50:51 +00:00
g_assert ( block_type < WTAP_OPTION_BLOCK_END_OF_LIST ) ;
2016-03-02 14:13:08 +00:00
/* Don't re-register. */
g_assert ( block_list [ block_type ] = = NULL ) ;
/* Sanity check */
g_assert ( block - > name ) ;
g_assert ( block - > description ) ;
g_assert ( block - > create ) ;
block_list [ block_type ] = block ;
2016-01-26 01:17:21 +00:00
}
2016-05-18 02:50:51 +00:00
int wtap_opttype_register_custom_block_type ( const char * name , const char * description , wtap_block_create_func create ,
wtap_write_func write_func , wtap_mand_free_func free_mand , wtap_mand_copy_func copy_mand )
{
int block_type ;
/* Ensure valid data/functions for required fields */
g_assert ( name ) ;
g_assert ( description ) ;
g_assert ( create ) ;
/* This shouldn't happen, so flag it for fixing */
g_assert ( num_custom_blocks < MAX_WTAP_OPTION_BLOCK_CUSTOM ) ;
block_type = WTAP_OPTION_BLOCK_END_OF_LIST + num_custom_blocks ;
custom_block_list [ num_custom_blocks ] . name = name ;
custom_block_list [ num_custom_blocks ] . description = description ;
custom_block_list [ num_custom_blocks ] . create = create ;
custom_block_list [ num_custom_blocks ] . write = write_func ;
custom_block_list [ num_custom_blocks ] . free_mand = free_mand ;
custom_block_list [ num_custom_blocks ] . copy_mand = copy_mand ;
block_list [ block_type ] = & custom_block_list [ num_custom_blocks ] ;
num_custom_blocks + + ;
return block_type ;
}
2016-03-02 14:13:08 +00:00
void * wtap_optionblock_get_mandatory_data ( wtap_optionblock_t block )
2016-01-26 01:17:21 +00:00
{
2016-03-02 14:13:08 +00:00
return block - > mandatory_data ;
2016-01-26 01:17:21 +00:00
}
2016-03-04 13:52:48 +00:00
static wtap_optblock_value_t * wtap_optionblock_get_option ( wtap_optionblock_t block , guint option_id )
2016-01-26 01:17:21 +00:00
{
2016-03-02 14:13:08 +00:00
guint i ;
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opttype = NULL ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
for ( i = 0 ; i < block - > option_values - > len ; i + + )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
opttype = g_array_index ( block - > option_values , wtap_optblock_value_t * , i ) ;
if ( opttype - > info - > number = = option_id )
2016-03-02 14:13:08 +00:00
return opttype ;
2016-01-26 01:17:21 +00:00
}
2016-03-02 14:13:08 +00:00
return NULL ;
}
2016-05-18 02:50:51 +00:00
wtap_optionblock_t wtap_optionblock_create ( int block_type )
2016-03-02 14:13:08 +00:00
{
wtap_optionblock_t block ;
2016-05-18 02:50:51 +00:00
if ( block_type > = ( int ) ( WTAP_OPTION_BLOCK_END_OF_LIST + num_custom_blocks ) )
2016-03-02 14:13:08 +00:00
return NULL ;
block = g_new ( struct wtap_optionblock , 1 ) ;
block - > info = block_list [ block_type ] ;
2016-03-04 13:52:48 +00:00
block - > option_infos = g_array_new ( FALSE , FALSE , sizeof ( wtap_optblock_internal_t * ) ) ;
block - > option_values = g_array_new ( FALSE , FALSE , sizeof ( wtap_optblock_value_t * ) ) ;
2016-03-02 14:13:08 +00:00
block - > info - > create ( block ) ;
2016-01-26 01:17:21 +00:00
return block ;
}
static void wtap_optionblock_free_options ( wtap_optionblock_t block )
{
guint i ;
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opttype = NULL ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
for ( i = 0 ; i < block - > option_values - > len ; i + + ) {
opttype = g_array_index ( block - > option_values , wtap_optblock_value_t * , i ) ;
switch ( opttype - > info - > type )
2016-01-26 01:17:21 +00:00
{
case WTAP_OPTTYPE_STRING :
g_free ( opttype - > option . stringval ) ;
break ;
case WTAP_OPTTYPE_CUSTOM :
opttype - > option . customval . free_func ( opttype - > option . customval . data ) ;
g_free ( opttype - > option . customval . data ) ;
opttype - > default_val . customval . free_func ( opttype - > default_val . customval . data ) ;
g_free ( opttype - > default_val . customval . data ) ;
break ;
default :
break ;
}
g_free ( opttype ) ;
}
}
void wtap_optionblock_free ( wtap_optionblock_t block )
{
2016-04-19 10:23:53 +00:00
unsigned i ;
2016-01-26 01:17:21 +00:00
if ( block ! = NULL )
{
2016-03-02 14:13:08 +00:00
if ( block - > info - > free_mand ! = NULL )
block - > info - > free_mand ( block ) ;
2016-01-26 01:17:21 +00:00
g_free ( block - > mandatory_data ) ;
wtap_optionblock_free_options ( block ) ;
2016-04-19 10:23:53 +00:00
for ( i = 0 ; i < block - > option_infos - > len ; i + + )
g_free ( g_array_index ( block - > option_infos , wtap_optblock_internal_t * , i ) ) ;
2016-03-04 13:52:48 +00:00
if ( block - > option_infos ! = NULL )
2016-04-19 10:23:53 +00:00
g_array_free ( block - > option_infos , TRUE ) ;
2016-03-04 13:52:48 +00:00
if ( block - > option_values ! = NULL )
2016-04-19 10:23:53 +00:00
g_array_free ( block - > option_values , TRUE ) ;
2016-01-26 01:17:21 +00:00
g_free ( block ) ;
}
}
2016-03-02 14:13:08 +00:00
void wtap_optionblock_copy_options ( wtap_optionblock_t dest_block , wtap_optionblock_t src_block )
2016-01-26 01:17:21 +00:00
{
guint i ;
2016-03-04 13:52:48 +00:00
wtap_optblock_internal_t * src_internal ;
wtap_optblock_value_t * dest_value , * src_value ;
2016-01-26 01:17:21 +00:00
2016-03-02 14:13:08 +00:00
if ( dest_block - > info - > copy_mand ! = NULL )
dest_block - > info - > copy_mand ( dest_block , src_block ) ;
/* Copy the options. For now, don't remove any options that are in destination
* but not source .
*/
2016-03-04 13:52:48 +00:00
for ( i = 0 ; i < src_block - > option_values - > len ; i + + )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
src_internal = g_array_index ( src_block - > option_infos , wtap_optblock_internal_t * , i ) ;
src_value = g_array_index ( src_block - > option_values , wtap_optblock_value_t * , i ) ;
dest_value = wtap_optionblock_get_option ( dest_block , src_internal - > number ) ;
if ( dest_value = = NULL )
2016-03-02 14:13:08 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_reg_t reg_optblock ;
reg_optblock . name = src_internal - > name ;
reg_optblock . description = src_internal - > description ;
reg_optblock . type = src_internal - > type ;
2016-03-09 02:22:27 +00:00
reg_optblock . write_size_func = src_internal - > write_size ;
reg_optblock . write_func = src_internal - > write_data ;
2016-03-04 13:52:48 +00:00
reg_optblock . option = src_value - > option ;
reg_optblock . default_val = src_value - > default_val ;
wtap_optionblock_add_option ( dest_block , src_internal - > number , & reg_optblock ) ;
2016-03-02 14:13:08 +00:00
}
else
{
/* Option exists, replace it */
2016-03-04 13:52:48 +00:00
switch ( src_internal - > type )
2016-03-02 14:13:08 +00:00
{
case WTAP_OPTTYPE_UINT8 :
2016-03-04 13:52:48 +00:00
dest_value - > option . uint8val = src_value - > option . uint8val ;
2016-03-02 14:13:08 +00:00
break ;
case WTAP_OPTTYPE_UINT64 :
2016-03-04 13:52:48 +00:00
dest_value - > option . uint64val = src_value - > option . uint64val ;
2016-03-02 14:13:08 +00:00
break ;
case WTAP_OPTTYPE_STRING :
2016-03-04 13:52:48 +00:00
g_free ( dest_value - > option . stringval ) ;
dest_value - > option . stringval = g_strdup ( src_value - > option . stringval ) ;
2016-03-02 14:13:08 +00:00
break ;
case WTAP_OPTTYPE_CUSTOM :
2016-03-04 13:52:48 +00:00
dest_value - > option . customval . free_func ( dest_value - > option . customval . data ) ;
g_free ( dest_value - > option . customval . data ) ;
dest_value - > option . customval . data = g_memdup ( src_value - > option . customval . data , src_value - > option . customval . size ) ;
2016-03-02 14:13:08 +00:00
break ;
}
}
2016-01-26 01:17:21 +00:00
}
}
2016-03-04 13:52:48 +00:00
gboolean wtap_optionblock_write ( struct wtap_dumper * wdh , wtap_optionblock_t block , int * err )
{
if ( ( block = = NULL ) | | ( block - > info - > write = = NULL ) )
{
* err = WTAP_ERR_INTERNAL ;
return FALSE ;
}
return block - > info - > write ( wdh , block , err ) ;
}
static guint32 wtap_optionblock_get_option_write_size ( wtap_optionblock_t block )
{
guint i ;
guint32 options_total_length = 0 , length ;
wtap_optblock_value_t * value ;
for ( i = 0 ; i < block - > option_values - > len ; i + + )
{
value = g_array_index ( block - > option_values , wtap_optblock_value_t * , i ) ;
if ( ( value - > info - > write_size ! = NULL ) & & ( value - > info - > write_data ! = NULL ) )
{
length = value - > info - > write_size ( & value - > option ) ;
options_total_length + = length ;
/* Add bytes for option header if option should be written */
2016-05-04 17:06:30 +00:00
if ( length > 0 ) {
/* Add optional padding to 32 bits */
if ( ( options_total_length & 0x03 ) ! = 0 )
{
options_total_length + = 4 - ( options_total_length & 0x03 ) ;
}
2016-03-04 13:52:48 +00:00
options_total_length + = 4 ;
2016-05-04 17:06:30 +00:00
}
2016-03-04 13:52:48 +00:00
}
}
return options_total_length ;
}
static gboolean wtap_optionblock_write_options ( struct wtap_dumper * wdh , wtap_optionblock_t block , guint32 options_total_length , int * err )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
guint i ;
wtap_optblock_value_t * value ;
struct pcapng_option_header option_hdr ;
guint32 length ;
/* Check if we have at least 1 option to write */
if ( options_total_length = = 0 )
return TRUE ;
for ( i = 0 ; i < block - > option_values - > len ; i + + )
{
value = g_array_index ( block - > option_values , wtap_optblock_value_t * , i ) ;
if ( ( value - > info - > write_size ! = NULL ) & & ( value - > info - > write_data ! = NULL ) & &
( ( length = value - > info - > write_size ( & value - > option ) ) > 0 ) )
{
/* Write the option */
wtap_debug ( " wtap_optionblock_write %s, field:'%s' length: %u " , block - > description , value - > info - > description , length ) ;
/* String options don't consider pad bytes part of the length, so readjust here */
if ( value - > info - > type = = WTAP_OPTTYPE_STRING )
length = ( guint32 ) strlen ( value - > option . stringval ) & 0xffff ;
option_hdr . type = value - > info - > number ;
option_hdr . value_length = length ;
if ( ! wtap_dump_file_write ( wdh , & option_hdr , 4 , err ) )
return FALSE ;
wdh - > bytes_dumped + = 4 ;
if ( ! value - > info - > write_data ( wdh , & value - > option , err ) )
return FALSE ;
}
}
/* Write end of options */
option_hdr . type = OPT_EOFOPT ;
option_hdr . value_length = 0 ;
if ( ! wtap_dump_file_write ( wdh , & option_hdr , 4 , err ) )
return FALSE ;
wdh - > bytes_dumped + = 4 ;
return TRUE ;
}
int wtap_optionblock_add_option ( wtap_optionblock_t block , guint option_id , wtap_optblock_reg_t * option )
{
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
wtap_optblock_internal_t * opt_internal ;
2016-01-26 01:17:21 +00:00
/* Option already exists */
2016-03-04 13:52:48 +00:00
if ( opt_value ! = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_ALREADY_EXISTS ;
2016-03-04 13:52:48 +00:00
opt_value = g_new0 ( wtap_optblock_value_t , 1 ) ;
opt_internal = g_new ( wtap_optblock_internal_t , 1 ) ;
opt_internal - > name = option - > name ;
opt_internal - > description = option - > description ;
opt_internal - > number = option_id ;
opt_internal - > type = option - > type ;
opt_internal - > write_size = option - > write_size_func ;
opt_internal - > write_data = option - > write_func ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
opt_value - > info = opt_internal ;
switch ( option - > type )
{
case WTAP_OPTTYPE_UINT8 :
opt_value - > option . uint8val = option - > option . uint8val ;
opt_value - > default_val . uint8val = option - > default_val . uint8val ;
break ;
case WTAP_OPTTYPE_UINT64 :
opt_value - > option . uint64val = option - > option . uint64val ;
opt_value - > default_val . uint64val = option - > default_val . uint64val ;
break ;
case WTAP_OPTTYPE_STRING :
opt_value - > option . stringval = g_strdup ( option - > option . stringval ) ;
opt_value - > default_val . stringval = option - > default_val . stringval ;
break ;
case WTAP_OPTTYPE_CUSTOM :
opt_value - > option . customval . size = option - > option . customval . size ;
opt_value - > option . customval . data = g_memdup ( option - > option . customval . data , option - > option . customval . size ) ;
opt_value - > option . customval . free_func = option - > option . customval . free_func ;
opt_value - > default_val . customval . size = option - > default_val . customval . size ;
opt_value - > default_val . customval . data = g_memdup ( option - > default_val . customval . data , option - > default_val . customval . size ) ;
opt_value - > default_val . customval . free_func = option - > default_val . customval . free_func ;
break ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
g_array_append_val ( block - > option_infos , opt_internal ) ;
g_array_append_val ( block - > option_values , opt_value ) ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_set_option_string ( wtap_optionblock_t block , guint option_id , char * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_STRING )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
g_free ( opt_value - > option . stringval ) ;
opt_value - > option . stringval = g_strdup ( value ) ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_get_option_string ( wtap_optionblock_t block , guint option_id , char * * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_STRING )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
* value = opt_value - > option . stringval ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
guint32 wtap_opttype_write_size_string ( wtap_option_type * data )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
guint32 size , pad ;
if ( ( data = = NULL ) | | ( data - > stringval = = NULL ) )
return 0 ;
size = ( guint32 ) strlen ( data - > stringval ) & 0xffff ;
if ( ( size % 4 ) ) {
pad = 4 - ( size % 4 ) ;
} else {
pad = 0 ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
return size + pad ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
gboolean wtap_opttype_write_data_string ( struct wtap_dumper * wdh , wtap_option_type * data , int * err )
{
guint32 size = ( guint32 ) strlen ( data - > stringval ) & 0xffff ;
guint32 pad ;
const guint32 zero_pad = 0 ;
if ( ! wtap_dump_file_write ( wdh , data - > stringval , size , err ) )
return FALSE ;
wdh - > bytes_dumped + = size ;
if ( ( size % 4 ) ) {
pad = 4 - ( size % 4 ) ;
} else {
pad = 0 ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
/* write padding (if any) */
if ( pad ! = 0 ) {
if ( ! wtap_dump_file_write ( wdh , & zero_pad , pad , err ) )
return FALSE ;
wdh - > bytes_dumped + = pad ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
return TRUE ;
2016-01-26 01:17:21 +00:00
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_set_option_uint64 ( wtap_optionblock_t block , guint option_id , guint64 value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_UINT64 )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
opt_value - > option . uint64val = value ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_get_option_uint64 ( wtap_optionblock_t block , guint option_id , guint64 * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_UINT64 )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
* value = opt_value - > option . uint64val ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
guint32 wtap_opttype_write_uint64_not0 ( wtap_option_type * data )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
if ( data = = NULL )
return 0 ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
if ( data - > uint64val = = 0 )
return 0 ;
/* value */
return 8 ;
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
guint32 wtap_opttype_write_uint64_not_minus1 ( wtap_option_type * data )
{
if ( data = = NULL )
return 0 ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
if ( data - > uint64val = = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) )
return 0 ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
/* value */
return 8 ;
}
gboolean wtap_opttype_write_data_uint64 ( struct wtap_dumper * wdh , wtap_option_type * data , int * err )
{
if ( ! wtap_dump_file_write ( wdh , & data - > uint64val , sizeof ( guint64 ) , err ) )
return FALSE ;
wdh - > bytes_dumped + = 8 ;
return TRUE ;
2016-01-26 01:17:21 +00:00
}
2016-05-17 21:04:04 +00:00
gboolean wtap_opttype_write_data_uint64_timestamp ( struct wtap_dumper * wdh , wtap_option_type * data , int * err )
{
guint32 high , low ;
high = ( guint32 ) ( data - > uint64val > > 32 ) ;
low = ( guint32 ) ( data - > uint64val > > 0 ) ;
if ( ! wtap_dump_file_write ( wdh , & high , sizeof ( guint32 ) , err ) )
return FALSE ;
wdh - > bytes_dumped + = 4 ;
if ( ! wtap_dump_file_write ( wdh , & low , sizeof ( guint32 ) , err ) )
return FALSE ;
wdh - > bytes_dumped + = 4 ;
return TRUE ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_set_option_uint8 ( wtap_optionblock_t block , guint option_id , guint8 value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_UINT8 )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
opt_value - > option . uint8val = value ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_get_option_uint8 ( wtap_optionblock_t block , guint option_id , guint8 * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_UINT8 )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
* value = opt_value - > option . uint8val ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
guint32 wtap_opttype_write_uint8_not0 ( wtap_option_type * data )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
if ( data = = NULL )
return 0 ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
if ( data - > uint8val = = 0 )
return 0 ;
2016-01-26 01:17:21 +00:00
2016-05-04 17:06:30 +00:00
return 1 ;
2016-03-04 13:52:48 +00:00
}
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
gboolean wtap_opttype_write_data_uint8 ( struct wtap_dumper * wdh , wtap_option_type * data , int * err )
{
const guint32 zero_pad = 0 ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
if ( ! wtap_dump_file_write ( wdh , & data - > uint8val , 1 , err ) )
return FALSE ;
wdh - > bytes_dumped + = 1 ;
if ( ! wtap_dump_file_write ( wdh , & zero_pad , 3 , err ) )
return FALSE ;
wdh - > bytes_dumped + = 3 ;
return TRUE ;
2016-01-26 01:17:21 +00:00
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_set_option_custom ( wtap_optionblock_t block , guint option_id , void * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
void * prev_value ;
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_CUSTOM )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
prev_value = opt_value - > option . customval . data ;
opt_value - > option . customval . data = g_memdup ( value , opt_value - > option . customval . size ) ;
2016-01-26 01:17:21 +00:00
/* Free after memory is duplicated in case structure was manipulated with a "get then set" */
g_free ( prev_value ) ;
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-04 13:52:48 +00:00
int wtap_optionblock_get_option_custom ( wtap_optionblock_t block , guint option_id , void * * value )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
wtap_optblock_value_t * opt_value = wtap_optionblock_get_option ( block , option_id ) ;
2016-01-26 01:17:21 +00:00
/* Didn't find the option */
2016-03-04 13:52:48 +00:00
if ( opt_value = = NULL )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_NOT_FOUND ;
2016-03-04 13:52:48 +00:00
if ( opt_value - > info - > type ! = WTAP_OPTTYPE_CUSTOM )
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_TYPE_MISMATCH ;
2016-03-04 13:52:48 +00:00
* value = opt_value - > option . customval . data ;
2016-01-26 01:17:21 +00:00
return WTAP_OPTTYPE_SUCCESS ;
}
2016-03-02 14:13:08 +00:00
static void shb_create ( wtap_optionblock_t block )
2016-01-26 01:17:21 +00:00
{
2016-03-04 13:52:48 +00:00
static wtap_optblock_reg_t comment_option = { " opt_comment " , " Optional comment " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t hardware_option = { " hardware " , " SBH Hardware " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t os_option = { " os " , " SBH Operating System " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t user_appl_option = { " user_appl " , " SBH User Application " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
2016-03-02 14:13:08 +00:00
wtapng_mandatory_section_t * section_mand = g_new ( wtapng_mandatory_section_t , 1 ) ;
2016-01-26 01:17:21 +00:00
2016-03-04 13:52:48 +00:00
/* Set proper values for the union */
comment_option . option . stringval = NULL ;
comment_option . default_val . stringval = NULL ;
hardware_option . option . stringval = NULL ;
hardware_option . default_val . stringval = NULL ;
os_option . option . stringval = NULL ;
os_option . default_val . stringval = NULL ;
user_appl_option . option . stringval = NULL ;
user_appl_option . default_val . stringval = NULL ;
2016-03-02 14:13:08 +00:00
section_mand - > section_length = - 1 ;
2016-01-26 01:17:21 +00:00
2016-03-02 14:13:08 +00:00
block - > mandatory_data = section_mand ;
2016-03-04 13:52:48 +00:00
wtap_optionblock_add_option ( block , OPT_COMMENT , & comment_option ) ;
wtap_optionblock_add_option ( block , OPT_SHB_HARDWARE , & hardware_option ) ;
wtap_optionblock_add_option ( block , OPT_SHB_OS , & os_option ) ;
wtap_optionblock_add_option ( block , OPT_SHB_USERAPPL , & user_appl_option ) ;
}
static gboolean shb_write ( struct wtap_dumper * wdh , wtap_optionblock_t block , int * err )
{
pcapng_block_header_t bh ;
pcapng_section_header_block_t shb ;
wtapng_mandatory_section_t * mand_data = ( wtapng_mandatory_section_t * ) block - > mandatory_data ;
guint32 options_total_length ;
wtap_debug ( " write_section_header_block: Have shb_hdr " ) ;
options_total_length = wtap_optionblock_get_option_write_size ( block ) ;
if ( options_total_length > 0 )
{
/* End-of-options tag */
options_total_length + = 4 ;
}
/* write block header */
bh . block_type = BLOCK_TYPE_SHB ;
bh . block_total_length = ( guint32 ) ( sizeof ( bh ) + sizeof ( shb ) + options_total_length + 4 ) ;
if ( ! wtap_dump_file_write ( wdh , & bh , sizeof bh , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh ;
/* write block fixed content */
shb . magic = 0x1A2B3C4D ;
shb . version_major = 1 ;
shb . version_minor = 0 ;
shb . section_length = mand_data - > section_length ;
if ( ! wtap_dump_file_write ( wdh , & shb , sizeof shb , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof shb ;
if ( ! wtap_optionblock_write_options ( wdh , block , options_total_length , err ) )
return FALSE ;
/* write block footer */
if ( ! wtap_dump_file_write ( wdh , & bh . block_total_length ,
sizeof bh . block_total_length , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh . block_total_length ;
return TRUE ;
2016-03-02 14:13:08 +00:00
}
static void shb_copy_mand ( wtap_optionblock_t dest_block , wtap_optionblock_t src_block )
{
memcpy ( dest_block - > mandatory_data , src_block - > mandatory_data , sizeof ( wtapng_mandatory_section_t ) ) ;
}
static void nrb_create ( wtap_optionblock_t block )
{
2016-03-04 13:52:48 +00:00
static wtap_optblock_reg_t comment_option = { " opt_comment " , " Optional comment " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
/* Set proper values for the union */
comment_option . option . stringval = NULL ;
comment_option . default_val . stringval = NULL ;
2016-03-02 14:13:08 +00:00
block - > mandatory_data = NULL ;
2016-03-04 13:52:48 +00:00
wtap_optionblock_add_option ( block , OPT_COMMENT , & comment_option ) ;
2016-03-02 14:13:08 +00:00
}
static void isb_create ( wtap_optionblock_t block )
{
2016-03-04 13:52:48 +00:00
static wtap_optblock_reg_t comment_option = { " opt_comment " , " Optional comment " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
2016-05-17 21:04:04 +00:00
static wtap_optblock_reg_t starttime_option = { " start_time " , " Start Time " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not0 , wtap_opttype_write_data_uint64_timestamp , { 0 } , { 0 } } ;
static wtap_optblock_reg_t endtime_option = { " end_time " , " End Time " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not0 , wtap_opttype_write_data_uint64_timestamp , { 0 } , { 0 } } ;
2016-03-04 13:52:48 +00:00
static wtap_optblock_reg_t rcv_pkt_option = { " recv " , " Receive Packets " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not_minus1 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t drop_pkt_option = { " drop " , " Dropped Packets " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not_minus1 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t filteraccept_option = { " filter_accept " , " Filter Accept " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not_minus1 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t os_drop_option = { " os_drop " , " OS Dropped Packets " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not_minus1 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t user_deliv_option = { " user_deliv " , " User Delivery " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not_minus1 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
2016-03-02 14:13:08 +00:00
block - > mandatory_data = g_new0 ( wtapng_if_stats_mandatory_t , 1 ) ;
2016-03-04 13:52:48 +00:00
/* Set proper values for the union */
comment_option . option . stringval = NULL ;
comment_option . default_val . stringval = NULL ;
starttime_option . option . uint64val = 0 ;
starttime_option . default_val . uint64val = 0 ;
endtime_option . option . uint64val = 0 ;
endtime_option . default_val . uint64val = 0 ;
rcv_pkt_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
rcv_pkt_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
drop_pkt_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
drop_pkt_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
filteraccept_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
filteraccept_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
os_drop_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
os_drop_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
user_deliv_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
user_deliv_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
wtap_optionblock_add_option ( block , OPT_COMMENT , & comment_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_STARTTIME , & starttime_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_ENDTIME , & endtime_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_IFRECV , & rcv_pkt_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_IFDROP , & drop_pkt_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_FILTERACCEPT , & filteraccept_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_OSDROP , & os_drop_option ) ;
wtap_optionblock_add_option ( block , OPT_ISB_USRDELIV , & user_deliv_option ) ;
}
static gboolean isb_write ( struct wtap_dumper * wdh , wtap_optionblock_t block , int * err )
{
pcapng_block_header_t bh ;
pcapng_interface_statistics_block_t isb ;
guint32 options_total_length ;
wtapng_if_stats_mandatory_t * mand_data = ( wtapng_if_stats_mandatory_t * ) block - > mandatory_data ;
wtap_debug ( " write_interface_statistics_block " ) ;
options_total_length = wtap_optionblock_get_option_write_size ( block ) ;
if ( options_total_length > 0 )
{
/* End-of-options tag */
options_total_length + = 4 ;
}
/* write block header */
bh . block_type = BLOCK_TYPE_ISB ;
bh . block_total_length = ( guint32 ) ( sizeof ( bh ) + sizeof ( isb ) + options_total_length + 4 ) ;
if ( ! wtap_dump_file_write ( wdh , & bh , sizeof bh , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh ;
/* write block fixed content */
isb . interface_id = mand_data - > interface_id ;
isb . timestamp_high = mand_data - > ts_high ;
isb . timestamp_low = mand_data - > ts_low ;
if ( ! wtap_dump_file_write ( wdh , & isb , sizeof isb , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof isb ;
if ( ! wtap_optionblock_write_options ( wdh , block , options_total_length , err ) )
return FALSE ;
/* write block footer */
if ( ! wtap_dump_file_write ( wdh , & bh . block_total_length ,
sizeof bh . block_total_length , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh . block_total_length ;
return TRUE ;
2016-03-02 14:13:08 +00:00
}
static void isb_copy_mand ( wtap_optionblock_t dest_block , wtap_optionblock_t src_block )
{
memcpy ( dest_block - > mandatory_data , src_block - > mandatory_data , sizeof ( wtapng_if_stats_mandatory_t ) ) ;
}
static void idb_filter_free ( void * data )
{
wtapng_if_descr_filter_t * filter = ( wtapng_if_descr_filter_t * ) data ;
g_free ( filter - > if_filter_str ) ;
g_free ( filter - > if_filter_bpf_bytes ) ;
}
2016-03-04 13:52:48 +00:00
static guint32 idb_filter_write_size ( wtap_option_type * data )
{
wtapng_if_descr_filter_t * filter ;
guint32 size , pad ;
if ( data = = NULL )
return 0 ;
filter = ( wtapng_if_descr_filter_t * ) data - > customval . data ;
if ( ( filter = = NULL ) | | ( filter - > if_filter_str = = NULL ) )
return 0 ;
size = ( guint32 ) ( strlen ( filter - > if_filter_str ) + 1 ) & 0xffff ;
if ( ( size % 4 ) ) {
pad = 4 - ( size % 4 ) ;
} else {
pad = 0 ;
}
return pad + size ;
}
static gboolean idb_filter_write ( struct wtap_dumper * wdh , wtap_option_type * data , int * err )
{
wtapng_if_descr_filter_t * filter = ( wtapng_if_descr_filter_t * ) data - > customval . data ;
guint32 size , pad ;
const guint32 zero_pad = 0 ;
size = ( guint32 ) ( strlen ( filter - > if_filter_str ) + 1 ) & 0xffff ;
if ( ( size % 4 ) ) {
pad = 4 - ( size % 4 ) ;
} else {
pad = 0 ;
}
/* Write the zero indicating libpcap filter variant */
if ( ! wtap_dump_file_write ( wdh , & zero_pad , 1 , err ) )
return FALSE ;
wdh - > bytes_dumped + = 1 ;
/* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
if ( ! wtap_dump_file_write ( wdh , filter - > if_filter_str , size - 1 , err ) )
return FALSE ;
wdh - > bytes_dumped + = size - 1 ;
/* write padding (if any) */
if ( pad ! = 0 ) {
if ( ! wtap_dump_file_write ( wdh , & zero_pad , pad , err ) )
return FALSE ;
wdh - > bytes_dumped + = pad ;
}
return TRUE ;
}
2016-03-02 14:13:08 +00:00
static void idb_create ( wtap_optionblock_t block )
{
2016-03-04 13:52:48 +00:00
static wtap_optblock_reg_t comment_option = { " opt_comment " , " Optional comment " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t name_option = { " name " , " Device name " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t description_option = { " description " , " Device description " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t speed_option = { " speed " , " Interface speed (in bps) " , WTAP_OPTTYPE_UINT64 , wtap_opttype_write_uint64_not0 , wtap_opttype_write_data_uint64 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t tsresol_option = { " ts_resolution " , " Resolution of timestamps " , WTAP_OPTTYPE_UINT8 , wtap_opttype_write_uint8_not0 , wtap_opttype_write_data_uint8 , { 0 } , { 0 } } ;
static wtap_optblock_reg_t filter_option = { " filter " , " Filter string " , WTAP_OPTTYPE_CUSTOM , idb_filter_write_size , idb_filter_write , { 0 } , { 0 } } ;
static wtap_optblock_reg_t os_option = { " os " , " Operating System " , WTAP_OPTTYPE_STRING , wtap_opttype_write_size_string , wtap_opttype_write_data_string , { 0 } , { 0 } } ;
static wtap_optblock_reg_t fcslen_option = { " fcslen " , " FCS Length " , WTAP_OPTTYPE_UINT8 , NULL , NULL , { 0 } , { 0 } } ;
2016-03-02 14:13:08 +00:00
wtapng_if_descr_filter_t default_filter ;
memset ( & default_filter , 0 , sizeof ( default_filter ) ) ;
block - > mandatory_data = g_new0 ( wtapng_if_descr_mandatory_t , 1 ) ;
2016-03-04 13:52:48 +00:00
/* Set proper values for the union */
comment_option . option . stringval = NULL ;
comment_option . default_val . stringval = NULL ;
name_option . option . stringval = NULL ;
name_option . default_val . stringval = NULL ;
description_option . option . stringval = NULL ;
description_option . default_val . stringval = NULL ;
speed_option . option . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
speed_option . default_val . uint64val = G_GUINT64_CONSTANT ( 0xFFFFFFFFFFFFFFFF ) ;
tsresol_option . option . uint8val = 6 ;
tsresol_option . default_val . uint8val = 6 ;
filter_option . option . customval . size = sizeof ( wtapng_if_descr_filter_t ) ;
filter_option . option . customval . data = & default_filter ;
filter_option . option . customval . free_func = idb_filter_free ;
filter_option . default_val . customval . size = sizeof ( wtapng_if_descr_filter_t ) ;
filter_option . default_val . customval . data = & default_filter ;
filter_option . default_val . customval . free_func = idb_filter_free ;
os_option . option . stringval = NULL ;
os_option . default_val . stringval = NULL ;
fcslen_option . option . uint8val = - 1 ;
fcslen_option . default_val . uint8val = - 1 ;
wtap_optionblock_add_option ( block , OPT_COMMENT , & comment_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_NAME , & name_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_DESCR , & description_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_SPEED , & speed_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_TSRESOL , & tsresol_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_FILTER , & filter_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_OS , & os_option ) ;
wtap_optionblock_add_option ( block , OPT_IDB_FCSLEN , & fcslen_option ) ;
}
static gboolean idb_write ( struct wtap_dumper * wdh , wtap_optionblock_t block , int * err )
{
pcapng_block_header_t bh ;
pcapng_interface_description_block_t idb ;
wtapng_if_descr_mandatory_t * mand_data = ( wtapng_if_descr_mandatory_t * ) block - > mandatory_data ;
guint32 options_total_length ;
wtap_debug ( " write_interface_description_block: encap = %d (%s), snaplen = %d " ,
mand_data - > link_type ,
wtap_encap_string ( wtap_pcap_encap_to_wtap_encap ( mand_data - > link_type ) ) ,
mand_data - > snap_len ) ;
if ( mand_data - > link_type = = ( guint16 ) - 1 ) {
* err = WTAP_ERR_UNWRITABLE_ENCAP ;
return FALSE ;
}
options_total_length = wtap_optionblock_get_option_write_size ( block ) ;
if ( options_total_length > 0 )
{
/* End-of-options tag */
options_total_length + = 4 ;
}
/* write block header */
bh . block_type = BLOCK_TYPE_IDB ;
bh . block_total_length = ( guint32 ) ( sizeof ( bh ) + sizeof ( idb ) + options_total_length + 4 ) ;
if ( ! wtap_dump_file_write ( wdh , & bh , sizeof bh , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh ;
/* write block fixed content */
idb . linktype = mand_data - > link_type ;
idb . reserved = 0 ;
idb . snaplen = mand_data - > snap_len ;
if ( ! wtap_dump_file_write ( wdh , & idb , sizeof idb , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof idb ;
if ( ! wtap_optionblock_write_options ( wdh , block , options_total_length , err ) )
return FALSE ;
/* write block footer */
if ( ! wtap_dump_file_write ( wdh , & bh . block_total_length ,
sizeof bh . block_total_length , err ) )
return FALSE ;
wdh - > bytes_dumped + = sizeof bh . block_total_length ;
return TRUE ;
2016-03-02 14:13:08 +00:00
}
static void idb_free_mand ( wtap_optionblock_t block )
{
guint j ;
wtap_optionblock_t if_stats ;
wtapng_if_descr_mandatory_t * mand = ( wtapng_if_descr_mandatory_t * ) block - > mandatory_data ;
for ( j = 0 ; j < mand - > num_stat_entries ; j + + ) {
if_stats = g_array_index ( mand - > interface_statistics , wtap_optionblock_t , j ) ;
wtap_optionblock_free ( if_stats ) ;
2016-01-26 01:17:21 +00:00
}
2016-03-02 14:13:08 +00:00
if ( mand - > interface_statistics )
g_array_free ( mand - > interface_statistics , TRUE ) ;
}
static void idb_copy_mand ( wtap_optionblock_t dest_block , wtap_optionblock_t src_block )
{
guint j ;
wtap_optionblock_t src_if_stats , dest_if_stats ;
wtapng_if_descr_mandatory_t * src_mand = ( wtapng_if_descr_mandatory_t * ) src_block - > mandatory_data ,
* dest_mand = ( wtapng_if_descr_mandatory_t * ) dest_block - > mandatory_data ;
/* Need special consideration for copying of the interface_statistics member */
if ( dest_mand - > num_stat_entries ! = 0 )
g_array_free ( dest_mand - > interface_statistics , TRUE ) ;
memcpy ( dest_mand , src_mand , sizeof ( wtapng_if_descr_mandatory_t ) ) ;
if ( src_mand - > num_stat_entries ! = 0 )
2016-01-26 01:17:21 +00:00
{
2016-03-02 14:13:08 +00:00
dest_mand - > interface_statistics = g_array_new ( FALSE , FALSE , sizeof ( wtap_optionblock_t ) ) ;
for ( j = 0 ; j < src_mand - > num_stat_entries ; j + + )
2016-01-26 01:17:21 +00:00
{
2016-03-02 14:13:08 +00:00
src_if_stats = g_array_index ( src_mand - > interface_statistics , wtap_optionblock_t , j ) ;
dest_if_stats = wtap_optionblock_create ( WTAP_OPTION_BLOCK_IF_STATS ) ;
wtap_optionblock_copy_options ( dest_if_stats , src_if_stats ) ;
dest_mand - > interface_statistics = g_array_append_val ( dest_mand - > interface_statistics , dest_if_stats ) ;
2016-01-26 01:17:21 +00:00
}
}
}
2016-03-02 14:13:08 +00:00
void wtap_opttypes_initialize ( void )
{
static wtap_opt_register_t shb_block = {
" SHB " , /* name */
" Section Header Block " , /* description */
shb_create , /* create */
2016-03-04 13:52:48 +00:00
shb_write , /* write */
2016-03-02 14:13:08 +00:00
NULL , /* free_mand */
shb_copy_mand , /* copy_mand */
} ;
static wtap_opt_register_t nrb_block = {
" NRB " , /* name */
" Name Resolution Block " , /* description */
nrb_create , /* create */
2016-03-04 13:52:48 +00:00
NULL , /* write */
2016-03-02 14:13:08 +00:00
NULL , /* free_mand */
NULL , /* copy_mand */
} ;
static wtap_opt_register_t isb_block = {
" ISB " , /* name */
" Interface Statistics Block " , /* description */
isb_create , /* create */
2016-03-04 13:52:48 +00:00
isb_write , /* write */
2016-03-02 14:13:08 +00:00
NULL , /* free_mand */
isb_copy_mand , /* copy_mand */
} ;
static wtap_opt_register_t idb_block = {
" IDB " , /* name */
" Interface Description Block " , /* description */
idb_create , /* create */
2016-03-04 13:52:48 +00:00
idb_write , /* write */
2016-03-02 14:13:08 +00:00
idb_free_mand , /* free_mand */
idb_copy_mand , /* copy_mand */
} ;
2016-05-18 02:50:51 +00:00
/* Initialize the custom block array. This is for future proofing
2016-03-02 14:13:08 +00:00
" outside registered " block types ( for NULL checking ) */
2016-05-18 02:50:51 +00:00
memset ( block_list , 0 , MAX_WTAP_OPTION_BLOCK_TYPE_VALUE * sizeof ( wtap_opt_register_t * ) ) ;
num_custom_blocks = 0 ;
2016-03-02 14:13:08 +00:00
wtap_opttype_block_register ( WTAP_OPTION_BLOCK_NG_SECTION , & shb_block ) ;
wtap_opttype_block_register ( WTAP_OPTION_BLOCK_NG_NRB , & nrb_block ) ;
wtap_opttype_block_register ( WTAP_OPTION_BLOCK_IF_STATS , & isb_block ) ;
wtap_opttype_block_register ( WTAP_OPTION_BLOCK_IF_DESCR , & idb_block ) ;
}