ASN1: Added support for using #.REGISTER_NEW
This will register BER PDU-dissectors as "new". Return number of bytes dissected from dissector_try_* functions. Return number of bytes dissected in DissectorTable:try() This will make it possible to get dissected length when using dissector_try_*() and dissected ASN.1 length in Lua when using DissectorTable:try() (as we already have for Dissector:call). Change-Id: I8802a812bd484c1e8794c618b87e676003aea94a Reviewed-on: https://code.wireshark.org/review/4493 Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org> Tested-by: Stig Bjørlykke <stig@bjorlykke.org>
This commit is contained in:
parent
a87659c530
commit
acc09c2aa2
|
@ -434,6 +434,16 @@ register_ber_oid_dissector(const char *oid, dissector_t dissector, int proto, co
|
|||
oid_add_from_string(name, oid);
|
||||
}
|
||||
|
||||
void
|
||||
new_register_ber_oid_dissector(const char *oid, new_dissector_t dissector, int proto, const char *name)
|
||||
{
|
||||
dissector_handle_t dissector_handle;
|
||||
|
||||
dissector_handle = new_create_dissector_handle(dissector, proto);
|
||||
dissector_add_string("ber.oid", oid, dissector_handle);
|
||||
oid_add_from_string(name, oid);
|
||||
}
|
||||
|
||||
void
|
||||
register_ber_syntax_dissector(const char *syntax, int proto, dissector_t dissector)
|
||||
{
|
||||
|
@ -444,6 +454,16 @@ register_ber_syntax_dissector(const char *syntax, int proto, dissector_t dissect
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
new_register_ber_syntax_dissector(const char *syntax, int proto, new_dissector_t dissector)
|
||||
{
|
||||
dissector_handle_t dissector_handle;
|
||||
|
||||
dissector_handle = new_create_dissector_handle(dissector, proto);
|
||||
dissector_add_string("ber.syntax", syntax, dissector_handle);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
register_ber_oid_syntax(const char *oid, const char *name, const char *syntax)
|
||||
{
|
||||
|
@ -1071,6 +1091,7 @@ call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *p
|
|||
{
|
||||
tvbuff_t *next_tvb;
|
||||
const char *syntax = NULL;
|
||||
int len = 0;
|
||||
|
||||
if (!tvb) {
|
||||
return offset;
|
||||
|
@ -1080,13 +1101,15 @@ call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *p
|
|||
if (oid == NULL ||
|
||||
((((syntax = get_ber_oid_syntax(oid)) == NULL) ||
|
||||
/* First see if a syntax has been registered for this oid (user defined) */
|
||||
!dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree, data)) &&
|
||||
(len = dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree, data)) == 0) &&
|
||||
/* Then try registered oid's */
|
||||
(!dissector_try_string(ber_oid_dissector_table, oid, next_tvb, pinfo, tree, data)))) {
|
||||
(len = dissector_try_string(ber_oid_dissector_table, oid, next_tvb, pinfo, tree, data)) == 0))
|
||||
{
|
||||
proto_item *item = NULL;
|
||||
proto_tree *next_tree = NULL;
|
||||
gint length_remaining;
|
||||
|
||||
/* XXX we should probably use get_ber_length() here */
|
||||
length_remaining = tvb_length_remaining(tvb, offset);
|
||||
|
||||
if (oid == NULL) {
|
||||
|
@ -1117,7 +1140,7 @@ call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *p
|
|||
/* Decoded an ASN.1 tag with a length indicating this
|
||||
* could be BER encoded data. Try dissecting as unknown BER.
|
||||
*/
|
||||
dissect_unknown_ber(pinfo, next_tvb, 0, next_tree);
|
||||
len = dissect_unknown_ber(pinfo, next_tvb, 0, next_tree);
|
||||
} else {
|
||||
proto_tree_add_text(next_tree, next_tvb, 0, length_remaining,
|
||||
"Unknown Data (%d byte%s)", length_remaining,
|
||||
|
@ -1127,11 +1150,15 @@ call_ber_oid_callback(const char *oid, tvbuff_t *tvb, int offset, packet_info *p
|
|||
|
||||
}
|
||||
|
||||
/*XXX until we change the #.REGISTER signature for _PDU()s
|
||||
* into new_dissector_t we have to do this kludge with
|
||||
* manually step past the content in the ANY type.
|
||||
*/
|
||||
offset += tvb_length_remaining(tvb, offset);
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
} else {
|
||||
/*XXX until we change the #.REGISTER signature for _PDU()s
|
||||
* into new_dissector_t we have to do this kludge with
|
||||
* manually step past the content in the ANY type.
|
||||
*/
|
||||
offset += tvb_length_remaining(tvb, offset);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
@ -1140,10 +1167,12 @@ static int
|
|||
call_ber_syntax_callback(const char *syntax, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
tvbuff_t *next_tvb;
|
||||
int len = 0;
|
||||
|
||||
next_tvb = tvb_new_subset_remaining(tvb, offset);
|
||||
if (syntax == NULL ||
|
||||
!dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree, NULL)) {
|
||||
(len = dissector_try_string(ber_syntax_dissector_table, syntax, next_tvb, pinfo, tree, NULL)) == 0)
|
||||
{
|
||||
proto_item *item = NULL;
|
||||
proto_tree *next_tree = NULL;
|
||||
|
||||
|
@ -1161,14 +1190,18 @@ call_ber_syntax_callback(const char *syntax, tvbuff_t *tvb, int offset, packet_i
|
|||
if (item) {
|
||||
next_tree = proto_item_add_subtree(item, ett_ber_unknown);
|
||||
}
|
||||
dissect_unknown_ber(pinfo, next_tvb, 0, next_tree);
|
||||
len = dissect_unknown_ber(pinfo, next_tvb, 0, next_tree);
|
||||
}
|
||||
|
||||
/*XXX until we change the #.REGISTER signature for _PDU()s
|
||||
* into new_dissector_t we have to do this kludge with
|
||||
* manually step past the content in the ANY type.
|
||||
*/
|
||||
offset+=tvb_length_remaining(tvb, offset);
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
} else {
|
||||
/*XXX until we change the #.REGISTER signature for _PDU()s
|
||||
* into new_dissector_t we have to do this kludge with
|
||||
* manually step past the content in the ANY type.
|
||||
*/
|
||||
offset += tvb_length_remaining(tvb, offset);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -207,7 +207,11 @@ void register_ber_oid_dissector_handle(const char *oid, dissector_handle_t disse
|
|||
WS_DLL_PUBLIC
|
||||
void register_ber_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name);
|
||||
WS_DLL_PUBLIC
|
||||
void new_register_ber_oid_dissector(const char *oid, new_dissector_t dissector, int proto, const char *name);
|
||||
WS_DLL_PUBLIC
|
||||
void register_ber_syntax_dissector(const char *oid, int proto, dissector_t dissector);
|
||||
WS_DLL_PUBLIC
|
||||
void new_register_ber_syntax_dissector(const char *syntax, int proto, new_dissector_t dissector);
|
||||
void register_ber_oid_name(const char *oid, const char *name);
|
||||
WS_DLL_PUBLIC
|
||||
void register_ber_oid_syntax(const char *oid, const char *name, const char *syntax);
|
||||
|
|
|
@ -1110,7 +1110,7 @@ dissector_reset_uint(const char *name, const guint32 pattern)
|
|||
call the dissector with the arguments supplied, and return TRUE,
|
||||
otherwise return FALSE. */
|
||||
|
||||
gboolean
|
||||
int
|
||||
dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
|
||||
tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
const gboolean add_proto_name, void *data)
|
||||
|
@ -1118,7 +1118,7 @@ dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
|
|||
dtbl_entry_t *dtbl_entry;
|
||||
struct dissector_handle *handle;
|
||||
guint32 saved_match_uint;
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
|
||||
if (dtbl_entry != NULL) {
|
||||
|
@ -1132,7 +1132,7 @@ dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
|
|||
* so that other dissectors might have a chance
|
||||
* to dissect this packet.
|
||||
*/
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1142,7 +1142,7 @@ dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
|
|||
*/
|
||||
saved_match_uint = pinfo->match_uint;
|
||||
pinfo->match_uint = uint_val;
|
||||
ret = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
|
||||
len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
|
||||
pinfo->match_uint = saved_match_uint;
|
||||
|
||||
/*
|
||||
|
@ -1154,16 +1154,16 @@ dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
|
|||
*
|
||||
* 0 is also returned if the protocol wasn't enabled.
|
||||
*
|
||||
* If the packet was rejected, we return FALSE, so that
|
||||
* If the packet was rejected, we return 0, so that
|
||||
* other dissectors might have a chance to dissect this
|
||||
* packet, otherwise we return TRUE.
|
||||
* packet, otherwise we return the dissected length.
|
||||
*/
|
||||
return ret != 0;
|
||||
return len;
|
||||
}
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
int
|
||||
dissector_try_uint(dissector_table_t sub_dissectors, const guint32 uint_val,
|
||||
tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
|
@ -1384,17 +1384,17 @@ dissector_reset_string(const char *name, const gchar *pattern)
|
|||
/* Look for a given string in a given dissector table and, if found, call
|
||||
the dissector with the arguments supplied, and return TRUE, otherwise
|
||||
return FALSE. */
|
||||
gboolean
|
||||
int
|
||||
dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
|
||||
tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
||||
{
|
||||
dtbl_entry_t *dtbl_entry;
|
||||
struct dissector_handle *handle;
|
||||
int ret;
|
||||
int len;
|
||||
const gchar *saved_match_string;
|
||||
|
||||
/* XXX ASSERT instead ? */
|
||||
if (!string) return FALSE;
|
||||
if (!string) return 0;
|
||||
dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
|
||||
if (dtbl_entry != NULL) {
|
||||
/*
|
||||
|
@ -1407,7 +1407,7 @@ dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
|
|||
* so that other dissectors might have a chance
|
||||
* to dissect this packet.
|
||||
*/
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1417,7 +1417,7 @@ dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
|
|||
*/
|
||||
saved_match_string = pinfo->match_string;
|
||||
pinfo->match_string = string;
|
||||
ret = call_dissector_work(handle, tvb, pinfo, tree, TRUE, data);
|
||||
len = call_dissector_work(handle, tvb, pinfo, tree, TRUE, data);
|
||||
pinfo->match_string = saved_match_string;
|
||||
|
||||
/*
|
||||
|
@ -1429,13 +1429,13 @@ dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
|
|||
*
|
||||
* 0 is also returned if the protocol wasn't enabled.
|
||||
*
|
||||
* If the packet was rejected, we return FALSE, so that
|
||||
* If the packet was rejected, we return 0, so that
|
||||
* other dissectors might have a chance to dissect this
|
||||
* packet, otherwise we return TRUE.
|
||||
* packet, otherwise we return the dissected length.
|
||||
*/
|
||||
return ret != 0;
|
||||
return len;
|
||||
}
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Look for a given value in a given string dissector table and, if found,
|
||||
|
|
|
@ -245,13 +245,13 @@ WS_DLL_PUBLIC void dissector_reset_uint(const char *name, const guint32 pattern)
|
|||
/* Look for a given value in a given uint dissector table and, if found,
|
||||
call the dissector with the arguments supplied, and return TRUE,
|
||||
otherwise return FALSE. */
|
||||
WS_DLL_PUBLIC gboolean dissector_try_uint(dissector_table_t sub_dissectors,
|
||||
WS_DLL_PUBLIC int dissector_try_uint(dissector_table_t sub_dissectors,
|
||||
const guint32 uint_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
|
||||
/* Look for a given value in a given uint dissector table and, if found,
|
||||
call the dissector with the arguments supplied, and return TRUE,
|
||||
otherwise return FALSE. */
|
||||
WS_DLL_PUBLIC gboolean dissector_try_uint_new(dissector_table_t sub_dissectors,
|
||||
WS_DLL_PUBLIC int dissector_try_uint_new(dissector_table_t sub_dissectors,
|
||||
const guint32 uint_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data);
|
||||
|
||||
/** Look for a given value in a given uint dissector table and, if found,
|
||||
|
@ -294,7 +294,7 @@ WS_DLL_PUBLIC void dissector_reset_string(const char *name, const gchar *pattern
|
|||
/* Look for a given string in a given dissector table and, if found, call
|
||||
the dissector with the arguments supplied, and return TRUE, otherwise
|
||||
return FALSE. */
|
||||
WS_DLL_PUBLIC gboolean dissector_try_string(dissector_table_t sub_dissectors,
|
||||
WS_DLL_PUBLIC int dissector_try_string(dissector_table_t sub_dissectors,
|
||||
const gchar *string, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
|
||||
|
||||
/** Look for a given value in a given string dissector table and, if found,
|
||||
|
|
|
@ -2086,12 +2086,12 @@ WSLUA_METHOD Dissector_call(lua_State* L) {
|
|||
Pinfo pinfo = checkPinfo(L,WSLUA_ARG_Dissector_call_PINFO);
|
||||
TreeItem ti = checkTreeItem(L,WSLUA_ARG_Dissector_call_TREE);
|
||||
const char *volatile error = NULL;
|
||||
int ret = 0;
|
||||
int len = 0;
|
||||
|
||||
if (! ( d && tvb && pinfo) ) return 0;
|
||||
|
||||
TRY {
|
||||
ret = call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree);
|
||||
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);
|
||||
|
@ -2100,7 +2100,7 @@ WSLUA_METHOD Dissector_call(lua_State* L) {
|
|||
|
||||
if (error) { WSLUA_ERROR(Dissector_call,error); }
|
||||
|
||||
lua_pushnumber(L,(lua_Number)ret);
|
||||
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. */
|
||||
}
|
||||
|
||||
|
@ -2503,6 +2503,7 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
|
|||
ftenum_t type;
|
||||
gboolean handled = FALSE;
|
||||
const gchar *volatile error = NULL;
|
||||
int len = 0;
|
||||
|
||||
if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0;
|
||||
|
||||
|
@ -2513,25 +2514,28 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
|
|||
if (type == FT_STRING) {
|
||||
const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
|
||||
|
||||
if (!pattern)
|
||||
if (!pattern) {
|
||||
handled = TRUE;
|
||||
|
||||
else if (dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree, NULL))
|
||||
handled = TRUE;
|
||||
|
||||
} else {
|
||||
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 = luaL_checkint(L, WSLUA_ARG_DissectorTable_try_PATTERN);
|
||||
|
||||
if (dissector_try_uint(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree))
|
||||
len = dissector_try_uint(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
|
||||
if (len > 0) {
|
||||
handled = TRUE;
|
||||
|
||||
}
|
||||
} else {
|
||||
luaL_error(L,"No such type of dissector_table");
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
|
||||
|
||||
if (!handled) {
|
||||
len = call_dissector(lua_data_handle,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);
|
||||
|
@ -2540,7 +2544,8 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
|
|||
|
||||
if (error) { WSLUA_ERROR(DissectorTable_try,error); }
|
||||
|
||||
return 0;
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue