2015-07-07 15:30:44 +00:00
/*
* wslua_dissector . c
*
* Wireshark ' s interface to the Lua Programming Language
*
* ( c ) 2006 , Luis E . Garcia Ontanon < luis @ ontanon . org >
* ( c ) 2008 , Balint Reczey < balint . reczey @ ericsson . com >
* ( c ) 2011 , Stig Bjorlykke < stig @ bjorlykke . org >
* ( c ) 2014 , Hadriel Kaplan < hadrielk @ yahoo . com >
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
2018-02-08 16:33:09 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2015-07-07 15:30:44 +00:00
*/
# include "config.h"
# include "wslua.h"
2019-06-12 16:53:08 +00:00
# include <epan/decode_as.h>
2015-07-07 15:30:44 +00:00
# include <epan/exceptions.h>
# include <epan/show_exception.h>
/* WSLUA_CONTINUE_MODULE Proto */
2016-04-03 08:58:44 +00:00
WSLUA_CLASS_DEFINE ( Dissector , NOP ) ;
2015-07-07 15:30:44 +00:00
/*
A refererence to a dissector , used to call a dissector against a packet or a part of it .
*/
WSLUA_CONSTRUCTOR Dissector_get ( lua_State * L ) {
/* Obtains a dissector reference by name. */
# define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector. */
const gchar * name = luaL_checkstring ( L , WSLUA_ARG_Dissector_get_NAME ) ;
Dissector d ;
if ( ( d = find_dissector ( name ) ) ) {
pushDissector ( L , d ) ;
2020-09-30 10:05:41 +00:00
} else {
lua_pushnil ( L ) ;
2015-07-07 15:30:44 +00:00
}
2020-09-30 10:05:41 +00:00
WSLUA_RETURN ( 1 ) ; /* The <<lua_class_Dissector,`Dissector`>> reference if found, otherwise `nil`. */
2015-07-07 15:30:44 +00:00
}
/* Allow dissector key names to be sorted alphabetically. */
static gint
compare_dissector_key_name ( gconstpointer dissector_a , gconstpointer dissector_b )
{
return strcmp ( ( const char * ) dissector_a , ( const char * ) dissector_b ) ;
}
WSLUA_CONSTRUCTOR Dissector_list ( lua_State * L ) {
/* Gets a Lua array table of all registered Dissector names.
2018-02-09 20:56:58 +00:00
Note : This is an expensive operation , and should only be used for troubleshooting .
2015-07-07 15:30:44 +00:00
@ since 1.11 .3
*/
GList * list = get_dissector_names ( ) ;
GList * elist = NULL ;
int i = 1 ;
if ( ! list ) return luaL_error ( L , " Cannot retrieve Dissector name list " ) ;
list = g_list_sort ( list , ( GCompareFunc ) compare_dissector_key_name ) ;
elist = g_list_first ( list ) ;
lua_newtable ( L ) ;
for ( i = 1 ; elist ; i + + , elist = g_list_next ( elist ) ) {
lua_pushstring ( L , ( const char * ) elist - > data ) ;
2017-08-25 18:19:06 +00:00
lua_rawseti ( L , - 2 , i ) ;
2015-07-07 15:30:44 +00:00
}
g_list_free ( list ) ;
WSLUA_RETURN ( 1 ) ; /* The array table of registered dissector names. */
}
WSLUA_METHOD Dissector_call ( lua_State * L ) {
/* Calls a dissector against a given packet (or part of it). */
# define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect. */
# define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info. */
# define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items. */
Dissector volatile d = checkDissector ( L , 1 ) ;
Tvb tvb = checkTvb ( L , WSLUA_ARG_Dissector_call_TVB ) ;
Pinfo pinfo = checkPinfo ( L , WSLUA_ARG_Dissector_call_PINFO ) ;
TreeItem ti = checkTreeItem ( L , WSLUA_ARG_Dissector_call_TREE ) ;
2016-02-08 21:59:47 +00:00
const char * volatile error = NULL ;
2015-07-07 15:30:44 +00:00
int len = 0 ;
if ( ! ( d & & tvb & & pinfo ) ) return 0 ;
TRY {
len = call_dissector ( d , tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree ) ;
/* XXX Are we sure about this??? is this the right/only thing to catch */
} CATCH_NONFATAL_ERRORS {
show_exception ( tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree , EXCEPT_CODE , GET_MESSAGE ) ;
2016-02-08 21:59:47 +00:00
error = " Malformed frame " ;
2015-07-07 15:30:44 +00:00
} ENDTRY ;
2016-02-08 21:59:47 +00:00
if ( error ) { WSLUA_ERROR ( Dissector_call , error ) ; }
2015-07-07 15:30:44 +00:00
lua_pushnumber ( L , ( lua_Number ) len ) ;
WSLUA_RETURN ( 1 ) ; /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
}
WSLUA_METAMETHOD Dissector__call ( lua_State * L ) {
/* Calls a dissector against a given packet (or part of it). */
# define WSLUA_ARG_Dissector__call_TVB 2 /* The buffer to dissect. */
# define WSLUA_ARG_Dissector__call_PINFO 3 /* The packet info. */
# define WSLUA_ARG_Dissector__call_TREE 4 /* The tree on which to add the protocol items. */
return Dissector_call ( L ) ;
}
WSLUA_METAMETHOD Dissector__tostring ( lua_State * L ) {
/* Gets the Dissector's protocol short name. */
Dissector d = checkDissector ( L , 1 ) ;
if ( ! d ) return 0 ;
lua_pushstring ( L , dissector_handle_get_short_name ( d ) ) ;
WSLUA_RETURN ( 1 ) ; /* A string of the protocol's short name. */
}
/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
static int Dissector__gc ( lua_State * L _U_ ) {
/* do NOT free Dissector */
return 0 ;
}
WSLUA_METHODS Dissector_methods [ ] = {
WSLUA_CLASS_FNREG ( Dissector , get ) ,
WSLUA_CLASS_FNREG ( Dissector , call ) ,
WSLUA_CLASS_FNREG ( Dissector , list ) ,
{ NULL , NULL }
} ;
WSLUA_META Dissector_meta [ ] = {
WSLUA_CLASS_MTREG ( Dissector , tostring ) ,
WSLUA_CLASS_MTREG ( Dissector , call ) ,
{ NULL , NULL }
} ;
int Dissector_register ( lua_State * L ) {
WSLUA_REGISTER_CLASS ( Dissector ) ;
return 0 ;
}
2016-04-03 08:58:44 +00:00
WSLUA_CLASS_DEFINE ( DissectorTable , NOP ) ;
2015-07-07 15:30:44 +00:00
/*
2020-03-29 22:46:46 +00:00
A table of subdissectors of a particular protocol ( e . g . TCP subdissectors like http , smtp , sip are added to table " tcp.port " ) .
2015-07-07 15:30:44 +00:00
2020-03-29 22:46:46 +00:00
Useful to add more dissectors to a table so that they appear in the “ Decode As . . . ” dialog .
2015-07-07 15:30:44 +00:00
*/
2015-08-11 12:08:08 +00:00
static int dissectortable_table_ref = LUA_NOREF ;
2015-07-07 15:30:44 +00:00
WSLUA_CONSTRUCTOR DissectorTable_new ( lua_State * L ) {
2020-03-29 22:46:46 +00:00
/* Creates a new `DissectorTable` for your dissector's use. */
# define WSLUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. Use lower-case alphanumeric, dot, and/or underscores (e.g., "ansi_map.tele_id" or "udp.port"). */
# define WSLUA_OPTARG_DissectorTable_new_UINAME 2 / * The name of the table in the user interface.
Defaults to the name given in ` tablename ` , but can be any string . */
# define WSLUA_OPTARG_DissectorTable_new_TYPE 3 / * One of `ftypes.UINT8`, `ftypes.UINT16`,
2015-07-07 15:30:44 +00:00
` ftypes . UINT24 ` , ` ftypes . UINT32 ` , or
2020-03-29 22:46:46 +00:00
` ftypes . STRING ` .
Defaults to ` ftypes . UINT32 ` . */
# define WSLUA_OPTARG_DissectorTable_new_BASE 4 / * One of `base.NONE`, `base.DEC`, `base.HEX`,
` base . OCT ` , ` base . DEC_HEX ` or ` base . HEX_DEC ` .
Defaults to ` base . DEC ` . */
# define WSLUA_OPTARG_DissectorTable_new_PROTO 5 /* The <<lua_class_Proto,`Proto`>> object that uses this dissector table. */
2015-07-07 15:30:44 +00:00
const gchar * name = ( const gchar * ) luaL_checkstring ( L , WSLUA_ARG_DissectorTable_new_TABLENAME ) ;
const gchar * ui_name = ( const gchar * ) luaL_optstring ( L , WSLUA_OPTARG_DissectorTable_new_UINAME , name ) ;
enum ftenum type = ( enum ftenum ) luaL_optinteger ( L , WSLUA_OPTARG_DissectorTable_new_TYPE , FT_UINT32 ) ;
unsigned base = ( unsigned ) luaL_optinteger ( L , WSLUA_OPTARG_DissectorTable_new_BASE , BASE_DEC ) ;
2019-06-10 18:23:34 +00:00
DissectorTable dt ;
2019-06-14 20:29:35 +00:00
int proto_id = - 1 ;
2015-07-07 15:30:44 +00:00
switch ( type ) {
case FT_STRING :
base = BASE_NONE ;
2019-06-10 18:23:34 +00:00
break ;
2019-06-12 16:53:08 +00:00
case FT_NONE :
2019-06-10 18:23:34 +00:00
break ;
2015-07-07 15:30:44 +00:00
case FT_UINT8 :
case FT_UINT16 :
case FT_UINT24 :
case FT_UINT32 :
2019-06-10 18:23:34 +00:00
break ;
2015-07-07 15:30:44 +00:00
default :
2019-06-10 18:23:34 +00:00
/* Calling WSLUA_OPTARG_ERROR raises a Lua error and
returns from this function . */
WSLUA_OPTARG_ERROR (
DissectorTable_new , TYPE ,
" must be ftypes.UINT{8,16,24,32}, ftypes.STRING or ftypes.NONE " ) ;
2015-07-07 15:30:44 +00:00
break ;
}
2019-06-10 18:23:34 +00:00
dt = ( DissectorTable ) g_malloc ( sizeof ( struct _wslua_distbl_t ) ) ;
2019-06-14 20:29:35 +00:00
if ( isProto ( L , WSLUA_OPTARG_DissectorTable_new_PROTO ) ) {
Proto proto = checkProto ( L , WSLUA_OPTARG_DissectorTable_new_PROTO ) ;
proto_id = proto_get_id_by_short_name ( proto - > name ) ;
}
2019-06-10 18:23:34 +00:00
dt - > table = ( type = = FT_NONE ) ?
2019-06-14 20:29:35 +00:00
register_decode_as_next_proto ( proto_id , name , ui_name , NULL ) :
register_dissector_table ( name , ui_name , proto_id , type , base ) ;
2019-06-10 18:23:34 +00:00
dt - > name = g_strdup ( name ) ;
dt - > ui_name = g_strdup ( ui_name ) ;
dt - > created = TRUE ;
dt - > expired = FALSE ;
lua_rawgeti ( L , LUA_REGISTRYINDEX , dissectortable_table_ref ) ;
lua_pushstring ( L , name ) ;
pushDissectorTable ( L , dt ) ;
lua_settable ( L , - 3 ) ;
pushDissectorTable ( L , dt ) ;
WSLUA_RETURN ( 1 ) ; /* The newly created DissectorTable. */
2015-07-07 15:30:44 +00:00
}
/* this struct is used for passing ourselves user_data through dissector_all_tables_foreach_table(). */
typedef struct dissector_tables_foreach_table_info {
int num ;
lua_State * L ;
} dissector_tables_foreach_table_info_t ;
/* this is the DATFunc_table function used for dissector_all_tables_foreach_table()
so we can get all dissector_table names . This pushes the name into a table at stack index 1 */
static void
dissector_tables_list_func ( const gchar * table_name , const gchar * ui_name _U_ , gpointer user_data ) {
dissector_tables_foreach_table_info_t * data = ( dissector_tables_foreach_table_info_t * ) user_data ;
lua_pushstring ( data - > L , table_name ) ;
lua_rawseti ( data - > L , 1 , data - > num ) ;
data - > num = data - > num + 1 ;
}
WSLUA_CONSTRUCTOR DissectorTable_list ( lua_State * L ) {
/* Gets a Lua array table of all DissectorTable names - i.e., the string names you can
use for the first argument to DissectorTable . get ( ) .
2018-02-09 20:56:58 +00:00
Note : This is an expensive operation , and should only be used for troubleshooting .
2015-07-07 15:30:44 +00:00
@ since 1.11 .3
*/
dissector_tables_foreach_table_info_t data = { 1 , L } ;
lua_newtable ( L ) ;
dissector_all_tables_foreach_table ( dissector_tables_list_func , ( gpointer ) & data ,
( GCompareFunc ) compare_dissector_key_name ) ;
WSLUA_RETURN ( 1 ) ; /* The array table of registered DissectorTable names. */
}
/* this is the DATFunc_heur_table function used for dissector_all_heur_tables_foreach_table()
so we can get all heuristic dissector list names . This pushes the name into a table at stack index 1 */
static void
2015-09-25 21:33:54 +00:00
heur_dissector_tables_list_func ( const gchar * table_name , struct heur_dissector_list * table _U_ , gpointer user_data ) {
2015-07-07 15:30:44 +00:00
dissector_tables_foreach_table_info_t * data = ( dissector_tables_foreach_table_info_t * ) user_data ;
lua_pushstring ( data - > L , table_name ) ;
lua_rawseti ( data - > L , 1 , data - > num ) ;
data - > num = data - > num + 1 ;
}
WSLUA_CONSTRUCTOR DissectorTable_heuristic_list ( lua_State * L ) {
/* Gets a Lua array table of all heuristic list names - i.e., the string names you can
use for the first argument in Proto : register_heuristic ( ) .
2018-02-09 20:56:58 +00:00
Note : This is an expensive operation , and should only be used for troubleshooting .
2015-07-07 15:30:44 +00:00
@ since 1.11 .3
*/
dissector_tables_foreach_table_info_t data = { 1 , L } ;
lua_newtable ( L ) ;
dissector_all_heur_tables_foreach_table ( heur_dissector_tables_list_func , ( gpointer ) & data , NULL ) ;
WSLUA_RETURN ( 1 ) ; /* The array table of registered heuristic list names */
}
2021-03-11 18:31:55 +00:00
WSLUA_CONSTRUCTOR DissectorTable_try_heuristics ( lua_State * L ) {
/*
Try all the dissectors in a given heuristic dissector table .
*/
# define WSLUA_ARG_DissectorTable_try_heuristics_LISTNAME 1 /* The name of the heuristic dissector. */
# define WSLUA_ARG_DissectorTable_try_heuristics_TVB 2 /* The buffer to dissect. */
# define WSLUA_ARG_DissectorTable_try_heuristics_PINFO 3 /* The packet info. */
# define WSLUA_ARG_DissectorTable_try_heuristics_TREE 4 /* The tree on which to add the protocol items. */
const gchar * name = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_try_heuristics_LISTNAME ) ;
Tvb tvb = checkTvb ( L , WSLUA_ARG_DissectorTable_try_heuristics_TVB ) ;
Pinfo pinfo = checkPinfo ( L , WSLUA_ARG_DissectorTable_try_heuristics_PINFO ) ;
TreeItem tree = checkTreeItem ( L , WSLUA_ARG_DissectorTable_try_heuristics_TREE ) ;
heur_dissector_list_t list ;
heur_dtbl_entry_t * entry ;
if ( ! ( name & & tvb & & pinfo & & tree ) ) return 0 ;
list = find_heur_dissector_list ( name ) ;
if ( ! list ) {
luaL_error ( L , " Heuristic list '%s' does not exist " , name ) ;
return 0 ;
}
lua_pushboolean ( L , dissector_try_heuristic ( list , tvb - > ws_tvb , pinfo - > ws_pinfo , tree - > tree , & entry , NULL ) ) ;
WSLUA_RETURN ( 1 ) ; /* True if the packet was recognized by the sub-dissector (stop dissection here). */
}
2015-07-07 15:30:44 +00:00
WSLUA_CONSTRUCTOR DissectorTable_get ( lua_State * L ) {
/*
Obtain a reference to an existing dissector table .
*/
# define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
const gchar * name = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_get_TABLENAME ) ;
dissector_table_t table = find_dissector_table ( name ) ;
if ( table ) {
DissectorTable dt = ( DissectorTable ) g_malloc ( sizeof ( struct _wslua_distbl_t ) ) ;
dt - > table = table ;
dt - > name = g_strdup ( name ) ;
2015-08-11 12:08:08 +00:00
dt - > ui_name = NULL ;
dt - > created = FALSE ;
dt - > expired = FALSE ;
2015-07-07 15:30:44 +00:00
pushDissectorTable ( L , dt ) ;
2020-09-30 10:05:41 +00:00
} else {
lua_pushnil ( L ) ;
2015-07-07 15:30:44 +00:00
}
2020-09-30 10:05:41 +00:00
WSLUA_RETURN ( 1 ) ; /* The <<lua_class_DissectorTable,`DissectorTable`>> reference if found, otherwise `nil`. */
2015-07-07 15:30:44 +00:00
}
WSLUA_METHOD DissectorTable_add ( lua_State * L ) {
/*
2020-03-29 22:46:46 +00:00
Add a < < lua_class_Proto , ` Proto ` > > with a dissector function or a < < lua_class_Dissector , ` Dissector ` > > object to the dissector table .
2015-07-07 15:30:44 +00:00
*/
# define WSLUA_ARG_DissectorTable_add_PATTERN 2 / * The pattern to match (either an integer, a
integer range or a string depending on the table ' s type ) . */
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
ftenum_t type ;
Dissector handle ;
if ( ! dt ) return 0 ;
if ( isProto ( L , WSLUA_ARG_DissectorTable_add_DISSECTOR ) ) {
Proto p ;
p = checkProto ( L , WSLUA_ARG_DissectorTable_add_DISSECTOR ) ;
handle = p - > handle ;
if ( ! handle ) {
WSLUA_ARG_ERROR ( DissectorTable_add , DISSECTOR , " a Protocol that does not have a dissector cannot be added to a table " ) ;
return 0 ;
}
} else if ( isDissector ( L , WSLUA_ARG_DissectorTable_add_DISSECTOR ) ) {
handle = toDissector ( L , WSLUA_ARG_DissectorTable_add_DISSECTOR ) ;
} else {
WSLUA_ARG_ERROR ( DissectorTable_add , DISSECTOR , " must be either Proto or Dissector " ) ;
return 0 ;
}
type = get_dissector_table_selector_type ( dt - > name ) ;
if ( type = = FT_STRING ) {
gchar * pattern = g_strdup ( luaL_checkstring ( L , WSLUA_ARG_DissectorTable_add_PATTERN ) ) ;
dissector_add_string ( dt - > name , pattern , handle ) ;
g_free ( pattern ) ;
} else if ( type = = FT_UINT32 | | type = = FT_UINT16 | | type = = FT_UINT8 | | type = = FT_UINT24 ) {
if ( lua_isnumber ( L , WSLUA_ARG_DissectorTable_add_PATTERN ) ) {
int port = ( int ) luaL_checkinteger ( L , WSLUA_ARG_DissectorTable_add_PATTERN ) ;
dissector_add_uint ( dt - > name , port , handle ) ;
} else {
/* Not a number, try as range */
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_add_PATTERN ) ;
range_t * range = NULL ;
2016-12-22 20:12:27 +00:00
if ( range_convert_str ( NULL , & range , pattern , G_MAXUINT32 ) = = CVT_NO_ERROR ) {
2015-07-07 15:30:44 +00:00
dissector_add_uint_range ( dt - > name , range , handle ) ;
} else {
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
WSLUA_ARG_ERROR ( DissectorTable_add , PATTERN , " invalid integer or range " ) ;
return 0 ;
}
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
}
} else {
luaL_error ( L , " Strange type %d for a DissectorTable " , type ) ;
}
return 0 ;
}
WSLUA_METHOD DissectorTable_set ( lua_State * L ) {
/*
2020-03-29 22:46:46 +00:00
Clear all existing dissectors from a table and add a new dissector or a range of new dissectors .
2015-07-07 15:30:44 +00:00
@ since 1.11 .3
*/
# define WSLUA_ARG_DissectorTable_set_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_set_DISSECTOR 3 /* The dissector to add (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
ftenum_t type ;
Dissector handle ;
if ( ! dt ) return 0 ;
if ( isProto ( L , WSLUA_ARG_DissectorTable_set_DISSECTOR ) ) {
Proto p ;
p = checkProto ( L , WSLUA_ARG_DissectorTable_set_DISSECTOR ) ;
handle = p - > handle ;
if ( ! handle ) {
WSLUA_ARG_ERROR ( DissectorTable_set , DISSECTOR , " a Protocol that does not have a dissector cannot be set to a table " ) ;
return 0 ;
}
} else if ( isDissector ( L , WSLUA_ARG_DissectorTable_set_DISSECTOR ) ) {
handle = toDissector ( L , WSLUA_ARG_DissectorTable_set_DISSECTOR ) ;
} else {
WSLUA_ARG_ERROR ( DissectorTable_set , DISSECTOR , " must be either Proto or Dissector " ) ;
return 0 ;
}
type = get_dissector_table_selector_type ( dt - > name ) ;
if ( type = = FT_STRING ) {
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_set_PATTERN ) ;
dissector_delete_all ( dt - > name , handle ) ;
dissector_add_string ( dt - > name , pattern , handle ) ;
} else if ( type = = FT_UINT32 | | type = = FT_UINT16 | | type = = FT_UINT8 | | type = = FT_UINT24 ) {
if ( lua_isnumber ( L , WSLUA_ARG_DissectorTable_set_PATTERN ) ) {
int port = ( int ) luaL_checkinteger ( L , WSLUA_ARG_DissectorTable_set_PATTERN ) ;
dissector_delete_all ( dt - > name , handle ) ;
dissector_add_uint ( dt - > name , port , handle ) ;
} else {
/* Not a number, try as range */
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_set_PATTERN ) ;
range_t * range = NULL ;
2016-12-22 20:12:27 +00:00
if ( range_convert_str ( NULL , & range , pattern , G_MAXUINT32 ) = = CVT_NO_ERROR ) {
2015-07-07 15:30:44 +00:00
dissector_delete_all ( dt - > name , handle ) ;
dissector_add_uint_range ( dt - > name , range , handle ) ;
} else {
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
WSLUA_ARG_ERROR ( DissectorTable_set , PATTERN , " invalid integer or range " ) ;
return 0 ;
}
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
}
} else {
luaL_error ( L , " Strange type %d for a DissectorTable " , type ) ;
}
return 0 ;
}
WSLUA_METHOD DissectorTable_remove ( lua_State * L ) {
/*
2020-03-29 22:46:46 +00:00
Remove a dissector or a range of dissectors from a table .
2015-07-07 15:30:44 +00:00
*/
# define WSLUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to remove (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
ftenum_t type ;
Dissector handle ;
if ( ! dt ) return 0 ;
if ( isProto ( L , WSLUA_ARG_DissectorTable_remove_DISSECTOR ) ) {
Proto p ;
p = checkProto ( L , WSLUA_ARG_DissectorTable_remove_DISSECTOR ) ;
handle = p - > handle ;
} else if ( isDissector ( L , WSLUA_ARG_DissectorTable_remove_DISSECTOR ) ) {
handle = toDissector ( L , WSLUA_ARG_DissectorTable_remove_DISSECTOR ) ;
} else {
WSLUA_ARG_ERROR ( DissectorTable_remove , DISSECTOR , " must be either Proto or Dissector " ) ;
return 0 ;
}
type = get_dissector_table_selector_type ( dt - > name ) ;
if ( type = = FT_STRING ) {
gchar * pattern = g_strdup ( luaL_checkstring ( L , WSLUA_ARG_DissectorTable_remove_PATTERN ) ) ;
dissector_delete_string ( dt - > name , pattern , handle ) ;
g_free ( pattern ) ;
} else if ( type = = FT_UINT32 | | type = = FT_UINT16 | | type = = FT_UINT8 | | type = = FT_UINT24 ) {
if ( lua_isnumber ( L , WSLUA_ARG_DissectorTable_remove_PATTERN ) ) {
int port = ( int ) luaL_checkinteger ( L , WSLUA_ARG_DissectorTable_remove_PATTERN ) ;
dissector_delete_uint ( dt - > name , port , handle ) ;
} else {
/* Not a number, try as range */
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_remove_PATTERN ) ;
range_t * range = NULL ;
2016-12-22 20:12:27 +00:00
if ( range_convert_str ( NULL , & range , pattern , G_MAXUINT32 ) = = CVT_NO_ERROR )
2015-07-07 15:30:44 +00:00
dissector_delete_uint_range ( dt - > name , range , handle ) ;
else {
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
WSLUA_ARG_ERROR ( DissectorTable_remove , PATTERN , " invalid integer or range " ) ;
return 0 ;
}
2016-12-22 20:12:27 +00:00
wmem_free ( NULL , range ) ;
2015-07-07 15:30:44 +00:00
}
}
return 0 ;
}
WSLUA_METHOD DissectorTable_remove_all ( lua_State * L ) {
/*
Remove all dissectors from a table .
@ since 1.11 .3
*/
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_remove_all_DISSECTOR 2 /* The dissector to remove (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
Dissector handle ;
if ( ! dt ) return 0 ;
if ( isProto ( L , WSLUA_ARG_DissectorTable_remove_all_DISSECTOR ) ) {
Proto p ;
p = checkProto ( L , WSLUA_ARG_DissectorTable_remove_all_DISSECTOR ) ;
handle = p - > handle ;
} else if ( isDissector ( L , WSLUA_ARG_DissectorTable_remove_all_DISSECTOR ) ) {
handle = toDissector ( L , WSLUA_ARG_DissectorTable_remove_all_DISSECTOR ) ;
} else {
WSLUA_ARG_ERROR ( DissectorTable_remove_all , DISSECTOR , " must be either Proto or Dissector " ) ;
return 0 ;
}
dissector_delete_all ( dt - > name , handle ) ;
return 0 ;
}
WSLUA_METHOD DissectorTable_try ( lua_State * L ) {
/*
2020-03-29 22:46:46 +00:00
Try to call a dissector from a table .
2015-07-07 15:30:44 +00:00
*/
# define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_try_TVB 3 /* The <<lua_class_Tvb,`Tvb`>> to dissect. */
# define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet's <<lua_class_Pinfo,`Pinfo`>>. */
# define WSLUA_ARG_DissectorTable_try_TREE 5 /* The <<lua_class_TreeItem,`TreeItem`>> on which to add the protocol items. */
2015-07-07 15:30:44 +00:00
DissectorTable volatile dt = checkDissectorTable ( L , 1 ) ;
Tvb tvb = checkTvb ( L , WSLUA_ARG_DissectorTable_try_TVB ) ;
Pinfo pinfo = checkPinfo ( L , WSLUA_ARG_DissectorTable_try_PINFO ) ;
TreeItem ti = checkTreeItem ( L , WSLUA_ARG_DissectorTable_try_TREE ) ;
ftenum_t type ;
gboolean handled = FALSE ;
2016-02-08 21:59:47 +00:00
const gchar * volatile error = NULL ;
2015-07-07 15:30:44 +00:00
int len = 0 ;
if ( ! ( dt & & tvb & & tvb - > ws_tvb & & pinfo & & ti ) ) return 0 ;
type = get_dissector_table_selector_type ( dt - > name ) ;
TRY {
if ( type = = FT_STRING ) {
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_try_PATTERN ) ;
len = dissector_try_string ( dt - > table , pattern , tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree , NULL ) ;
if ( len > 0 ) {
handled = TRUE ;
}
} else if ( type = = FT_UINT32 | | type = = FT_UINT16 | | type = = FT_UINT8 | | type = = FT_UINT24 ) {
int port = ( int ) luaL_checkinteger ( L , WSLUA_ARG_DissectorTable_try_PATTERN ) ;
len = dissector_try_uint ( dt - > table , port , tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree ) ;
if ( len > 0 ) {
handled = TRUE ;
}
} else {
2019-05-25 14:47:59 +00:00
error = " No such type of dissector table " ;
2015-07-07 15:30:44 +00:00
}
if ( ! handled ) {
2019-07-20 21:24:56 +00:00
len = call_data_dissector ( tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree ) ;
2015-07-07 15:30:44 +00:00
}
/* XXX Are we sure about this??? is this the right/only thing to catch */
} CATCH_NONFATAL_ERRORS {
show_exception ( tvb - > ws_tvb , pinfo - > ws_pinfo , ti - > tree , EXCEPT_CODE , GET_MESSAGE ) ;
2016-02-08 21:59:47 +00:00
error = " Malformed frame " ;
2015-07-07 15:30:44 +00:00
} ENDTRY ;
2016-02-08 21:59:47 +00:00
if ( error ) { WSLUA_ERROR ( DissectorTable_try , error ) ; }
2015-07-07 15:30:44 +00:00
lua_pushnumber ( L , ( lua_Number ) len ) ;
WSLUA_RETURN ( 1 ) ; /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
}
WSLUA_METHOD DissectorTable_get_dissector ( lua_State * L ) {
/*
Try to obtain a dissector from a table .
*/
# define WSLUA_ARG_DissectorTable_get_dissector_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
ftenum_t type ;
2019-07-20 21:24:56 +00:00
dissector_handle_t handle = NULL ;
2015-07-07 15:30:44 +00:00
if ( ! dt ) return 0 ;
type = get_dissector_table_selector_type ( dt - > name ) ;
if ( type = = FT_STRING ) {
const gchar * pattern = luaL_checkstring ( L , WSLUA_ARG_DissectorTable_get_dissector_PATTERN ) ;
handle = dissector_get_string_handle ( dt - > table , pattern ) ;
} else if ( type = = FT_UINT32 | | type = = FT_UINT16 | | type = = FT_UINT8 | | type = = FT_UINT24 ) {
int port = ( int ) luaL_checkinteger ( L , WSLUA_ARG_DissectorTable_get_dissector_PATTERN ) ;
handle = dissector_get_uint_handle ( dt - > table , port ) ;
}
if ( handle ) {
pushDissector ( L , handle ) ;
} else {
lua_pushnil ( L ) ;
}
2020-09-30 10:05:41 +00:00
WSLUA_RETURN ( 1 ) ; /* The <<lua_class_Dissector,`Dissector`>> handle if found, otherwise `nil` */
2015-07-07 15:30:44 +00:00
}
WSLUA_METHOD DissectorTable_add_for_decode_as ( lua_State * L ) {
/*
2020-03-29 22:46:46 +00:00
Add the given < < lua_class_Proto , ` Proto ` > > to the “ Decode as . . . ” list for this DissectorTable .
The passed - in < < lua_class_Proto , ` Proto ` > > object ' s ` dissector ( ) ` function is used for dissecting .
2015-07-07 15:30:44 +00:00
@ since 1.99 .1
*/
2020-03-29 22:46:46 +00:00
# define WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO 2 /* The <<lua_class_Proto,`Proto`>> to add. */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
Proto proto = checkProto ( L , WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO ) ;
dissector_handle_t handle = NULL ;
if ( ! proto - > handle ) {
2015-12-11 01:56:03 +00:00
proto - > handle = register_dissector ( proto - > loname , dissect_lua , proto - > hfid ) ;
2015-07-07 15:30:44 +00:00
}
handle = proto - > handle ;
dissector_add_for_decode_as ( dt - > name , handle ) ;
return 0 ;
}
/* XXX It would be nice to iterate and print which dissectors it has */
WSLUA_METAMETHOD DissectorTable__tostring ( lua_State * L ) {
2020-03-29 22:46:46 +00:00
/* Gets some debug information about the <<lua_class_DissectorTable,`DissectorTable`>>. */
2015-07-07 15:30:44 +00:00
DissectorTable dt = checkDissectorTable ( L , 1 ) ;
GString * s ;
ftenum_t type ;
if ( ! dt ) return 0 ;
type = get_dissector_table_selector_type ( dt - > name ) ;
s = g_string_new ( " DissectorTable " ) ;
switch ( type ) {
case FT_STRING :
{
g_string_append_printf ( s , " %s String: \n " , dt - > name ) ;
break ;
}
case FT_UINT8 :
case FT_UINT16 :
case FT_UINT24 :
case FT_UINT32 :
{
int base = get_dissector_table_param ( dt - > name ) ;
g_string_append_printf ( s , " %s Integer(%i): \n " , dt - > name , base ) ;
break ;
}
2019-05-25 13:43:31 +00:00
case FT_NONE :
{
g_string_append_printf ( s , " %s only for Decode As: \n " , dt - > name ) ;
break ;
}
2015-07-07 15:30:44 +00:00
default :
luaL_error ( L , " Strange table type " ) ;
}
lua_pushstring ( L , s - > str ) ;
g_string_free ( s , TRUE ) ;
2020-03-29 22:46:46 +00:00
WSLUA_RETURN ( 1 ) ; /* A string of debug information about the <<lua_class_DissectorTable,`DissectorTable`>>. */
2015-07-07 15:30:44 +00:00
}
/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
2016-03-28 13:25:12 +00:00
static int DissectorTable__gc ( lua_State * L ) {
2015-08-11 12:08:08 +00:00
DissectorTable dt = toDissectorTable ( L , 1 ) ;
if ( dt - > created & & ! dt - > expired ) {
/* Created DissectorTable will pass GC two times */
dt - > expired = TRUE ;
} else {
g_free ( ( char * ) dt - > name ) ;
g_free ( ( char * ) dt - > ui_name ) ;
g_free ( dt ) ;
}
2015-07-07 15:30:44 +00:00
return 0 ;
}
WSLUA_METHODS DissectorTable_methods [ ] = {
WSLUA_CLASS_FNREG ( DissectorTable , new ) ,
WSLUA_CLASS_FNREG ( DissectorTable , get ) ,
WSLUA_CLASS_FNREG ( DissectorTable , list ) ,
WSLUA_CLASS_FNREG ( DissectorTable , heuristic_list ) ,
2021-03-11 18:31:55 +00:00
WSLUA_CLASS_FNREG ( DissectorTable , try_heuristics ) ,
2015-07-07 15:30:44 +00:00
WSLUA_CLASS_FNREG ( DissectorTable , add ) ,
WSLUA_CLASS_FNREG ( DissectorTable , set ) ,
WSLUA_CLASS_FNREG ( DissectorTable , remove ) ,
WSLUA_CLASS_FNREG ( DissectorTable , remove_all ) ,
WSLUA_CLASS_FNREG ( DissectorTable , try ) ,
WSLUA_CLASS_FNREG ( DissectorTable , get_dissector ) ,
WSLUA_CLASS_FNREG ( DissectorTable , add_for_decode_as ) ,
{ NULL , NULL }
} ;
WSLUA_META DissectorTable_meta [ ] = {
WSLUA_CLASS_MTREG ( DissectorTable , tostring ) ,
{ NULL , NULL }
} ;
int DissectorTable_register ( lua_State * L ) {
WSLUA_REGISTER_CLASS ( DissectorTable ) ;
2015-08-11 12:08:08 +00:00
lua_newtable ( L ) ;
dissectortable_table_ref = luaL_ref ( L , LUA_REGISTRYINDEX ) ;
2015-07-07 15:30:44 +00:00
return 0 ;
}
2015-08-11 12:08:08 +00:00
int wslua_deregister_dissector_tables ( lua_State * L ) {
/* for each registered DissectorTable do... */
lua_rawgeti ( L , LUA_REGISTRYINDEX , dissectortable_table_ref ) ;
for ( lua_pushnil ( L ) ; lua_next ( L , - 2 ) ; lua_pop ( L , 1 ) ) {
DissectorTable dt = checkDissectorTable ( L , - 1 ) ;
if ( dt - > created ) {
deregister_dissector_table ( dt - > name ) ;
}
}
lua_pop ( L , 1 ) ; /* dissector_table_ref */
return 0 ;
}
2015-07-07 15:30:44 +00:00
/*
2019-07-26 18:43:17 +00:00
* Editor modelines - https : //www.wireshark.org/tools/modelines.html
2015-07-07 15:30:44 +00:00
*
* 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 :
*/