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>
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
42 #include <wiretap/wtap.h>
44 #include <wsutil/report_err.h>
45 #include <wsutil/nstime.h>
47 #include <epan/packet.h>
48 #include <epan/strutil.h>
49 #include <epan/prefs.h>
50 #include <epan/proto.h>
51 #include <epan/epan_dissect.h>
53 #include <epan/filesystem.h>
54 #include <epan/funnel.h>
55 #include <epan/tvbparse.h>
56 #include <epan/epan.h>
58 #include "declare_wslua.h"
61 * @ingroup wslua_group
64 #define WSLUA_INIT_ROUTINES "init_routines"
65 #define WSLUA_PREFS_CHANGED "prefs_changed"
66 #define LOG_DOMAIN_LUA "wslua"
75 packet_info
* ws_pinfo
;
79 struct _wslua_tvbrange
{
80 struct _wslua_tvb
* tvb
;
86 funnel_text_window_t
* ws_tw
;
90 typedef struct _wslua_field_t
{
103 * PREF_OBSOLETE is used for preferences that a module used to support
104 * but no longer supports; we give different error messages for them.
116 typedef struct _wslua_pref_t
{
130 guint32 max_value
; /**< maximum value of a range */
132 const enum_val_t
*enumvals
; /**< list of name & values */
133 gboolean radio_buttons
; /**< TRUE if it should be shown as
134 radio buttons rather than as an
135 option menu or combo box in
136 the preferences tab */
137 } enum_info
; /**< for PREF_ENUM */
138 } info
; /**< display/text file information */
140 struct _wslua_pref_t
* next
;
141 struct _wslua_proto_t
* proto
;
144 typedef struct _wslua_proto_t
{
151 module_t
*prefs_module
;
152 dissector_handle_t handle
;
153 gboolean is_postdissector
;
156 struct _wslua_distbl_t
{
157 dissector_table_t table
;
161 struct _wslua_col_info
{
172 struct _wslua_private_table
{
174 gboolean is_allocated
;
178 struct _wslua_treeitem
{
184 typedef void (*tap_extractor_t
)(lua_State
*,const void*);
189 tap_extractor_t extractor
;
196 # define DIRECTORY_T GDir
197 # define FILE_T gchar
198 # define OPENDIR_OP(name) g_dir_open(name, 0, dir->dummy)
199 # define DIRGETNEXT_OP(dir) g_dir_read_name(dir)
200 # define GETFNAME_OP(file) (file);
201 # define CLOSEDIR_OP(dir) g_dir_close(dir)
209 struct _wslua_progdlg
{
210 funnel_progress_window_t
* pw
;
216 typedef struct { const char* name
; tap_extractor_t extractor
; } tappable_t
;
218 typedef struct {const gchar
* str
; enum ftenum id
; } wslua_ft_types_t
;
220 typedef wslua_pref_t
* Pref
;
221 typedef wslua_pref_t
* Prefs
;
222 typedef struct _wslua_field_t
* ProtoField
;
223 typedef struct _wslua_proto_t
* Proto
;
224 typedef struct _wslua_distbl_t
* DissectorTable
;
225 typedef dissector_handle_t Dissector
;
226 typedef GByteArray
* ByteArray
;
227 typedef struct _wslua_tvb
* Tvb
;
228 typedef struct _wslua_tvbrange
* TvbRange
;
229 typedef struct _wslua_col_info
* Column
;
230 typedef struct _wslua_cols
* Columns
;
231 typedef struct _wslua_pinfo
* Pinfo
;
232 typedef struct _wslua_treeitem
* TreeItem
;
233 typedef address
* Address
;
234 typedef nstime_t
* NSTime
;
235 typedef gint64
* Int64
;
236 typedef guint64
* UInt64
;
237 typedef header_field_info
** Field
;
238 typedef field_info
* FieldInfo
;
239 typedef struct _wslua_tap
* Listener
;
240 typedef struct _wslua_tw
* TextWindow
;
241 typedef struct _wslua_progdlg
* ProgDlg
;
242 typedef wtap_dumper
* Dumper
;
243 typedef struct lua_pseudo_header
* PseudoHeader
;
244 typedef tvbparse_t
* Parser
;
245 typedef tvbparse_wanted_t
* Rule
;
246 typedef tvbparse_elem_t
* Node
;
247 typedef tvbparse_action_t
* Shortcut
;
248 typedef struct _wslua_main
* WireShark
;
249 typedef struct _wslua_dir
* Dir
;
250 typedef struct _wslua_private_table
* PrivateTable
;
253 * toXxx(L,idx) gets a Xxx from an index (Lua Error if fails)
254 * checkXxx(L,idx) gets a Xxx from an index after calling check_code (No Lua Error if it fails)
255 * pushXxx(L,xxx) pushes an Xxx into the stack
256 * isXxx(L,idx) tests whether we have an Xxx at idx
257 * shiftXxx(L,idx) removes and returns an Xxx from idx only if it has a type of Xxx, returns NULL otherwise
258 * WSLUA_CLASS_DEFINE must be used with a trailing ';'
259 * (a dummy typedef is used to be syntactically correct)
261 #define WSLUA_CLASS_DEFINE(C,check_code,push_code) \
262 C to##C(lua_State* L, int idx) { \
263 C* v = (C*)lua_touserdata (L, idx); \
264 if (!v) luaL_error(L, "bad argument %d (%s expected, got %s)", idx, #C, lua_typename(L, lua_type(L, idx))); \
265 return v ? *v : NULL; \
267 C check##C(lua_State* L, int idx) { \
269 luaL_checktype(L,idx,LUA_TUSERDATA); \
270 p = (C*)luaL_checkudata(L, idx, #C); \
272 return p ? *p : NULL; \
274 C* push##C(lua_State* L, C v) { \
276 luaL_checkstack(L,2,"Unable to grow stack\n"); \
277 p = (C*)lua_newuserdata(L,sizeof(C)); *p = v; \
278 luaL_getmetatable(L, #C); lua_setmetatable(L, -2); \
282 gboolean is##C(lua_State* L,int i) { \
284 if(!lua_isuserdata(L,i)) return FALSE; \
285 p = lua_touserdata(L, i); \
286 lua_getfield(L, LUA_REGISTRYINDEX, #C); \
287 if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
289 return p ? TRUE : FALSE; \
291 C shift##C(lua_State* L,int i) { \
293 if(!lua_isuserdata(L,i)) return NULL; \
294 p = (C*)lua_touserdata(L, i); \
295 lua_getfield(L, LUA_REGISTRYINDEX, #C); \
296 if (p == NULL || !lua_getmetatable(L, i) || !lua_rawequal(L, -1, -2)) p=NULL; \
298 if (p) { lua_remove(L,i); return *p; }\
305 #define WSLUA_REGISTER_CLASS(C) { \
306 /* check for existing class table in global */ \
307 lua_getglobal (L, #C); \
308 if (!lua_isnil (L, -1)) { \
309 fprintf(stderr, "ERROR: Attempt to register class '%s' which already exists in global Lua table\n", #C); \
313 /* create new class method table and 'register' the class methods into it */ \
315 wslua_setfuncs (L, C ## _methods, 0); \
316 /* add a method-table field named '__typeof' = the class name, this is used by the typeof() Lua func */ \
317 lua_pushstring(L, #C); \
318 lua_setfield(L, -2, "__typeof"); \
319 /* create a new metatable and register metamethods into it */ \
320 luaL_newmetatable (L, #C); \
321 wslua_setfuncs (L, C ## _meta, 0); \
322 /* add the '__gc' metamethod with a C-function named Class__gc */ \
323 /* this will force ALL wslua classes to have a Class__gc function defined, which is good */ \
324 lua_pushcfunction(L, C ## __gc); \
325 lua_setfield(L, -2, "__gc"); \
326 /* push a copy of the class methods table, and set it to be the metatable's __index field */ \
327 lua_pushvalue (L, -2); \
328 lua_setfield (L, -2, "__index"); \
329 /* push a copy of the class methods table, and set it to be the metatable's __metatable field, to hide metatable */ \
330 lua_pushvalue (L, -2); \
331 lua_setfield (L, -2, "__metatable"); \
332 /* pop the metatable */ \
334 /* set the class methods table as the global class table */ \
335 lua_setglobal (L, #C); \
338 #define WSLUA_REGISTER_META(C) { \
339 /* check for existing metatable in registry */ \
340 luaL_getmetatable(L, #C); \
341 if (!lua_isnil (L, -1)) { \
342 fprintf(stderr, "ERROR: Attempt to register metatable '%s' which already exists in Lua registry\n", #C); \
346 /* create a new metatable and register metamethods into it */ \
347 luaL_newmetatable (L, #C); \
348 wslua_setfuncs (L, C ## _meta, 0); \
349 /* add a metatable field named '__typeof' = the class name, this is used by the typeof() Lua func */ \
350 lua_pushstring(L, #C); \
351 lua_setfield(L, -2, "__typeof"); \
352 /* add the '__gc' metamethod with a C-function named Class__gc */ \
353 /* this will force ALL wslua classes to have a Class__gc function defined, which is good */ \
354 lua_pushcfunction(L, C ## __gc); \
355 lua_setfield(L, -2, "__gc"); \
356 /* pop the metatable */ \
360 #define WSLUA_INIT(L) \
362 wslua_register_classes(L); \
363 wslua_register_functions(L);
367 #define WSLUA_FUNCTION extern int
369 #define WSLUA_REGISTER_FUNCTION(name) { lua_pushcfunction(L, wslua_## name); lua_setglobal(L, #name); }
371 #define WSLUA_REGISTER extern int
373 #define WSLUA_METHOD static int
374 #define WSLUA_CONSTRUCTOR static int
375 #define WSLUA_ATTR_SET static int
376 #define WSLUA_ATTR_GET static int
377 #define WSLUA_METAMETHOD static int
379 #define WSLUA_METHODS static const luaL_Reg
380 #define WSLUA_META static const luaL_Reg
381 #define WSLUA_CLASS_FNREG(class,name) { #name, class##_##name }
382 #define WSLUA_CLASS_FNREG_ALIAS(class,aliasname,name) { #aliasname, class##_##name }
384 #define WSLUA_ERROR(name,error) { luaL_error(L, ep_strdup_printf("%s%s", #name ": " ,error) ); return 0; }
385 #define WSLUA_ARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_ARG_ ## name ## _ ## attr, #name ": " error); return 0; }
386 #define WSLUA_OPTARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_OPTARG_##name##_ ##attr, #name ": " error); return 0; }
388 #define WSLUA_REG_GLOBAL_BOOL(L,n,v) { lua_pushboolean(L,v); lua_setglobal(L,n); }
389 #define WSLUA_REG_GLOBAL_STRING(L,n,v) { lua_pushstring(L,v); lua_setglobal(L,n); }
390 #define WSLUA_REG_GLOBAL_NUMBER(L,n,v) { lua_pushnumber(L,v); lua_setglobal(L,n); }
392 #define WSLUA_RETURN(i) return (i);
394 #define WSLUA_API extern
397 #define FAIL_ON_NULL(s) if (! *p) luaL_argerror(L,idx,s)
399 /* Clears or marks references that connects Lua to Wireshark structures */
400 #define CLEAR_OUTSTANDING(C, marker, marker_val) void clear_outstanding_##C(void) { \
401 while (outstanding_##C->len) { \
402 C p = (C)g_ptr_array_remove_index_fast(outstanding_##C,0); \
404 if (p->marker != marker_val) \
405 p->marker = marker_val; \
412 #define WSLUA_CLASS_DECLARE(C) \
413 extern C to##C(lua_State* L, int idx); \
414 extern C check##C(lua_State* L, int idx); \
415 extern C* push##C(lua_State* L, C v); \
416 extern int C##_register(lua_State* L); \
417 extern gboolean is##C(lua_State* L,int i); \
418 extern C shift##C(lua_State* L,int i)
420 extern packet_info
* lua_pinfo
;
421 extern TreeItem lua_tree
;
422 extern tvbuff_t
* lua_tvb
;
423 extern dissector_handle_t lua_data_handle
;
424 extern gboolean lua_initialized
;
425 extern int lua_dissectors_table_ref
;
427 WSLUA_DECLARE_CLASSES()
428 WSLUA_DECLARE_FUNCTIONS()
430 extern lua_State
* wslua_state(void);
432 extern gboolean
wslua_optbool(lua_State
* L
, int n
, gboolean def
);
433 extern const gchar
* lua_shiftstring(lua_State
* L
,int idx
);
434 extern void wslua_setfuncs(lua_State
*L
, const luaL_Reg
*l
, int nup
);
435 extern int dissect_lua(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
);
436 extern void wslua_prefs_changed(void);
437 extern void proto_register_lua(void);
438 extern GString
* lua_register_all_taps(void);
439 extern void wslua_prime_dfilter(epan_dissect_t
*edt
);
440 extern void lua_prime_all_fields(proto_tree
* tree
);
442 extern int Proto_commit(lua_State
* L
);
444 extern Tvb
* push_Tvb(lua_State
* L
, tvbuff_t
* tvb
);
445 extern void clear_outstanding_Tvb(void);
446 extern void clear_outstanding_TvbRange(void);
448 extern Pinfo
* push_Pinfo(lua_State
* L
, packet_info
* p
);
449 extern void clear_outstanding_Pinfo(void);
450 extern void clear_outstanding_Column(void);
451 extern void clear_outstanding_Columns(void);
452 extern void clear_outstanding_PrivateTable(void);
454 extern TreeItem
* push_TreeItem(lua_State
* L
, TreeItem ti
);
455 extern void clear_outstanding_TreeItem(void);
457 extern void wslua_print_stack(char* s
, lua_State
* L
);
459 extern int wslua_init(register_cb cb
, gpointer client_data
);
460 extern int wslua_cleanup(void);
462 extern tap_extractor_t
wslua_get_tap_extractor(const gchar
* name
);
463 extern int wslua_set_tap_enums(lua_State
* L
);
465 extern int luaopen_bit(lua_State
*L
);
467 extern int wslua_is_field_available(lua_State
* L
, const char* field_abbr
);