4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
9 * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
21 #include "epan/guid-utils.h"
22 #include "epan/proto.h"
25 #include <epan/decode_as.h>
26 #include <epan/exceptions.h>
27 #include <epan/show_exception.h>
28 #include <epan/dissectors/packet-dcerpc.h>
32 /* WSLUA_CONTINUE_MODULE Proto */
35 WSLUA_CLASS_DEFINE(Dissector
,NOP
);
37 A refererence to a dissector, used to call a dissector against a packet or a part of it.
40 WSLUA_CONSTRUCTOR
Dissector_get (lua_State
*L
) {
41 /* Obtains a dissector reference by name. */
42 #define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector. */
43 const char* name
= luaL_checkstring(L
,WSLUA_ARG_Dissector_get_NAME
);
46 if ((d
= find_dissector(name
))) {
52 WSLUA_RETURN(1); /* The <<lua_class_Dissector,`Dissector`>> reference if found, otherwise `nil`. */
55 /* Allow dissector key names to be sorted alphabetically. */
57 compare_dissector_key_name(const void *dissector_a
, const void *dissector_b
)
59 return strcmp((const char*)dissector_a
, (const char*)dissector_b
);
62 WSLUA_CONSTRUCTOR
Dissector_list (lua_State
*L
) {
63 /* Gets a Lua array table of all registered Dissector names.
65 Note: This is an expensive operation, and should only be used for troubleshooting.
67 GList
* list
= get_dissector_names();
71 if (!list
) return luaL_error(L
,"Cannot retrieve Dissector name list");
73 list
= g_list_sort(list
, (GCompareFunc
)compare_dissector_key_name
);
74 elist
= g_list_first(list
);
77 for (i
=1; elist
; i
++, elist
= g_list_next(elist
)) {
78 lua_pushstring(L
,(const char *) elist
->data
);
83 WSLUA_RETURN(1); /* The array table of registered dissector names. */
86 WSLUA_METHOD
Dissector_call(lua_State
* L
) {
87 /* Calls a dissector against a given packet (or part of it). */
88 #define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect. */
89 #define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info. */
90 #define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items. */
92 Dissector
volatile d
= checkDissector(L
,1);
93 Tvb tvb
= checkTvb(L
,WSLUA_ARG_Dissector_call_TVB
);
94 Pinfo pinfo
= checkPinfo(L
,WSLUA_ARG_Dissector_call_PINFO
);
95 TreeItem ti
= checkTreeItem(L
,WSLUA_ARG_Dissector_call_TREE
);
98 if (! ( d
&& tvb
&& pinfo
) ) return 0;
100 WRAP_NON_LUA_EXCEPTIONS(
101 len
= call_dissector(d
, tvb
->ws_tvb
, pinfo
->ws_pinfo
, ti
->tree
);
104 lua_pushinteger(L
,(lua_Integer
)len
);
105 WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
108 WSLUA_METAMETHOD
Dissector__call(lua_State
* L
) {
109 /* Calls a dissector against a given packet (or part of it). */
110 #define WSLUA_ARG_Dissector__call_TVB 2 /* The buffer to dissect. */
111 #define WSLUA_ARG_Dissector__call_PINFO 3 /* The packet info. */
112 #define WSLUA_ARG_Dissector__call_TREE 4 /* The tree on which to add the protocol items. */
113 return Dissector_call(L
);
116 WSLUA_METAMETHOD
Dissector__tostring(lua_State
* L
) {
117 /* Gets the Dissector's description. */
118 Dissector d
= checkDissector(L
,1);
120 lua_pushstring(L
,dissector_handle_get_description(d
));
121 WSLUA_RETURN(1); /* A string of the Dissector's description. */
124 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
125 static int Dissector__gc(lua_State
* L _U_
) {
126 /* do NOT free Dissector */
130 WSLUA_METHODS Dissector_methods
[] = {
131 WSLUA_CLASS_FNREG(Dissector
,get
),
132 WSLUA_CLASS_FNREG(Dissector
,call
),
133 WSLUA_CLASS_FNREG(Dissector
,list
),
137 WSLUA_META Dissector_meta
[] = {
138 WSLUA_CLASS_MTREG(Dissector
,tostring
),
139 WSLUA_CLASS_MTREG(Dissector
,call
),
143 int Dissector_register(lua_State
* L
) {
144 WSLUA_REGISTER_CLASS(Dissector
);
148 WSLUA_CLASS_DEFINE(DissectorTable
,NOP
);
150 A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp, sip are added to table "tcp.port").
152 Useful to add more dissectors to a table so that they appear in the “Decode As...” dialog.
155 static int dissectortable_table_ref
= LUA_NOREF
;
157 WSLUA_CONSTRUCTOR
DissectorTable_new (lua_State
*L
) {
158 /* Creates a new `DissectorTable` for your dissector's use. */
159 #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"). */
160 #define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the user interface.
161 Defaults to the name given in `tablename`, but can be any string. */
162 #define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* One of `ftypes.UINT8`, `ftypes.UINT16`,
163 `ftypes.UINT24`, `ftypes.UINT32`,
164 `ftypes.STRING`, `ftypes.NONE`,
166 Defaults to `ftypes.UINT32`. */
167 #define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* One of `base.NONE`, `base.DEC`, `base.HEX`,
168 `base.OCT`, `base.DEC_HEX` or `base.HEX_DEC`.
169 Defaults to `base.DEC`. */
170 #define WSLUA_OPTARG_DissectorTable_new_PROTO 5 /* The <<lua_class_Proto,`Proto`>> object that uses this dissector table. */
171 const char* name
= (const char*)luaL_checkstring(L
,WSLUA_ARG_DissectorTable_new_TABLENAME
);
172 const char* ui_name
= (const char*)luaL_optstring(L
,WSLUA_OPTARG_DissectorTable_new_UINAME
,name
);
173 enum ftenum type
= (enum ftenum
)luaL_optinteger(L
,WSLUA_OPTARG_DissectorTable_new_TYPE
,FT_UINT32
);
174 unsigned base
= (unsigned)luaL_optinteger(L
,WSLUA_OPTARG_DissectorTable_new_BASE
,BASE_DEC
);
197 /* Calling WSLUA_OPTARG_ERROR raises a Lua error and
198 returns from this function. */
200 DissectorTable_new
, TYPE
,
201 "must be ftypes.UINT{8,16,24,32}, ftypes.STRING, ftypes.GUID or ftypes.NONE");
205 dt
= (DissectorTable
)g_malloc(sizeof(struct _wslua_distbl_t
));
207 if (isProto(L
, WSLUA_OPTARG_DissectorTable_new_PROTO
)) {
208 Proto proto
= checkProto(L
, WSLUA_OPTARG_DissectorTable_new_PROTO
);
209 proto_id
= proto_get_id_by_short_name(proto
->name
);
212 dt
->table
= (type
== FT_NONE
) ?
213 register_decode_as_next_proto(proto_id
, name
, ui_name
, NULL
) :
214 register_dissector_table(name
, ui_name
, proto_id
, type
, base
);
215 dt
->heur_list
= NULL
;
216 dt
->name
= g_strdup(name
);
217 dt
->ui_name
= g_strdup(ui_name
);
221 lua_rawgeti(L
, LUA_REGISTRYINDEX
, dissectortable_table_ref
);
222 lua_pushstring(L
, name
);
223 pushDissectorTable(L
, dt
);
226 pushDissectorTable(L
, dt
);
227 WSLUA_RETURN(1); /* The newly created DissectorTable. */
230 WSLUA_CONSTRUCTOR
DissectorTable_heuristic_new(lua_State
*L
) {
231 /* Creates a new heuristic `DissectorTable` for your dissector's use. Returns true if table was created successfully.
232 * XXX - Currently it always returns nil.
236 #define WSLUA_ARG_DissectorTable_heuristic_new_TABLENAME 1 /* The short name of the table. Use lower-case alphanumeric, dot, and/or underscores. */
237 #define WSLUA_OPTARG_DissectorTable_heuristic_new_UINAME 2 /* The name of the table in the user interface.
238 Defaults to the name given in `tablename`, but can be any string. */
239 #define WSLUA_ARG_DissectorTable_heuristic_new_PROTO 3 /* The <<lua_class_Proto,`Proto`>> object that uses this dissector table. */
240 const char* name
= (const char*)luaL_checkstring(L
,WSLUA_ARG_DissectorTable_heuristic_new_TABLENAME
);
241 const char* ui_name
= NULL
;
244 heur_dissector_list_t list
;
245 int idx
= WSLUA_OPTARG_DissectorTable_heuristic_new_UINAME
;
247 if (lua_isstring(L
, idx
)) {
248 ui_name
= luaL_checkstring(L
, idx
);
252 proto
= checkProto(L
, idx
);
253 proto_id
= proto_get_id_by_short_name(proto
->name
);
255 list
= find_heur_dissector_list(name
);
257 luaL_error(L
, "Heuristic list '%s' already exists", name
);
263 dt
= (DissectorTable
)g_malloc(sizeof(struct _wslua_distbl_t
));
265 dt
->heur_list
= register_heur_dissector_list_with_description(name
, ui_name
, proto_id
);
266 dt
->name
= g_strdup(name
);
267 dt
->ui_name
= g_strdup(ui_name
);
271 lua_rawgeti(L
, LUA_REGISTRYINDEX
, dissectortable_table_ref
);
272 lua_pushstring(L
, name
);
273 pushDissectorTable(L
, dt
);
277 /* Return nil because this is not a regular DissectorTable that could
278 * be used with _try, _set, _add, etc., and so we need to build checks
279 * into the functions similar to File and CaptureInfo so that it
280 * doesn't get used as one. However, not returning it means that it
281 * doesn't get properly garbage collected. */
282 pushDissectorTable(L
, dt
);
283 WSLUA_RETURN(1); /* The newly created DissectorTable. */
288 /* this struct is used for passing ourselves user_data through dissector_all_tables_foreach_table(). */
289 typedef struct dissector_tables_foreach_table_info
{
292 } dissector_tables_foreach_table_info_t
;
294 /* this is the DATFunc_table function used for dissector_all_tables_foreach_table()
295 so we can get all dissector_table names. This pushes the name into a table at stack index 1 */
297 dissector_tables_list_func(const char *table_name
, const char *ui_name _U_
, void *user_data
) {
298 dissector_tables_foreach_table_info_t
*data
= (dissector_tables_foreach_table_info_t
*) user_data
;
299 lua_pushstring(data
->L
, table_name
);
300 lua_rawseti(data
->L
, 1, data
->num
);
301 data
->num
= data
->num
+ 1;
304 WSLUA_CONSTRUCTOR
DissectorTable_list (lua_State
*L
) {
305 /* Gets a Lua array table of all DissectorTable names - i.e., the string names you can
306 use for the first argument to DissectorTable.get().
308 Note: This is an expensive operation, and should only be used for troubleshooting.
310 dissector_tables_foreach_table_info_t data
= { 1, L
};
314 dissector_all_tables_foreach_table(dissector_tables_list_func
, (void *)&data
,
315 (GCompareFunc
)compare_dissector_key_name
);
317 WSLUA_RETURN(1); /* The array table of registered DissectorTable names. */
320 /* this is the DATFunc_heur_table function used for dissector_all_heur_tables_foreach_table()
321 so we can get all heuristic dissector list names. This pushes the name into a table at stack index 1 */
323 heur_dissector_tables_list_func(const char *table_name
, struct heur_dissector_list
*table _U_
, void *user_data
) {
324 dissector_tables_foreach_table_info_t
*data
= (dissector_tables_foreach_table_info_t
*) user_data
;
325 lua_pushstring(data
->L
, table_name
);
326 lua_rawseti(data
->L
, 1, data
->num
);
327 data
->num
= data
->num
+ 1;
330 WSLUA_CONSTRUCTOR
DissectorTable_heuristic_list (lua_State
*L
) {
331 /* Gets a Lua array table of all heuristic list names - i.e., the string names you can
332 use for the first argument in Proto:register_heuristic().
334 Note: This is an expensive operation, and should only be used for troubleshooting.
336 dissector_tables_foreach_table_info_t data
= { 1, L
};
340 dissector_all_heur_tables_foreach_table(heur_dissector_tables_list_func
, (void *)&data
, NULL
);
342 WSLUA_RETURN(1); /* The array table of registered heuristic list names */
345 WSLUA_CONSTRUCTOR
DissectorTable_try_heuristics (lua_State
*L
) {
347 Try all the dissectors in a given heuristic dissector table.
349 #define WSLUA_ARG_DissectorTable_try_heuristics_LISTNAME 1 /* The name of the heuristic dissector. */
350 #define WSLUA_ARG_DissectorTable_try_heuristics_TVB 2 /* The buffer to dissect. */
351 #define WSLUA_ARG_DissectorTable_try_heuristics_PINFO 3 /* The packet info. */
352 #define WSLUA_ARG_DissectorTable_try_heuristics_TREE 4 /* The tree on which to add the protocol items. */
354 const char* name
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_try_heuristics_LISTNAME
);
355 Tvb tvb
= checkTvb(L
,WSLUA_ARG_DissectorTable_try_heuristics_TVB
);
356 Pinfo pinfo
= checkPinfo(L
,WSLUA_ARG_DissectorTable_try_heuristics_PINFO
);
357 TreeItem tree
= checkTreeItem(L
,WSLUA_ARG_DissectorTable_try_heuristics_TREE
);
358 heur_dissector_list_t list
;
359 heur_dtbl_entry_t
*entry
;
361 if (!(name
&& tvb
&& pinfo
&& tree
)) return 0;
363 list
= find_heur_dissector_list(name
);
365 luaL_error(L
, "Heuristic list '%s' does not exist", name
);
369 lua_pushboolean(L
, dissector_try_heuristic(list
, tvb
->ws_tvb
, pinfo
->ws_pinfo
, tree
->tree
, &entry
, NULL
));
371 WSLUA_RETURN(1); /* True if the packet was recognized by the sub-dissector (stop dissection here). */
374 WSLUA_CONSTRUCTOR
DissectorTable_get (lua_State
*L
) {
376 Obtain a reference to an existing dissector table.
378 #define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
379 const char* name
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_get_TABLENAME
);
380 dissector_table_t table
= find_dissector_table(name
);
383 DissectorTable dt
= (DissectorTable
)g_malloc(sizeof(struct _wslua_distbl_t
));
385 dt
->heur_list
= NULL
;
386 dt
->name
= g_strdup(name
);
391 pushDissectorTable(L
, dt
);
396 WSLUA_RETURN(1); /* The <<lua_class_DissectorTable,`DissectorTable`>> reference if found, otherwise `nil`. */
399 WSLUA_METHOD
DissectorTable_add (lua_State
*L
) {
401 Add a <<lua_class_Proto,`Proto`>> with a dissector function or a <<lua_class_Dissector,`Dissector`>> object to the dissector table.
403 #define WSLUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer, a
404 integer range or a string depending on the table's type). */
405 #define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
407 DissectorTable dt
= checkDissectorTable(L
,1);
413 if( isProto(L
,WSLUA_ARG_DissectorTable_add_DISSECTOR
) ) {
415 p
= checkProto(L
,WSLUA_ARG_DissectorTable_add_DISSECTOR
);
419 WSLUA_ARG_ERROR(DissectorTable_add
,DISSECTOR
,"a Protocol that does not have a dissector cannot be added to a table");
423 } else if ( isDissector(L
,WSLUA_ARG_DissectorTable_add_DISSECTOR
) ) {
424 handle
= toDissector(L
,WSLUA_ARG_DissectorTable_add_DISSECTOR
);
426 WSLUA_ARG_ERROR(DissectorTable_add
,DISSECTOR
,"must be either Proto or Dissector");
430 type
= get_dissector_table_selector_type(dt
->name
);
432 if (type
== FT_STRING
) {
433 char* pattern
= g_strdup(luaL_checkstring(L
,WSLUA_ARG_DissectorTable_add_PATTERN
));
434 dissector_add_string(dt
->name
, pattern
,handle
);
436 } else if (type
== FT_GUID
) {
437 /* Handle GUID type (assuming it is represented as a string in Lua) */
438 const char* guid_str
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_add_PATTERN
);
439 fvalue_t
* fval
= fvalue_from_literal(type
, guid_str
, 0, NULL
);
440 const e_guid_t
* guid
= fvalue_get_guid(fval
);
441 guid_key gk
= {*guid
, 0};
442 /* The dcerpc.uuid table requires its own initializer */
443 if(strcmp(DCERPC_TABLE_NAME
, dt
->name
) == 0) {
445 memcpy(&uuid
, guid
, sizeof(e_guid_t
));
446 dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle
), &uuid
, 0, handle
);
448 dissector_add_guid(dt
->name
, &gk
, handle
);
449 guids_add_uuid(guid
, dissector_handle_get_protocol_short_name(handle
));
451 } else if ( type
== FT_UINT32
|| type
== FT_UINT16
|| type
== FT_UINT8
|| type
== FT_UINT24
) {
452 /* Either an integer or a range.
453 * For number literals, Lua only accepts "." as the decimal separator,
454 * but when converting strings to numbers, Lua will accept "." or the
455 * locale native separator, and when converting numbers to strings will
456 * use the locale native separator. (On Lua 5.2 and earlier, *only*
457 * the locale native separator may be accepted.) The behavior can be
458 * changed when compiling Lua, but generally isn't (and on UN*X we use
459 * system packages for Lua.)
461 * Some locales use "," as the decimal separator. range_convert_str
462 * expects "," to separate integers in ranges.
464 * We can either call setlocale(LC_NUMERIC, ...) to save, set, and
465 * restore the locale here (not thread safe), or try to work around it.
467 switch(lua_type(L
, WSLUA_ARG_DissectorTable_add_PATTERN
)) {
470 /* Try to convert to an integer. Note that on Lua 5.3 and higher
471 * this fails for numbers that can't be converted exactly, unlike
472 * on Lua 5.2 where it simply casts. This can be changed at Lua
473 * compile time, but on UN*X systems we use system Lua packages.
475 uint32_t port
= wslua_checkuint32(L
, WSLUA_ARG_DissectorTable_add_PATTERN
);
476 dissector_add_uint(dt
->name
, port
, handle
);
482 /* Convert all strings to ranges without trying number conversion,
483 * so that on locales that use decimal commas "10,11" is a range
484 * not the number 10.11.
485 * Using a range works fine for numbers that are single integers,
486 * but note range_convert_str will reject strings like "10.0",
487 * whereas Lua checkinteger will convert it.
489 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_add_PATTERN
);
490 range_t
*range
= NULL
;
491 if (range_convert_str(NULL
, &range
, pattern
, UINT32_MAX
) == CVT_NO_ERROR
) {
492 dissector_add_uint_range(dt
->name
, range
, handle
);
494 wmem_free (NULL
, range
);
495 WSLUA_ARG_ERROR(DissectorTable_add
,PATTERN
,"invalid integer or range");
498 wmem_free (NULL
, range
);
503 /* Just don't allow UInt64 types, but if 64-bit integer tables get
504 * supported (#20207) we'll need something like: */
506 checkUInt64(L
, checkUInt64(L
, 1);
512 WSLUA_ARG_ERROR(DissectorTable_add
,PATTERN
,"invalid integer or range");
516 luaL_error(L
,"Strange type %d for a DissectorTable",type
);
522 WSLUA_METHOD
DissectorTable_set (lua_State
*L
) {
523 /* Clear all existing dissectors from a table and add a new dissector or a range of new dissectors. */
524 #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). */
525 #define WSLUA_ARG_DissectorTable_set_DISSECTOR 3 /* The dissector to add (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
527 DissectorTable dt
= checkDissectorTable(L
,1);
533 if( isProto(L
,WSLUA_ARG_DissectorTable_set_DISSECTOR
) ) {
535 p
= checkProto(L
,WSLUA_ARG_DissectorTable_set_DISSECTOR
);
539 WSLUA_ARG_ERROR(DissectorTable_set
,DISSECTOR
,"a Protocol that does not have a dissector cannot be set to a table");
543 } else if ( isDissector(L
,WSLUA_ARG_DissectorTable_set_DISSECTOR
) ) {
544 handle
= toDissector(L
,WSLUA_ARG_DissectorTable_set_DISSECTOR
);
546 WSLUA_ARG_ERROR(DissectorTable_set
,DISSECTOR
,"must be either Proto or Dissector");
550 type
= get_dissector_table_selector_type(dt
->name
);
552 if (type
== FT_STRING
) {
553 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_set_PATTERN
);
554 dissector_delete_all(dt
->name
, handle
);
555 dissector_add_string(dt
->name
, pattern
,handle
);
556 } else if (type
== FT_GUID
) {
557 /* Handle GUID type (assuming it is represented as a string in Lua) */
558 const char* guid_str
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_set_PATTERN
);
559 fvalue_t
* fval
= fvalue_from_literal(type
, guid_str
, 0, NULL
);
560 const e_guid_t
* guid
= fvalue_get_guid(fval
);
561 guid_key gk
= {*guid
, 0};
562 /* The dcerpc.uuid table requires its own initializer */
563 if(strcmp(DCERPC_TABLE_NAME
, dt
->name
) == 0) {
565 memcpy(&uuid
, guid
, sizeof(e_guid_t
));
566 dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle
), &uuid
, 0, handle
);
568 dissector_add_guid(dt
->name
, &gk
, handle
);
569 guids_add_uuid(guid
, dissector_handle_get_protocol_short_name(handle
));
571 } else if ( type
== FT_UINT32
|| type
== FT_UINT16
|| type
== FT_UINT8
|| type
== FT_UINT24
) {
572 /* Either an integer or a range. See discussion above in _add. */
573 switch(lua_type(L
, WSLUA_ARG_DissectorTable_set_PATTERN
)) {
577 uint32_t port
= wslua_checkuint32(L
, WSLUA_ARG_DissectorTable_set_PATTERN
);
578 dissector_delete_all(dt
->name
, handle
);
579 dissector_add_uint(dt
->name
, port
, handle
);
585 /* Convert all strings to ranges */
586 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_set_PATTERN
);
587 range_t
*range
= NULL
;
588 if (range_convert_str(NULL
, &range
, pattern
, UINT32_MAX
) == CVT_NO_ERROR
) {
589 dissector_delete_all(dt
->name
, handle
);
590 dissector_add_uint_range(dt
->name
, range
, handle
);
592 wmem_free (NULL
, range
);
593 WSLUA_ARG_ERROR(DissectorTable_set
,PATTERN
,"invalid integer or range");
596 wmem_free (NULL
, range
);
601 WSLUA_ARG_ERROR(DissectorTable_set
,PATTERN
,"invalid integer or range");
605 luaL_error(L
,"Strange type %d for a DissectorTable",type
);
611 WSLUA_METHOD
DissectorTable_remove (lua_State
*L
) {
613 Remove a dissector or a range of dissectors from a table.
615 #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). */
616 #define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to remove (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
617 DissectorTable dt
= checkDissectorTable(L
,1);
623 if( isProto(L
,WSLUA_ARG_DissectorTable_remove_DISSECTOR
) ) {
625 p
= checkProto(L
,WSLUA_ARG_DissectorTable_remove_DISSECTOR
);
628 } else if ( isDissector(L
,WSLUA_ARG_DissectorTable_remove_DISSECTOR
) ) {
629 handle
= toDissector(L
,WSLUA_ARG_DissectorTable_remove_DISSECTOR
);
631 WSLUA_ARG_ERROR(DissectorTable_remove
,DISSECTOR
,"must be either Proto or Dissector");
635 type
= get_dissector_table_selector_type(dt
->name
);
637 if (type
== FT_STRING
) {
638 char* pattern
= g_strdup(luaL_checkstring(L
,WSLUA_ARG_DissectorTable_remove_PATTERN
));
639 dissector_delete_string(dt
->name
, pattern
,handle
);
641 } else if (type
== FT_GUID
) {
642 // Handle GUID type (assuming it is represented as a string in Lua)
643 const char* guid_str
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_remove_PATTERN
);
644 fvalue_t
* fval
= fvalue_from_literal(type
, guid_str
, 0, NULL
);
645 const e_guid_t
* guid
= fvalue_get_guid(fval
);
646 guid_key gk
= {*guid
, 0};
647 guids_delete_guid(guid
);
648 dissector_delete_guid(dt
->name
, &gk
, handle
);
649 } else if ( type
== FT_UINT32
|| type
== FT_UINT16
|| type
== FT_UINT8
|| type
== FT_UINT24
) {
650 /* Either an integer or a range. See discussion above in _add. */
651 switch(lua_type(L
, WSLUA_ARG_DissectorTable_set_PATTERN
)) {
655 uint32_t port
= wslua_checkuint32(L
, WSLUA_ARG_DissectorTable_set_PATTERN
);
656 dissector_delete_uint(dt
->name
, port
, handle
);
662 /* Convert all strings to ranges */
663 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_remove_PATTERN
);
664 range_t
*range
= NULL
;
665 if (range_convert_str(NULL
, &range
, pattern
, UINT32_MAX
) == CVT_NO_ERROR
) {
666 dissector_delete_uint_range(dt
->name
, range
, handle
);
668 wmem_free (NULL
, range
);
669 WSLUA_ARG_ERROR(DissectorTable_remove
,PATTERN
,"invalid integer or range");
672 wmem_free (NULL
, range
);
677 WSLUA_ARG_ERROR(DissectorTable_remove
,PATTERN
,"invalid integer or range");
685 WSLUA_METHOD
DissectorTable_remove_all (lua_State
*L
) {
686 /* Remove all dissectors from a table. */
687 #define WSLUA_ARG_DissectorTable_remove_all_DISSECTOR 2 /* The dissector to remove (either a <<lua_class_Proto,`Proto`>> or a <<lua_class_Dissector,`Dissector`>>). */
688 DissectorTable dt
= checkDissectorTable(L
,1);
693 if( isProto(L
,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR
) ) {
695 p
= checkProto(L
,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR
);
698 } else if ( isDissector(L
,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR
) ) {
699 handle
= toDissector(L
,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR
);
701 WSLUA_ARG_ERROR(DissectorTable_remove_all
,DISSECTOR
,"must be either Proto or Dissector");
705 dissector_delete_all (dt
->name
, handle
);
710 WSLUA_METHOD
DissectorTable_try (lua_State
*L
) {
712 Try to call a dissector from a table.
714 #define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
715 #define WSLUA_ARG_DissectorTable_try_TVB 3 /* The <<lua_class_Tvb,`Tvb`>> to dissect. */
716 #define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet's <<lua_class_Pinfo,`Pinfo`>>. */
717 #define WSLUA_ARG_DissectorTable_try_TREE 5 /* The <<lua_class_TreeItem,`TreeItem`>> on which to add the protocol items. */
718 DissectorTable
volatile dt
= checkDissectorTable(L
,1);
719 Tvb tvb
= checkTvb(L
,WSLUA_ARG_DissectorTable_try_TVB
);
720 Pinfo pinfo
= checkPinfo(L
,WSLUA_ARG_DissectorTable_try_PINFO
);
721 TreeItem ti
= checkTreeItem(L
,WSLUA_ARG_DissectorTable_try_TREE
);
723 bool handled
= false;
724 const char *volatile error
= NULL
;
727 if (! (dt
&& tvb
&& tvb
->ws_tvb
&& pinfo
&& ti
) ) return 0;
729 type
= get_dissector_table_selector_type(dt
->name
);
733 if (type
== FT_STRING
) {
734 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_try_PATTERN
);
736 len
= dissector_try_string_with_data(dt
->table
,pattern
,tvb
->ws_tvb
,pinfo
->ws_pinfo
,ti
->tree
, true, NULL
);
740 } else if ( type
== FT_GUID
) {
741 const char* guid_str
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_try_PATTERN
);
742 fvalue_t
* fval
= fvalue_from_literal(type
, guid_str
, 0, NULL
);
743 const e_guid_t
* guid
= fvalue_get_guid(fval
);
744 guid_key gk
= {*guid
, 0};
746 len
= dissector_try_guid_with_data(dt
->table
, &gk
,tvb
->ws_tvb
,pinfo
->ws_pinfo
,ti
->tree
, true, NULL
);
750 } else if ( type
== FT_UINT32
|| type
== FT_UINT16
|| type
== FT_UINT8
|| type
== FT_UINT24
) {
751 uint32_t port
= wslua_checkuint32(L
, WSLUA_ARG_DissectorTable_try_PATTERN
);
753 len
= dissector_try_uint(dt
->table
,port
,tvb
->ws_tvb
,pinfo
->ws_pinfo
,ti
->tree
);
757 } else if ( type
== FT_NONE
) {
758 len
= dissector_try_payload_with_data(dt
->table
,tvb
->ws_tvb
,pinfo
->ws_pinfo
,ti
->tree
, true, NULL
);
763 error
= "No such type of dissector table";
767 len
= call_data_dissector(tvb
->ws_tvb
, pinfo
->ws_pinfo
, ti
->tree
);
769 /* XXX Are we sure about this??? is this the right/only thing to catch */
770 } CATCH_NONFATAL_ERRORS
{
771 show_exception(tvb
->ws_tvb
, pinfo
->ws_pinfo
, ti
->tree
, EXCEPT_CODE
, GET_MESSAGE
);
772 error
= "Malformed frame";
775 if (error
) { WSLUA_ERROR(DissectorTable_try
,error
); }
777 lua_pushinteger(L
,(lua_Integer
)len
);
778 WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
781 WSLUA_METHOD
DissectorTable_get_dissector (lua_State
*L
) {
783 Try to obtain a dissector from a table.
785 #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). */
787 DissectorTable dt
= checkDissectorTable(L
,1);
789 dissector_handle_t handle
= NULL
;
793 type
= get_dissector_table_selector_type(dt
->name
);
795 if (type
== FT_STRING
) {
796 const char* pattern
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_get_dissector_PATTERN
);
797 handle
= dissector_get_string_handle(dt
->table
,pattern
);
798 } else if ( type
== FT_GUID
) {
799 const char* guid_str
= luaL_checkstring(L
,WSLUA_ARG_DissectorTable_get_dissector_PATTERN
);
800 fvalue_t
* fval
= fvalue_from_literal(type
, guid_str
, 0, NULL
);
801 const e_guid_t
* guid
= fvalue_get_guid(fval
);
802 guid_key gk
= {*guid
, 0};
803 handle
= dissector_get_guid_handle(dt
->table
,&gk
);
804 } else if ( type
== FT_UINT32
|| type
== FT_UINT16
|| type
== FT_UINT8
|| type
== FT_UINT24
) {
805 uint32_t port
= wslua_checkuint32(L
, WSLUA_ARG_DissectorTable_get_dissector_PATTERN
);
806 handle
= dissector_get_uint_handle(dt
->table
,port
);
810 pushDissector(L
,handle
);
815 WSLUA_RETURN(1); /* The <<lua_class_Dissector,`Dissector`>> handle if found, otherwise `nil` */
818 WSLUA_METHOD
DissectorTable_add_for_decode_as (lua_State
*L
) {
820 Add the given <<lua_class_Proto,`Proto`>> to the “Decode as...” list for this DissectorTable.
821 The passed-in <<lua_class_Proto,`Proto`>> object's `dissector()` function is used for dissecting.
823 #define WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO 2 /* The <<lua_class_Proto,`Proto`>> to add. */
824 DissectorTable dt
= checkDissectorTable(L
,1);
825 Proto proto
= checkProto(L
, WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO
);
826 dissector_handle_t handle
= NULL
;
828 if (! proto
->handle
) {
829 proto
->handle
= register_dissector(proto
->loname
, dissect_lua
, proto
->hfid
);
832 handle
= proto
->handle
;
834 dissector_add_for_decode_as(dt
->name
, handle
);
839 /* XXX It would be nice to iterate and print which dissectors it has */
840 WSLUA_METAMETHOD
DissectorTable__tostring(lua_State
* L
) {
841 /* Gets some debug information about the <<lua_class_DissectorTable,`DissectorTable`>>. */
842 DissectorTable dt
= checkDissectorTable(L
,1);
848 type
= get_dissector_table_selector_type(dt
->name
);
849 s
= g_string_new("DissectorTable ");
854 g_string_append_printf(s
,"%s String:\n",dt
->name
);
862 int base
= get_dissector_table_param(dt
->name
);
863 g_string_append_printf(s
,"%s Integer(%i):\n",dt
->name
,base
);
868 g_string_append_printf(s
,"%s GUID:\n",dt
->name
);
873 g_string_append_printf(s
,"%s only for Decode As:\n",dt
->name
);
877 luaL_error(L
,"Strange table type");
880 lua_pushstring(L
,s
->str
);
881 g_string_free(s
,TRUE
);
882 WSLUA_RETURN(1); /* A string of debug information about the <<lua_class_DissectorTable,`DissectorTable`>>. */
885 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
886 static int DissectorTable__gc(lua_State
* L
) {
887 DissectorTable dt
= toDissectorTable(L
,1);
889 if (dt
->created
&& !dt
->expired
) {
890 /* Created DissectorTable will pass GC two times */
893 g_free((char *)dt
->name
);
894 g_free((char *)dt
->ui_name
);
901 WSLUA_METHODS DissectorTable_methods
[] = {
902 WSLUA_CLASS_FNREG(DissectorTable
,new),
903 WSLUA_CLASS_FNREG(DissectorTable
,heuristic_new
),
904 WSLUA_CLASS_FNREG(DissectorTable
,get
),
905 WSLUA_CLASS_FNREG(DissectorTable
,list
),
906 WSLUA_CLASS_FNREG(DissectorTable
,heuristic_list
),
907 WSLUA_CLASS_FNREG(DissectorTable
,try_heuristics
),
908 WSLUA_CLASS_FNREG(DissectorTable
,add
),
909 WSLUA_CLASS_FNREG(DissectorTable
,set
),
910 WSLUA_CLASS_FNREG(DissectorTable
,remove
),
911 WSLUA_CLASS_FNREG(DissectorTable
,remove_all
),
912 WSLUA_CLASS_FNREG(DissectorTable
,try),
913 WSLUA_CLASS_FNREG(DissectorTable
,get_dissector
),
914 WSLUA_CLASS_FNREG(DissectorTable
,add_for_decode_as
),
918 WSLUA_META DissectorTable_meta
[] = {
919 WSLUA_CLASS_MTREG(DissectorTable
,tostring
),
923 int DissectorTable_register(lua_State
* L
) {
924 WSLUA_REGISTER_CLASS(DissectorTable
);
927 dissectortable_table_ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
932 int wslua_deregister_dissector_tables(lua_State
* L
) {
933 /* for each registered DissectorTable do... */
934 lua_rawgeti(L
, LUA_REGISTRYINDEX
, dissectortable_table_ref
);
935 for (lua_pushnil(L
); lua_next(L
, -2); lua_pop(L
, 1)) {
936 DissectorTable dt
= checkDissectorTable(L
, -1);
939 deregister_dissector_table(dt
->name
);
942 deregister_heur_dissector_list(dt
->name
);
947 lua_pop(L
, 1); /* dissector_table_ref */
954 * Editor modelines - https://www.wireshark.org/tools/modelines.html
959 * indent-tabs-mode: nil
962 * vi: set shiftwidth=4 tabstop=8 expandtab:
963 * :indentSize=4:tabSize=8:noTabs=true: