4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2007, Tamas Regos <tamas.regos@ericsson.com>
8 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
28 #include <ws_log_defs.h>
30 #include <wiretap/wtap.h>
32 #include <wsutil/report_message.h>
33 #include <wsutil/nstime.h>
34 #include <wsutil/ws_assert.h>
35 #include <wsutil/wslog.h>
37 #include <epan/packet.h>
38 #include <epan/strutil.h>
39 #include <epan/to_str.h>
40 #include <epan/prefs.h>
41 #include <epan/proto.h>
42 #include <epan/epan_dissect.h>
44 #include <epan/column-utils.h>
45 #include <wsutil/filesystem.h>
46 #include <epan/funnel.h>
47 #include <epan/tvbparse.h>
48 #include <epan/epan.h>
49 #include <epan/expert.h>
50 #include <epan/exceptions.h>
51 #include <epan/show_exception.h>
53 #include <epan/wslua/declare_wslua.h>
56 * @ingroup wslua_group
59 #define WSLUA_INIT_ROUTINES "init_routines"
60 #define WSLUA_PREFS_CHANGED "prefs_changed"
62 /* type conversion macros - lua_Number is a double, so casting isn't kosher; and
63 using Lua's already-available lua_tointeger() and luaL_checkinteger() might be
64 different on different machines; so use these instead please!
66 It can be important to choose the correct version of signed or unsigned
67 conversion macros; don't assume that you can freely convert to the signed
68 or unsigned integer of the same size later:
70 On 32-bit Windows x86, Lua 5.2 and earlier must use lua_tounsigned() and
71 luaL_checkunsigned() due to the use of float to integer inlined assembly.
73 On ARM, casting from a negative floating point number to an unsigned integer
74 type doesn't perform wraparound conversion in the same way as casting from
75 float to the same size signed integer then to unsigned does, unlike x86[-64].
76 (Commit 15392c324d5eaefcaa298cdee09cd5b40b12e09c)
78 On Lua 5.3 and later, numbers are stored as a kind of union between
79 Lua_Number and Lua_Integer. On 5.2 and earlier. all numbers are stored
80 as Lua_Number internally.
82 Be careful about using the 64-bit functions, as they convert from double
83 and lose precision at high values. See wslua_int64.c and the types there.
84 TODO: Check if Lua_Integer is 64 bit on Lua 5.3 and later.
86 #define wslua_toint(L,i) (int) ( lua_tointeger(L,i) )
87 #define wslua_toint32(L,i) (int32_t) ( lua_tointeger(L,i) )
88 #define wslua_toint64(L,i) (int64_t) ( lua_tonumber(L,i) )
89 #define wslua_touint64(L,i) (uint64_t) ( lua_tonumber(L,i) )
91 #define wslua_checkint(L,i) (int) ( luaL_checkinteger(L,i) )
92 #define wslua_checkint32(L,i) (int32_t) ( luaL_checkinteger(L,i) )
93 #define wslua_checkint64(L,i) (int64_t) ( luaL_checknumber(L,i) )
94 #define wslua_checkuint64(L,i) (uint64_t) ( luaL_checknumber(L,i) )
96 #define wslua_optint(L,i,d) (int) ( luaL_optinteger(L,i,d) )
97 #define wslua_optint32(L,i,d) (int32_t) ( luaL_optinteger(L,i,d) )
98 #define wslua_optint64(L,i,d) (int64_t) ( luaL_optnumber(L,i,d) )
99 #define wslua_optuint64(L,i,d) (uint64_t) ( luaL_optnumber(L,i,d) )
102 * On Lua 5.3 and later, the unsigned conversions may not be defined
103 * (depending on a compatibility define), and they're just casts if they
106 #if LUA_VERSION_NUM < 503
107 #define wslua_touint(L,i) (unsigned) ( lua_tounsigned(L,i) )
108 #define wslua_touint32(L,i) (uint32_t) ( lua_tounsigned(L,i) )
109 #define wslua_checkuint(L,i) (unsigned) ( luaL_checkunsigned(L,i) )
110 #define wslua_checkuint32(L,i) (uint32_t) ( luaL_checkunsigned(L,i) )
111 #define wslua_optuint(L,i,d) (unsigned) ( luaL_optunsigned(L,i,d) )
112 #define wslua_optuint32(L,i,d) (uint32_t) ( luaL_optunsigned(L,i,d) )
114 #define wslua_touint(L,i) (unsigned) ( lua_tointeger(L,i) )
115 #define wslua_touint32(L,i) (uint32_t) ( lua_tointeger(L,i) )
116 #define wslua_checkuint(L,i) (unsigned) ( luaL_checkinteger(L,i) )
117 #define wslua_checkuint32(L,i) (uint32_t) ( luaL_checkinteger(L,i) )
118 #define wslua_optuint(L,i,d) (unsigned) ( luaL_optinteger(L,i,d) )
119 #define wslua_optuint32(L,i,d) (uint32_t) ( luaL_optinteger(L,i,d) )
128 struct _wslua_pinfo
{
129 packet_info
* ws_pinfo
;
133 struct _wslua_tvbrange
{
134 struct _wslua_tvb
* tvb
;
140 funnel_text_window_t
* ws_tw
;
145 typedef struct _wslua_field_t
{
158 typedef struct _wslua_expert_field_t
{
164 } wslua_expert_field_t
;
167 * PREF_OBSOLETE is used for preferences that a module used to support
168 * but no longer supports; we give different error messages for them.
180 typedef struct _wslua_pref_t
{
194 uint32_t max_value
; /**< maximum value of a range */
196 const enum_val_t
*enumvals
; /**< list of name & values */
197 bool radio_buttons
; /**< true if it should be shown as
198 radio buttons rather than as an
199 option menu or combo box in
200 the preferences tab */
201 } enum_info
; /**< for PREF_ENUM */
202 char* default_s
; /**< default value for value.s */
203 } info
; /**< display/text file information */
205 struct _wslua_pref_t
* next
;
206 struct _wslua_proto_t
* proto
;
207 int ref
; /* Reference to enable Proto to deregister prefs. */
210 typedef struct _wslua_proto_t
{
218 int expert_info_table_ref
;
219 expert_module_t
*expert_module
;
220 module_t
*prefs_module
;
221 dissector_handle_t handle
;
225 bool is_postdissector
;
229 /* a "DissectorTable" object can be different things under the hood,
230 * since its heuristic_new() can create a heur_dissector_list_t that
231 * needs to be deregistered. */
232 struct _wslua_distbl_t
{
233 dissector_table_t table
;
234 heur_dissector_list_t heur_list
;
241 struct _wslua_col_info
{
252 struct _wslua_private_table
{
258 struct _wslua_treeitem
{
264 // Internal structure for wslua_field.c to track info about registered fields.
265 struct _wslua_header_field_info
{
267 header_field_info
*hfi
;
270 struct _wslua_field_info
{
275 typedef void (*tap_extractor_t
)(lua_State
*,const void*);
280 tap_extractor_t extractor
;
288 /* a "File" object can be different things under the hood. It can either
289 be a FILE_T from wtap struct, which it is during read operations, or it
290 can be a wtap_dumper struct during write operations. A wtap_dumper struct
291 has a FILE_T member, but we can't only store its pointer here because
292 dump operations need the whole thing to write out with. Ugh. */
295 wtap_dumper
*wdh
; /* will be NULL during read usage */
299 /* a "CaptureInfo" object can also be different things under the hood. */
300 struct _wslua_captureinfo
{
301 wtap
*wth
; /* will be NULL during write usage */
302 wtap_dumper
*wdh
; /* will be NULL during read usage */
307 wtap_rec
*rec
; /* this also exists in wtap struct, but is different for seek_read ops */
308 Buffer
*buf
; /* can't use the one in wtap because it's different for seek_read ops */
312 struct _wslua_const_phdr
{
318 struct _wslua_filehandler
{
319 struct file_type_subtype_info finfo
;
322 char* internal_description
; /* XXX - this is redundant; finfo.description should suffice */
330 int seq_read_close_ref
;
331 int can_write_encap_ref
;
337 bool removed
; /* This is set during reload Lua plugins */
345 struct _wslua_progdlg
{
352 typedef struct { const char* name
; tap_extractor_t extractor
; } tappable_t
;
354 typedef struct {const char* str
; enum ftenum id
; } wslua_ft_types_t
;
356 typedef wslua_pref_t
* Pref
;
357 typedef wslua_pref_t
* Prefs
;
358 typedef struct _wslua_field_t
* ProtoField
;
359 typedef struct _wslua_expert_field_t
* ProtoExpert
;
360 typedef struct _wslua_proto_t
* Proto
;
361 typedef struct _wslua_distbl_t
* DissectorTable
;
362 typedef dissector_handle_t Dissector
;
363 typedef GByteArray
* ByteArray
;
364 typedef struct _wslua_tvb
* Tvb
;
365 typedef struct _wslua_tvbrange
* TvbRange
;
366 typedef struct _wslua_col_info
* Column
;
367 typedef struct _wslua_cols
* Columns
;
368 typedef struct _wslua_pinfo
* Pinfo
;
369 typedef struct _wslua_treeitem
* TreeItem
;
370 typedef address
* Address
;
371 typedef nstime_t
* NSTime
;
372 typedef int64_t Int64
;
373 typedef uint64_t UInt64
;
374 typedef struct _wslua_header_field_info
* Field
;
375 typedef struct _wslua_field_info
* FieldInfo
;
376 typedef struct _wslua_tap
* Listener
;
377 typedef struct _wslua_tw
* TextWindow
;
378 typedef struct _wslua_progdlg
* ProgDlg
;
379 typedef struct _wslua_file
* File
;
380 typedef struct _wslua_captureinfo
* CaptureInfo
;
381 typedef struct _wslua_captureinfo
* CaptureInfoConst
;
382 typedef struct _wslua_phdr
* FrameInfo
;
383 typedef struct _wslua_const_phdr
* FrameInfoConst
;
384 typedef struct _wslua_filehandler
* FileHandler
;
385 typedef wtap_dumper
* Dumper
;
386 typedef struct lua_pseudo_header
* PseudoHeader
;
387 typedef tvbparse_t
* Parser
;
388 typedef tvbparse_wanted_t
* Rule
;
389 typedef tvbparse_elem_t
* Node
;
390 typedef tvbparse_action_t
* Shortcut
;
391 typedef struct _wslua_dir
* Dir
;
392 typedef struct _wslua_private_table
* PrivateTable
;
393 typedef char* Struct
;
396 * toXxx(L,idx) gets a Xxx from an index (Lua Error if fails)
397 * checkXxx(L,idx) gets a Xxx from an index after calling check_code (No Lua Error if it fails)
398 * pushXxx(L,xxx) pushes an Xxx into the stack
399 * isXxx(L,idx) tests whether we have an Xxx at idx
400 * shiftXxx(L,idx) removes and returns an Xxx from idx only if it has a type of Xxx, returns NULL otherwise
401 * WSLUA_CLASS_DEFINE must be used with a trailing ';'
402 * (a dummy typedef is used to be syntactically correct)
404 #define WSLUA_CLASS_DEFINE(C,check_code) \
405 WSLUA_CLASS_DEFINE_BASE(C,check_code,NULL)
407 #define WSLUA_CLASS_DEFINE_BASE(C,check_code,retval) \
408 C to##C(lua_State* L, int idx) { \
409 C* v = (C*)lua_touserdata (L, idx); \
410 if (!v) luaL_error(L, "bad argument %d (%s expected, got %s)", idx, #C, lua_typename(L, lua_type(L, idx))); \
411 return v ? *v : retval; \
413 C check##C(lua_State* L, int idx) { \
415 luaL_checktype(L,idx,LUA_TUSERDATA); \
416 p = (C*)luaL_checkudata(L, idx, #C); \
418 return p ? *p : retval; \
420 C* push##C(lua_State* L, C v) { \
422 luaL_checkstack(L,2,"Unable to grow stack\n"); \
423 p = (C*)lua_newuserdata(L,sizeof(C)); *p = v; \
424 luaL_getmetatable(L, #C); lua_setmetatable(L, -2); \
427 bool is##C(lua_State* L,int i) { \
429 if(!lua_isuserdata(L,i)) return false; \
430 p = lua_touserdata(L, i); \
431 lua_getfield(L, LUA_REGISTRYINDEX, #C); \
432 if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
434 return p ? true : false; \
436 C shift##C(lua_State* L,int i) { \
438 if(!lua_isuserdata(L,i)) return retval; \
439 p = (C*)lua_touserdata(L, i); \
440 lua_getfield(L, LUA_REGISTRYINDEX, #C); \
441 if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
443 if (p) { lua_remove(L,i); return *p; }\
448 typedef struct _wslua_attribute_table
{
449 const char *fieldname
;
450 lua_CFunction getfunc
;
451 lua_CFunction setfunc
;
452 } wslua_attribute_table
;
453 extern int wslua_reg_attributes(lua_State
*L
, const wslua_attribute_table
*t
, bool is_getter
);
455 #define WSLUA_TYPEOF_FIELD "__typeof"
459 /* temporary transition macro to reduce duplication in WSLUA_REGISTER_xxx. */
460 #define WSLUA_REGISTER_GC(C) \
461 luaL_getmetatable(L, #C); \
462 /* add the '__gc' metamethod with a C-function named Class__gc */ \
463 /* this will force ALL wslua classes to have a Class__gc function defined, which is good */ \
464 lua_pushcfunction(L, C ## __gc); \
465 lua_setfield(L, -2, "__gc"); \
466 /* pop the metatable */ \
469 #define __WSLUA_REGISTER_META(C, ATTRS) { \
470 const wslua_class C ## _class = { \
472 .instance_meta = C ## _meta, \
475 wslua_register_classinstance_meta(L, &C ## _class); \
476 WSLUA_REGISTER_GC(C); \
479 #define WSLUA_REGISTER_META(C) __WSLUA_REGISTER_META(C, NULL)
480 #define WSLUA_REGISTER_META_WITH_ATTRS(C) \
481 __WSLUA_REGISTER_META(C, C ## _attributes)
483 #define __WSLUA_REGISTER_CLASS(C, ATTRS) { \
484 const wslua_class C ## _class = { \
486 .class_methods = C ## _methods, \
487 .class_meta = C ## _meta, \
488 .instance_methods = C ## _methods, \
489 .instance_meta = C ## _meta, \
492 wslua_register_class(L, &C ## _class); \
493 WSLUA_REGISTER_GC(C); \
496 #define WSLUA_REGISTER_CLASS(C) __WSLUA_REGISTER_CLASS(C, NULL)
497 #define WSLUA_REGISTER_CLASS_WITH_ATTRS(C) \
498 __WSLUA_REGISTER_CLASS(C, C ## _attributes)
500 #define WSLUA_INIT(L) \
502 wslua_register_classes(L); \
503 wslua_register_functions(L);
507 #define WSLUA_FUNCTION extern int
508 /* This is for functions intended only to be used in init.lua */
509 #define WSLUA_INTERNAL_FUNCTION extern int
511 #define WSLUA_REGISTER_FUNCTION(name) { lua_pushcfunction(L, wslua_## name); lua_setglobal(L, #name); }
513 #define WSLUA_REGISTER extern int
515 #define WSLUA_METHOD static int
516 #define WSLUA_CONSTRUCTOR static int
517 #define WSLUA_ATTR_SET static int
518 #define WSLUA_ATTR_GET static int
519 #define WSLUA_METAMETHOD static int
521 #define WSLUA_METHODS static const luaL_Reg
522 #define WSLUA_META static const luaL_Reg
523 #define WSLUA_CLASS_FNREG(class,name) { #name, class##_##name }
524 #define WSLUA_CLASS_FNREG_ALIAS(class,aliasname,name) { #aliasname, class##_##name }
525 #define WSLUA_CLASS_MTREG(class,name) { "__" #name, class##__##name }
527 #define WSLUA_ATTRIBUTES static const wslua_attribute_table
528 /* following are useful macros for the rows in the array created by above */
529 #define WSLUA_ATTRIBUTE_RWREG(class,name) { #name, class##_get_##name, class##_set_##name }
530 #define WSLUA_ATTRIBUTE_ROREG(class,name) { #name, class##_get_##name, NULL }
531 #define WSLUA_ATTRIBUTE_WOREG(class,name) { #name, NULL, class##_set_##name }
533 #define WSLUA_ATTRIBUTE_FUNC_SETTER(C,field) \
534 static int C##_set_##field (lua_State* L) { \
535 C obj = check##C (L,1); \
536 if (! lua_isfunction(L,-1) ) \
537 return luaL_error(L, "%s's attribute `%s' must be a function", #C , #field ); \
538 if (obj->field##_ref != LUA_NOREF) \
539 /* there was one registered before, remove it */ \
540 luaL_unref(L, LUA_REGISTRYINDEX, obj->field##_ref); \
541 obj->field##_ref = luaL_ref(L, LUA_REGISTRYINDEX); \
544 /* silly little trick so we can add a semicolon after this macro */ \
545 typedef void __dummy##C##_set_##field
547 #define WSLUA_ATTRIBUTE_GET(C,name,block) \
548 static int C##_get_##name (lua_State* L) { \
549 C obj = check##C (L,1); \
553 /* silly little trick so we can add a semicolon after this macro */ \
554 typedef void __dummy##C##_get_##name
556 #define WSLUA_ATTRIBUTE_NAMED_BOOLEAN_GETTER(C,name,member) \
557 WSLUA_ATTRIBUTE_GET(C,name,{lua_pushboolean(L, obj->member );})
559 #define WSLUA_ATTRIBUTE_NAMED_INTEGER_GETTER(C,name,member) \
560 WSLUA_ATTRIBUTE_GET(C,name,{lua_pushinteger(L,(lua_Integer)(obj->member));})
562 #define WSLUA_ATTRIBUTE_INTEGER_GETTER(C,member) \
563 WSLUA_ATTRIBUTE_NAMED_INTEGER_GETTER(C,member,member)
565 #define WSLUA_ATTRIBUTE_BLOCK_NUMBER_GETTER(C,name,block) \
566 WSLUA_ATTRIBUTE_GET(C,name,{lua_pushnumber(L,(lua_Number)(block));})
568 #define WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(C,name,member) \
569 WSLUA_ATTRIBUTE_GET(C,name, { \
570 lua_pushstring(L,obj->member); /* this pushes nil if obj->member is null */ \
573 #define WSLUA_ATTRIBUTE_STRING_GETTER(C,member) \
574 WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(C,member,member)
576 #define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(C,name,member,option) \
577 WSLUA_ATTRIBUTE_GET(C,name, { \
579 if ((obj->member) && (obj->member->len > 0)) { \
580 if (wtap_block_get_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, &str) == WTAP_OPTTYPE_SUCCESS) { \
581 lua_pushstring(L,str); \
587 * XXX - we need to support Lua programs getting instances of a "multiple
588 * allowed" option other than the first option.
590 #define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_STRING_GETTER(C,name,member,option) \
591 WSLUA_ATTRIBUTE_GET(C,name, { \
593 if ((obj->member) && (obj->member->len > 0)) { \
594 if (wtap_block_get_nth_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, 0, &str) == WTAP_OPTTYPE_SUCCESS) { \
595 lua_pushstring(L,str); \
600 #define WSLUA_ATTRIBUTE_SET(C,name,block) \
601 static int C##_set_##name (lua_State* L) { \
602 C obj = check##C (L,1); \
606 /* silly little trick so we can add a semicolon after this macro */ \
607 typedef void __dummy##C##_set_##name
609 #define WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(C,name,member) \
610 WSLUA_ATTRIBUTE_SET(C,name, { \
611 if (! lua_isboolean(L,-1) ) \
612 return luaL_error(L, "%s's attribute `%s' must be a boolean", #C , #name ); \
613 obj->member = lua_toboolean(L,-1); \
616 /* to make this integral-safe, we treat it as int32 and then cast
617 Note: This will truncate 64-bit integers (but then Lua itself only has doubles */
618 #define WSLUA_ATTRIBUTE_NAMED_INTEGER_SETTER(C,name,member,cast) \
619 WSLUA_ATTRIBUTE_SET(C,name, { \
620 if (! lua_isinteger(L,-1) ) \
621 return luaL_error(L, "%s's attribute `%s' must be an integer", #C , #name ); \
622 obj->member = (cast) wslua_toint32(L,-1); \
625 #define WSLUA_ATTRIBUTE_INTEGER_SETTER(C,member,cast) \
626 WSLUA_ATTRIBUTE_NAMED_INTEGER_SETTER(C,member,member,cast)
628 #define WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(C,field,member,need_free) \
629 static int C##_set_##field (lua_State* L) { \
630 C obj = check##C (L,1); \
632 if (lua_isstring(L,-1) || lua_isnil(L,-1)) { \
633 s = g_strdup(lua_tostring(L,-1)); \
635 return luaL_error(L, "%s's attribute `%s' must be a string or nil", #C , #field ); \
637 if (obj->member != NULL && need_free) \
638 g_free((void*) obj->member); \
642 /* silly little trick so we can add a semicolon after this macro */ \
643 typedef void __dummy##C##_set_##field
645 #define WSLUA_ATTRIBUTE_STRING_SETTER(C,field,need_free) \
646 WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(C,field,field,need_free)
648 #define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(C,field,member,option) \
649 static int C##_set_##field (lua_State* L) { \
650 C obj = check##C (L,1); \
652 if (lua_isstring(L,-1) || lua_isnil(L,-1)) { \
653 s = g_strdup(lua_tostring(L,-1)); \
655 return luaL_error(L, "%s's attribute `%s' must be a string or nil", #C , #field ); \
657 if ((obj->member) && (obj->member->len > 0)) { \
658 wtap_block_set_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, s, strlen(s)); \
663 /* silly little trick so we can add a semicolon after this macro */ \
664 typedef void __dummy##C##_set_##field
666 #define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_STRING_SETTER(C,field,member,option) \
667 static int C##_set_##field (lua_State* L) { \
668 C obj = check##C (L,1); \
670 if (lua_isstring(L,-1) || lua_isnil(L,-1)) { \
671 s = g_strdup(lua_tostring(L,-1)); \
673 return luaL_error(L, "%s's attribute `%s' must be a string or nil", #C , #field ); \
675 if ((obj->member) && (obj->member->len > 0)) { \
676 wtap_block_set_nth_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, 0, s, strlen(s)); \
681 /* silly little trick so we can add a semicolon after this macro */ \
682 typedef void __dummy##C##_set_##field
684 #define WSLUA_ERROR(name,error) { luaL_error(L, "%s%s", #name ": ", error); }
685 #define WSLUA_ARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_ARG_ ## name ## _ ## attr, #name ": " error); }
686 #define WSLUA_OPTARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_OPTARG_##name##_ ##attr, #name ": " error); }
688 #define WSLUA_REG_GLOBAL_BOOL(L,n,v) { lua_pushboolean(L,v); lua_setglobal(L,n); }
689 #define WSLUA_REG_GLOBAL_STRING(L,n,v) { lua_pushstring(L,v); lua_setglobal(L,n); }
690 #define WSLUA_REG_GLOBAL_INTEGER(L,n,v) { lua_pushinteger(L,v); lua_setglobal(L,n); }
692 #define WSLUA_RETURN(i) return (i)
694 #define WSLUA_API extern
696 /* empty macro arguments trigger ISO C90 warnings, so do this */
699 #define FAIL_ON_NULL(s) if (! *p) luaL_argerror(L,idx,"null " s)
701 #define FAIL_ON_NULL_OR_EXPIRED(s) if (!*p) { \
702 luaL_argerror(L,idx,"null " s); \
703 } else if ((*p)->expired) { \
704 luaL_argerror(L,idx,"expired " s); \
707 /* Clears or marks references that connects Lua to Wireshark structures */
708 #define CLEAR_OUTSTANDING(C, marker, marker_val) void clear_outstanding_##C(void) { \
709 while (outstanding_##C->len) { \
710 C p = (C)g_ptr_array_remove_index_fast(outstanding_##C,0); \
712 if (p->marker != marker_val) \
713 p->marker = marker_val; \
720 #define WSLUA_CLASS_DECLARE(C) \
721 extern C to##C(lua_State* L, int idx); \
722 extern C check##C(lua_State* L, int idx); \
723 extern C* push##C(lua_State* L, C v); \
724 extern int C##_register(lua_State* L); \
725 extern bool is##C(lua_State* L,int i); \
726 extern C shift##C(lua_State* L,int i)
729 /* Throws a Wireshark exception, catchable via normal exceptions.h routines. */
730 #define THROW_LUA_ERROR(...) \
731 THROW_FORMATTED(DissectorError, __VA_ARGS__)
733 /* Catches any Wireshark exceptions in code and convert it into a Lua error.
734 * Normal restrictions for TRY/CATCH apply, in particular, do not return!
736 * This means do not call lua[L]_error() inside code, as that longjmps out
737 * of the TRY block to the Lua pcall! Use THROW_LUA_ERROR, which is caught
738 * and then converted into a Lua error.
740 * XXX: We CATCH_ALL here, although there's little point in catching
741 * OutOfMemoryError here. (Is CATCH_BOUNDS_AND_DISSECTOR_ERRORS sufficient?)
742 * There are some Exceptions that we catch and show but don't want to add
743 * the Lua error malformed expert info to the tree: BoundsError,
744 * FragmentBoundsError, and ScsiBoundsError (show_exception doesn't consider
745 * those malformed). The traceback might (or might not) be useful for those.
746 * Putting an extra malformed expert info in the tree in the cases that are
747 * malformed seems not so bad, but we might want to reduce that. Perhaps
748 * at least we could have a separate LuaError type and not call show_exception
749 * for that (we still need to handle some Lua errors that don't use this in
750 * dissector_error_handler.)
752 #define WRAP_NON_LUA_EXCEPTIONS(code) \
754 volatile bool has_error = false; \
757 } CATCH3(BoundsError, FragmentBoundsError, ScsiBoundsError) { \
758 show_exception(lua_tvb, lua_pinfo, lua_tree->tree, EXCEPT_CODE, GET_MESSAGE); \
760 show_exception(lua_tvb, lua_pinfo, lua_tree->tree, EXCEPT_CODE, GET_MESSAGE); \
761 lua_pushfstring(L, "%s: %s", __func__, GET_MESSAGE ? GET_MESSAGE : "Malformed packet"); \
764 if (has_error) { lua_error(L); } \
768 extern packet_info
* lua_pinfo
;
769 extern TreeItem lua_tree
;
770 extern tvbuff_t
* lua_tvb
;
771 extern bool lua_initialized
;
772 extern int lua_dissectors_table_ref
;
773 extern int lua_heur_dissectors_table_ref
;
775 WSLUA_DECLARE_CLASSES()
776 WSLUA_DECLARE_FUNCTIONS()
778 extern lua_State
* wslua_state(void);
781 /* wslua_internals.c */
783 * @brief Type for defining new classes.
785 * A new class is defined as a Lua table type. Instances of this class are
786 * created through pushXxx which sets the appropriate metatable.
788 typedef struct _wslua_class
{
789 const char *name
; /**< Class name that is exposed to Lua code. */
790 const luaL_Reg
*class_methods
; /**< Methods for the static class (optional) */
791 const luaL_Reg
*class_meta
; /**< Metatable for the static class (optional) */
792 const luaL_Reg
*instance_methods
; /**< Methods for class instances. (optional) */
793 const luaL_Reg
*instance_meta
; /**< Metatable for class instances (optional) */
794 const wslua_attribute_table
*attrs
; /**< Table of getters/setters for attributes on class instances (optional). */
796 void wslua_register_classinstance_meta(lua_State
*L
, const wslua_class
*cls_def
);
797 void wslua_register_class(lua_State
*L
, const wslua_class
*cls_def
);
799 extern int wslua__concat(lua_State
* L
);
800 extern bool wslua_toboolean(lua_State
* L
, int n
);
801 extern bool wslua_checkboolean(lua_State
* L
, int n
);
802 extern bool wslua_optbool(lua_State
* L
, int n
, bool def
);
803 extern lua_Integer
wslua_tointeger(lua_State
* L
, int n
);
804 extern int wslua_optboolint(lua_State
* L
, int n
, int def
);
805 extern const char* wslua_checklstring_only(lua_State
* L
, int n
, size_t *l
);
806 extern const char* wslua_checkstring_only(lua_State
* L
, int n
);
807 extern void wslua_setfuncs(lua_State
*L
, const luaL_Reg
*l
, int nup
);
808 extern const char* wslua_typeof_unknown
;
809 extern const char* wslua_typeof(lua_State
*L
, int idx
);
810 extern bool wslua_get_table(lua_State
*L
, int idx
, const char *name
);
811 extern bool wslua_get_field(lua_State
*L
, int idx
, const char *name
);
812 extern int dissect_lua(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
);
813 extern bool heur_dissect_lua(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
);
814 extern expert_field
* wslua_get_expert_field(const int group
, const int severity
);
815 extern void wslua_prefs_changed(void);
816 extern void proto_register_lua(void);
817 extern GString
* lua_register_all_taps(void);
818 extern void wslua_prime_dfilter(epan_dissect_t
*edt
);
819 extern bool wslua_has_field_extractors(void);
820 extern void lua_prime_all_fields(proto_tree
* tree
);
822 extern int Proto_commit(lua_State
* L
);
824 extern TreeItem
create_TreeItem(proto_tree
* tree
, proto_item
* item
);
826 extern void clear_outstanding_FuncSavers(void);
828 extern void Int64_pack(lua_State
* L
, luaL_Buffer
*b
, int idx
, bool asLittleEndian
);
829 extern int Int64_unpack(lua_State
* L
, const char *buff
, bool asLittleEndian
);
830 extern void UInt64_pack(lua_State
* L
, luaL_Buffer
*b
, int idx
, bool asLittleEndian
);
831 extern int UInt64_unpack(lua_State
* L
, const char *buff
, bool asLittleEndian
);
832 extern uint64_t getUInt64(lua_State
*L
, int i
);
834 extern Tvb
* push_Tvb(lua_State
* L
, tvbuff_t
* tvb
);
835 extern int push_wsluaTvb(lua_State
* L
, Tvb t
);
836 extern bool push_TvbRange(lua_State
* L
, tvbuff_t
* tvb
, int offset
, int len
);
837 extern void clear_outstanding_Tvb(void);
838 extern void clear_outstanding_TvbRange(void);
840 extern Pinfo
* push_Pinfo(lua_State
* L
, packet_info
* p
);
841 extern void clear_outstanding_Pinfo(void);
842 extern void clear_outstanding_Column(void);
843 extern void clear_outstanding_Columns(void);
844 extern void clear_outstanding_PrivateTable(void);
846 extern int get_hf_wslua_text(void);
847 extern TreeItem
push_TreeItem(lua_State
*L
, proto_tree
*tree
, proto_item
*item
);
848 extern void clear_outstanding_TreeItem(void);
850 extern FieldInfo
* push_FieldInfo(lua_State
*L
, field_info
* f
);
851 extern void clear_outstanding_FieldInfo(void);
853 extern void wslua_print_stack(char* s
, lua_State
* L
);
855 extern void wslua_init(register_cb cb
, void *client_data
);
856 extern void wslua_early_cleanup(void);
857 extern void wslua_cleanup(void);
859 extern tap_extractor_t
wslua_get_tap_extractor(const char* name
);
860 extern int wslua_set_tap_enums(lua_State
* L
);
862 extern ProtoField
wslua_is_field_available(lua_State
* L
, const char* field_abbr
);
864 extern char* wslua_get_actual_filename(const char* fname
);
866 extern int wslua_bin2hex(lua_State
* L
, const uint8_t* data
, const unsigned len
, const bool lowercase
, const char* sep
);
867 extern int wslua_hex2bin(lua_State
* L
, const char* data
, const unsigned len
, const char* sep
);
868 extern int luaopen_rex_pcre2(lua_State
*L
);
870 extern const char* get_current_plugin_version(void);
871 extern void clear_current_plugin_version(void);
873 extern int wslua_deregister_heur_dissectors(lua_State
* L
);
874 extern int wslua_deregister_protocols(lua_State
* L
);
875 extern int wslua_deregister_dissector_tables(lua_State
* L
);
876 extern int wslua_deregister_listeners(lua_State
* L
);
877 extern int wslua_deregister_fields(lua_State
* L
);
878 extern int wslua_deregister_filehandlers(lua_State
* L
);
879 extern void wslua_deregister_menus(void);
881 extern void wslua_init_wtap_filetypes(lua_State
* L
);
886 * Editor modelines - https://www.wireshark.org/tools/modelines.html
891 * indent-tabs-mode: nil
894 * vi: set shiftwidth=4 tabstop=8 expandtab:
895 * :indentSize=4:tabSize=8:noTabs=true: