4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
16 #define WS_LOG_DOMAIN LOG_DOMAIN_WSLUA
19 #include "init_wslua.h"
23 #include <epan/expert.h>
24 #include <epan/ex-opt.h>
25 #include <epan/introspection.h>
26 #include <wiretap/introspection.h>
27 #include <wsutil/privileges.h>
28 #include <wsutil/file_util.h>
29 #include <wsutil/wslog.h>
30 #include <wsutil/array.h>
32 /* linked list of Lua plugins */
33 typedef struct _wslua_plugin
{
34 char *name
; /**< plugin name */
35 char *version
; /**< plugin version */
36 char *filename
; /**< plugin filename */
37 struct _wslua_plugin
*next
;
40 static wslua_plugin
*wslua_plugin_list
;
44 static void (*wslua_gui_print_func_ptr
)(const char *, void *);
45 static void *wslua_gui_print_data_ptr
;
46 static int wslua_lua_print_func_ref
= LUA_NOREF
;
48 /* XXX: global variables? Really?? Yuck. These could be done differently,
49 using the Lua registry */
50 packet_info
* lua_pinfo
;
51 struct _wslua_treeitem
* lua_tree
;
53 int lua_dissectors_table_ref
= LUA_NOREF
;
54 int lua_heur_dissectors_table_ref
= LUA_NOREF
;
58 static int hf_wslua_fake
;
59 static int hf_wslua_text
;
61 static expert_field ei_lua_error
;
63 static expert_field ei_lua_proto_checksum_comment
;
64 static expert_field ei_lua_proto_checksum_chat
;
65 static expert_field ei_lua_proto_checksum_note
;
66 static expert_field ei_lua_proto_checksum_warn
;
67 static expert_field ei_lua_proto_checksum_error
;
69 static expert_field ei_lua_proto_sequence_comment
;
70 static expert_field ei_lua_proto_sequence_chat
;
71 static expert_field ei_lua_proto_sequence_note
;
72 static expert_field ei_lua_proto_sequence_warn
;
73 static expert_field ei_lua_proto_sequence_error
;
75 static expert_field ei_lua_proto_response_comment
;
76 static expert_field ei_lua_proto_response_chat
;
77 static expert_field ei_lua_proto_response_note
;
78 static expert_field ei_lua_proto_response_warn
;
79 static expert_field ei_lua_proto_response_error
;
81 static expert_field ei_lua_proto_request_comment
;
82 static expert_field ei_lua_proto_request_chat
;
83 static expert_field ei_lua_proto_request_note
;
84 static expert_field ei_lua_proto_request_warn
;
85 static expert_field ei_lua_proto_request_error
;
87 static expert_field ei_lua_proto_undecoded_comment
;
88 static expert_field ei_lua_proto_undecoded_chat
;
89 static expert_field ei_lua_proto_undecoded_note
;
90 static expert_field ei_lua_proto_undecoded_warn
;
91 static expert_field ei_lua_proto_undecoded_error
;
93 static expert_field ei_lua_proto_reassemble_comment
;
94 static expert_field ei_lua_proto_reassemble_chat
;
95 static expert_field ei_lua_proto_reassemble_note
;
96 static expert_field ei_lua_proto_reassemble_warn
;
97 static expert_field ei_lua_proto_reassemble_error
;
99 static expert_field ei_lua_proto_malformed_comment
;
100 static expert_field ei_lua_proto_malformed_chat
;
101 static expert_field ei_lua_proto_malformed_note
;
102 static expert_field ei_lua_proto_malformed_warn
;
103 static expert_field ei_lua_proto_malformed_error
;
105 static expert_field ei_lua_proto_debug_comment
;
106 static expert_field ei_lua_proto_debug_chat
;
107 static expert_field ei_lua_proto_debug_note
;
108 static expert_field ei_lua_proto_debug_warn
;
109 static expert_field ei_lua_proto_debug_error
;
111 static expert_field ei_lua_proto_protocol_comment
;
112 static expert_field ei_lua_proto_protocol_chat
;
113 static expert_field ei_lua_proto_protocol_note
;
114 static expert_field ei_lua_proto_protocol_warn
;
115 static expert_field ei_lua_proto_protocol_error
;
117 static expert_field ei_lua_proto_security_comment
;
118 static expert_field ei_lua_proto_security_chat
;
119 static expert_field ei_lua_proto_security_note
;
120 static expert_field ei_lua_proto_security_warn
;
121 static expert_field ei_lua_proto_security_error
;
123 static expert_field ei_lua_proto_comments_comment
;
124 static expert_field ei_lua_proto_comments_chat
;
125 static expert_field ei_lua_proto_comments_note
;
126 static expert_field ei_lua_proto_comments_warn
;
127 static expert_field ei_lua_proto_comments_error
;
129 static expert_field ei_lua_proto_decryption_comment
;
130 static expert_field ei_lua_proto_decryption_chat
;
131 static expert_field ei_lua_proto_decryption_note
;
132 static expert_field ei_lua_proto_decryption_warn
;
133 static expert_field ei_lua_proto_decryption_error
;
135 static expert_field ei_lua_proto_assumption_comment
;
136 static expert_field ei_lua_proto_assumption_chat
;
137 static expert_field ei_lua_proto_assumption_note
;
138 static expert_field ei_lua_proto_assumption_warn
;
139 static expert_field ei_lua_proto_assumption_error
;
141 static expert_field ei_lua_proto_deprecated_comment
;
142 static expert_field ei_lua_proto_deprecated_chat
;
143 static expert_field ei_lua_proto_deprecated_note
;
144 static expert_field ei_lua_proto_deprecated_warn
;
145 static expert_field ei_lua_proto_deprecated_error
;
147 static expert_field ei_lua_proto_receive_comment
;
148 static expert_field ei_lua_proto_receive_chat
;
149 static expert_field ei_lua_proto_receive_note
;
150 static expert_field ei_lua_proto_receive_warn
;
151 static expert_field ei_lua_proto_receive_error
;
153 static expert_field ei_lua_proto_interface_comment
;
154 static expert_field ei_lua_proto_interface_chat
;
155 static expert_field ei_lua_proto_interface_note
;
156 static expert_field ei_lua_proto_interface_warn
;
157 static expert_field ei_lua_proto_interface_error
;
159 static int ett_wslua_traceback
;
162 lua_pinfo_end(wmem_allocator_t
*allocator _U_
, wmem_cb_event_t event _U_
,
165 clear_outstanding_Tvb();
166 clear_outstanding_TvbRange();
167 clear_outstanding_Pinfo();
168 clear_outstanding_Column();
169 clear_outstanding_Columns();
170 clear_outstanding_PrivateTable();
171 clear_outstanding_TreeItem();
172 clear_outstanding_FieldInfo();
173 clear_outstanding_FuncSavers();
175 /* keep invoking this callback later? */
179 static int wslua_not_register_menu(lua_State
* LS
) {
180 luaL_error(LS
,"too late to register a menu");
184 /* a getter for wslua_tree.c's TreeItem_add_item_any() to use */
185 int get_hf_wslua_text(void) {
186 return hf_wslua_text
;
190 // Attach the lua traceback to the proto_tree
191 static int dissector_error_handler(lua_State
*LS
) {
192 // Entering, stack: [ error_handler, dissector, errmsg ]
197 // Add the expert info Lua error message
198 // XXX - Should this add the current protocol to the message, and add to
199 // COL_INFO and the log, like DissectorError does?
200 proto_tree_add_expert_format(lua_tree
->tree
, lua_pinfo
, &ei_lua_error
, lua_tvb
, 0, 0,
201 "Lua Error: %s", lua_tostring(LS
,-1));
203 // Create a new proto sub_tree for the traceback
204 tb_item
= proto_tree_add_text_internal(lua_tree
->tree
, lua_tvb
, 0, 0, "Lua Traceback");
205 tb_tree
= proto_item_add_subtree(tb_item
, ett_wslua_traceback
);
207 // Push the traceback onto the stack
208 // After call, stack: [ error_handler, dissector, errmsg, tb_string ]
209 luaL_traceback(LS
, LS
, NULL
, 1);
211 // Get the string length of the traceback. Note that the string
212 // has a terminating NUL, but string_length doesn't include it.
213 // The lua docs say the string can have NULs in it too, but we
214 // ignore that because the traceback string shouldn't have them.
215 // This function does not own the string; it's still owned by lua.
216 size_t string_length
;
217 const char *orig_tb_string
= lua_tolstring(LS
, -1, &string_length
);
219 // We make the copy so we can modify the string. Don't forget the
220 // extra byte for the terminating NUL!
221 char *tb_string
= (char*) g_memdup2(orig_tb_string
, string_length
+1);
223 // The string has tabs and new lines in it
224 // We will add proto_items for each new-line-delimited sub-string.
225 // We also convert tabs to spaces, because the Wireshark GUI
226 // shows tabs literally as "\t".
228 // 'beginning' is the beginning of the sub-string
229 char *beginning
= tb_string
;
231 // 'p' is the pointer to the byte as we iterate over the string
235 bool skip_initial_tabs
= true;
236 size_t last_eol_i
= 0;
237 for (i
= 0 ; i
< string_length
; i
++) {
238 // At the beginning of a sub-string, we will convert tabs to spaces
239 if (skip_initial_tabs
) {
243 // Once we hit the first non-tab character in a substring,
244 // we won't convert tabs (until the next substring)
245 skip_initial_tabs
= false;
248 // If we see a newline, we add the substring to the proto tree
250 // Terminate the string.
252 proto_tree_add_text_internal(tb_tree
, lua_tvb
, 0, 0, "%s", beginning
);
254 skip_initial_tabs
= true;
261 // The last portion of the string doesn't have a newline, so add it here
262 // after the loop. But to be sure, check that we didn't just add it, in
263 // case lua decides to change it in the future.
264 if ( last_eol_i
< i
-1 ) {
265 proto_tree_add_text_internal(tb_tree
, lua_tvb
, 0, 0, "%s", beginning
);
271 // Return the same original error message
276 int dissect_lua(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
) {
277 int consumed_bytes
= tvb_captured_length(tvb
);
278 tvbuff_t
*saved_lua_tvb
= lua_tvb
;
279 packet_info
*saved_lua_pinfo
= lua_pinfo
;
280 struct _wslua_treeitem
*saved_lua_tree
= lua_tree
;
285 * almost equivalent to Lua:
286 * dissectors[current_proto](tvb,pinfo,tree)
289 // set the stack top be index 0
292 // After call, stack: [ error_handler_func ]
293 lua_pushcfunction(L
, dissector_error_handler
);
295 // Push the dissectors table onto the the stack
296 // After call, stack: [ error_handler_func, dissectors_table ]
297 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_dissectors_table_ref
);
299 // Push a copy of the current_proto string onto the stack
300 // After call, stack: [ error_handler_func, dissectors_table, current_proto ]
301 lua_pushstring(L
, pinfo
->current_proto
);
303 // dissectors_table[current_proto], a dissector, goes into the stack
304 // The key (current_proto) is popped off the stack.
305 // After call, stack: [ error_handler_func, dissectors_table, dissector ]
308 // We don't need the dissectors_table in the stack
309 // After call, stack: [ error_handler_func, dissector ]
312 // Is the dissector a function?
313 if (lua_isfunction(L
,2)) {
315 // After call, stack: [ error_handler_func, dissector, tvb ]
317 // After call, stack: [ error_handler_func, dissector, tvb, pinfo ]
319 // After call, stack: [ error_handler_func, dissector, tvb, pinfo, TreeItem ]
320 lua_tree
= push_TreeItem(L
, tree
, proto_tree_add_item(tree
, hf_wslua_fake
, tvb
, 0, 0, ENC_NA
));
321 proto_item_set_hidden(lua_tree
->item
);
323 if ( lua_pcall(L
, /*num_args=*/3, /*num_results=*/1, /*error_handler_func_stack_position=*/1) ) {
324 // do nothing; the traceback error message handler function does everything
327 /* if the Lua dissector reported the consumed bytes, pass it to our caller */
328 if (lua_isnumber(L
, -1)) {
329 /* we got the consumed bytes or the missing bytes as a negative number */
330 consumed_bytes
= wslua_toint(L
, -1);
336 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
337 "Lua Error: did not find the %s dissector in the dissectors table", pinfo
->current_proto
);
340 wmem_register_callback(pinfo
->pool
, lua_pinfo_end
, NULL
);
342 lua_pinfo
= saved_lua_pinfo
;
343 lua_tree
= saved_lua_tree
;
344 lua_tvb
= saved_lua_tvb
;
346 return consumed_bytes
;
350 /** Type of a heuristic dissector, used in heur_dissector_add().
352 * @param tvb the tvbuff with the (remaining) packet data
353 * @param pinfo the packet info of this packet (additional info)
354 * @param tree the protocol tree to be build or NULL
355 * @return true if the packet was recognized by the sub-dissector (stop dissection here)
357 bool heur_dissect_lua(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
) {
359 tvbuff_t
*saved_lua_tvb
= lua_tvb
;
360 packet_info
*saved_lua_pinfo
= lua_pinfo
;
361 struct _wslua_treeitem
*saved_lua_tree
= lua_tree
;
365 ws_assert(tvb
&& pinfo
);
367 if (!pinfo
->heur_list_name
|| !pinfo
->current_proto
) {
368 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
369 "internal error in heur_dissect_lua: NULL list name or current proto");
373 /* heuristic functions are stored in a table in the registry; the registry has a
374 * table at reference lua_heur_dissectors_table_ref, and that table has keys for
375 * the heuristic listname (e.g., "udp", "tcp", etc.), and that key's value is a
376 * table of keys of the Proto->name, and their value is the function.
377 * So it's like registry[table_ref][heur_list_name][proto_name] = func
382 /* get the table of all lua heuristic dissector lists */
383 lua_rawgeti(L
, LUA_REGISTRYINDEX
, lua_heur_dissectors_table_ref
);
385 /* get the table inside that, for the lua heuristic dissectors of the requested heur list */
386 if (!wslua_get_table(L
, -1, pinfo
->heur_list_name
)) {
387 /* this shouldn't happen */
389 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
390 "internal error in heur_dissect_lua: no %s heur list table", pinfo
->heur_list_name
);
394 /* get the table inside that, for the specific lua heuristic dissector */
395 if (!wslua_get_field(L
,-1,pinfo
->current_proto
)) {
396 /* this shouldn't happen */
398 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
399 "internal error in heur_dissect_lua: no %s heuristic dissector for list %s",
400 pinfo
->current_proto
, pinfo
->heur_list_name
);
404 /* remove the table of all lists (the one in the registry) */
406 /* remove the heur_list_name heur list table */
409 if (!lua_isfunction(L
,-1)) {
410 /* this shouldn't happen */
412 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
413 "internal error in heur_dissect_lua: %s heuristic dissector is not a function", pinfo
->current_proto
);
419 lua_tree
= push_TreeItem(L
, tree
, proto_tree_add_item(tree
, hf_wslua_fake
, tvb
, 0, 0, ENC_NA
));
420 proto_item_set_hidden(lua_tree
->item
);
422 if ( lua_pcall(L
,3,1,0) ) {
423 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
424 "Lua Error: error calling %s heuristic dissector: %s", pinfo
->current_proto
, lua_tostring(L
,-1));
427 if (lua_isboolean(L
, -1) || lua_isnil(L
, -1)) {
428 result
= lua_toboolean(L
, -1);
429 } else if (lua_type(L
, -1) == LUA_TNUMBER
) {
430 result
= lua_tointeger(L
,-1) != 0 ? true : false;
432 proto_tree_add_expert_format(tree
, pinfo
, &ei_lua_error
, tvb
, 0, 0,
433 "Lua Error: invalid return value from Lua %s heuristic dissector", pinfo
->current_proto
);
438 wmem_register_callback(pinfo
->pool
, lua_pinfo_end
, NULL
);
440 lua_pinfo
= saved_lua_pinfo
;
441 lua_tree
= saved_lua_tree
;
442 lua_tvb
= saved_lua_tvb
;
447 static void iter_table_and_call(lua_State
* LS
, const char* table_name
, lua_CFunction error_handler
) {
450 lua_pushcfunction(LS
,error_handler
);
451 lua_getglobal(LS
, table_name
);
453 if (!lua_istable(LS
, 2)) {
454 report_failure("Lua: either `%s' does not exist or it is not a table!\n",table_name
);
462 while (lua_next(LS
, 2)) {
463 const char* name
= lua_tostring(L
,-2);
465 if (lua_isfunction(LS
,-1)) {
467 if ( lua_pcall(LS
,0,0,1) ) {
472 report_failure("Lua: Something not a function got its way into the %s.%s",table_name
,name
);
483 static int init_error_handler(lua_State
* LS
) {
484 const char* error
= lua_tostring(LS
,1);
485 report_failure("Lua: Error during execution of initialization:\n %s",error
);
490 static bool init_routine_initialized
;
491 static void wslua_init_routine(void) {
493 if ( ! init_routine_initialized
) {
495 * This must be done only once during the entire life of
496 * tshark/wireshark, because it must be done only once per the life of
497 * the Lua state/engine, so we guard this with the boolean above;
498 * otherwise it would occur every time a file is opened (every time
499 * epan_new() is called).
501 * If we ever allow the Lua state to be restarted, or to have multiple
502 * Lua states, we'll need to change this.
504 lua_prime_all_fields(NULL
);
505 init_routine_initialized
= true;
509 iter_table_and_call(L
, WSLUA_INIT_ROUTINES
,init_error_handler
);
514 static void wslua_cleanup_routine(void) {
516 iter_table_and_call(L
, WSLUA_INIT_ROUTINES
,init_error_handler
);
520 static int prefs_changed_error_handler(lua_State
* LS
) {
521 const char* error
= lua_tostring(LS
,1);
522 report_failure("Lua: Error during execution of prefs apply callback:\n %s",error
);
526 void wslua_prefs_changed(void) {
528 iter_table_and_call(L
, WSLUA_PREFS_CHANGED
,prefs_changed_error_handler
);
532 static const char *getF(lua_State
*LS _U_
, void *ud
, size_t *size
)
535 static char buff
[512];
536 if (feof(f
)) return NULL
;
537 *size
=fread(buff
,1,sizeof(buff
),f
);
538 return (*size
>0) ? buff
: NULL
;
541 static int error_handler_with_callback(lua_State
*LS
) {
542 const char *msg
= lua_tostring(LS
, 1);
543 luaL_traceback(LS
, LS
, msg
, 1); /* push message with traceback. */
544 lua_remove(LS
, -2); /* remove original msg */
548 static void wslua_add_plugin(const char *name
, const char *version
, const char *filename
)
550 wslua_plugin
*new_plug
, *lua_plug
;
552 lua_plug
= wslua_plugin_list
;
553 new_plug
= g_new(wslua_plugin
, 1);
555 if (!lua_plug
) { /* the list is empty */
556 wslua_plugin_list
= new_plug
;
558 while (lua_plug
->next
!= NULL
) {
559 lua_plug
= lua_plug
->next
;
561 lua_plug
->next
= new_plug
;
564 new_plug
->name
= g_strdup(name
);
565 new_plug
->version
= g_strdup(version
);
566 new_plug
->filename
= g_strdup(filename
);
567 new_plug
->next
= NULL
;
570 static void wslua_clear_plugin_list(void)
572 wslua_plugin
*lua_plug
;
574 while (wslua_plugin_list
) {
575 lua_plug
= wslua_plugin_list
;
576 wslua_plugin_list
= wslua_plugin_list
->next
;
577 g_free (lua_plug
->name
);
578 g_free (lua_plug
->version
);
579 g_free (lua_plug
->filename
);
584 static int lua_script_push_args(const int script_num
) {
585 char* argname
= ws_strdup_printf("lua_script%d", script_num
);
586 const char* argvalue
= NULL
;
587 int i
, count
= ex_opt_count(argname
);
589 for (i
= 0; i
< count
; i
++) {
590 argvalue
= ex_opt_get_nth(argname
, i
);
591 lua_pushstring(L
,argvalue
);
598 /* Prepends a path to the global package path (used by require)
599 * We could add a custom loader to package.searchers instead, which
600 * might be more useful in some way. We could also have some method of
601 * saving and restoring the path, instead of constantly adding to it. */
602 static void prepend_path(const char* dirname
) {
605 /* prepend the directory name to _G.package.path */
606 lua_getglobal(L
, "package"); /* get the package table from the global table */
607 lua_getfield(L
, -1, "path"); /* get the path field from the package table */
608 path
= luaL_checkstring(L
, -1); /* get the path string */
609 lua_pop(L
, 1); /* pop the path string */
610 /* prepend the path */
611 /* We could also add "?/init.lua" for packages. */
612 lua_pushfstring(L
, "%s" G_DIR_SEPARATOR_S
"?.lua;%s",
614 lua_setfield(L
, -2, "path");
618 #define FILE_NAME_KEY "__FILE__"
619 #define DIR_NAME_KEY "__DIR__"
620 #define DIR_SEP_NAME_KEY "__DIR_SEPARATOR__"
621 /* assumes a loaded chunk's function is on top of stack */
622 static void set_file_environment(const char* filename
, const char* dirname
) {
623 lua_newtable(L
); /* environment for script (index 3) */
625 /* XXX - Do we need this? A script can get the filename and path from
626 * debug.getinfo/lua_Debug source */
627 lua_pushstring(L
, filename
); /* tell the script about its filename */
628 lua_setfield(L
, -2, FILE_NAME_KEY
); /* make it accessible at __FILE__ */
630 lua_pushstring(L
, dirname
); /* tell the script about its dirname */
631 lua_setfield(L
, -2, DIR_NAME_KEY
); /* make it accessible at __DIR__ */
633 /* XXX - Do we need this? package.config:sub(1,1) is the directory separator */
634 lua_pushstring(L
, G_DIR_SEPARATOR_S
); /* tell the script the directory separator */
635 lua_setfield(L
, -2, DIR_SEP_NAME_KEY
); /* make it accessible at __DIR_SEPARATOR__ */
637 lua_newtable(L
); /* new metatable */
639 lua_pushglobaltable(L
);
641 lua_setfield(L
, -2, "__index"); /* make metatable's __index point to global table */
643 lua_setmetatable(L
, -2); /* pop metatable, set it as metatable of environment */
645 lua_setupvalue(L
, -2, 1); /* pop environment and assign it to upvalue 1 */
647 /* The result of this is a new environment that falls back to reading from
648 * the global environment for any entry not in the new environment, but
649 * can't change the global environment while running.
651 * Unfortunately, while we could create a file-local package.path, it
652 * wouldn't have any effect on the path actually used by requires, since
653 * the requires function has as an upvalue the original package table;
654 * we can't change the behavior of requires without changing it for
655 * the global environment and for all scripts.
657 * For some of the same reasons, if the script itself calls require(),
658 * that actually affects the original global environment too, so this
659 * sandboxing doesn't completely work to keep the global environment
660 * unchanged. Is it worth it?
664 /* This loads plugins like Lua modules / libraries, using require().
665 * It has the advantage that loaded files get add to the package.loaded
666 * table, so files aren't run again by require() either.
668 static bool lua_load_plugin(const char* filename
) {
672 const char *basename
= get_basename(filename
);
673 char *dot
= strrchr(basename
, '.');
675 trimmed
= g_strndup(basename
, dot
- basename
);
677 trimmed
= g_strdup(basename
);
682 lua_pushcfunction(L
, error_handler_with_callback
);
684 lua_getglobal(L
, "require");
686 lua_pushstring(L
, trimmed
);
689 /* Ignore the return from "require" by passing 0 as nresults to lua_pcall
690 * (we could add it to the global table using the name as dolibrary() does,
691 * but that is deprecated style in modern Lua.)
693 status
= lua_pcall(L
, 1, 0, 1);
694 if (status
!= LUA_OK
) {
697 report_failure("Lua: Error during loading:\n%s", lua_tostring(L
, -1));
700 report_failure("Lua: Error during loading: out of memory");
703 report_failure("Lua: Error during loading: error while retrieving error message");
706 report_failure("Lua: Error during loading: unknown error %d", status
);
710 return status
== LUA_OK
;
713 /* If file_count > 0 then it's a command-line-added user script, and the count
714 * represents which user script it is (first=1, second=2, etc.).
715 * If dirname != NULL, then it's a user script and the dirname will get put in a file environment
716 * If dirname == NULL then it's a wireshark script and no file environment is created
718 static bool lua_load_script(const char* filename
, const char* dirname
, const int file_count
) {
723 if (! ( file
= ws_fopen(filename
,"r")) ) {
724 report_open_failure(filename
,errno
,false);
730 lua_pushcfunction(L
, error_handler_with_callback
);
731 /* The source argument should start with '@' to indicate a file. */
732 lua_pushfstring(L
, "@%s", filename
);
734 error
= lua_load(L
, getF
, file
, lua_tostring(L
, -1), NULL
);
739 set_file_environment(filename
, dirname
);
741 if (file_count
> 0) {
742 numargs
= lua_script_push_args(file_count
);
744 error
= lua_pcall(L
, numargs
, 0, 1);
748 report_failure("Lua: Error during loading:\n%s", lua_tostring(L
, -1));
751 report_failure("Lua: Error during loading: out of memory");
754 report_failure("Lua: Error during loading: error while retrieving error message");
757 report_failure("Lua: Error during loading: unknown error %d", error
);
764 report_failure("Lua: syntax error: %s", lua_tostring(L
, -1));
768 report_failure("Lua: memory allocation error during precompilation of %s", filename
);
772 report_failure("Lua: unknown error during precompilation of %s: %d", filename
, error
);
776 lua_pop(L
, 2); /* pop the filename and error handler */
780 /* This one is used to load the init.lua scripts, or anything else
781 * that shouldn't really be considered a real plugin.
783 static bool lua_load_internal_script(const char* filename
) {
784 return lua_load_script(filename
, NULL
, 0);
787 /* This one is used to load plugins from the plugin directories,
788 * or scripts from the command line. The latter have file_count > 0.
790 static bool lua_load_plugin_script(const char* name
,
791 const char* filename
,
793 const int file_count
)
795 ws_debug("Loading lua script: %s", filename
);
796 if (file_count
> 0 ? lua_load_script(filename
, dirname
, file_count
) :
797 lua_load_plugin(filename
)) {
798 wslua_add_plugin(name
, get_current_plugin_version(), filename
);
799 clear_current_plugin_version();
805 static int wslua_panic(lua_State
* LS
) {
806 ws_error("LUA PANIC: %s",lua_tostring(LS
,-1));
807 /** ws_error() does an abort() and thus never returns **/
808 return 0; /* keep gcc happy */
811 static int string_compare(const void *a
, const void *b
) {
812 return strcmp((const char*)a
, (const char*)b
);
815 static int lua_load_plugins(const char *dirname
, register_cb cb
, void *client_data
,
816 bool count_only
, const bool is_user
, GHashTable
*loaded_files
,
819 WS_DIR
*dir
; /* scanned directory */
820 WS_DIRENT
*file
; /* current file */
821 char *filename
, *dot
;
823 int plugins_counter
= 0;
824 GList
*sorted_dirnames
= NULL
;
825 GList
*sorted_filenames
= NULL
;
828 if ((dir
= ws_dir_open(dirname
, 0, NULL
)) != NULL
) {
829 while ((file
= ws_dir_read_name(dir
)) != NULL
) {
830 name
= ws_dir_get_name(file
);
832 if (strcmp(name
, ".") == 0 || strcmp(name
, "..") == 0) {
833 /* skip "." and ".." */
836 if (depth
== 0 && strcmp(name
, "init.lua") == 0) {
837 /* If we are in the root directory skip the special "init.lua"
838 * file that was already loaded before every other user script.
839 * (If we are below the root script directory we just treat it like any other
844 filename
= ws_strdup_printf("%s" G_DIR_SEPARATOR_S
"%s", dirname
, name
);
845 if (test_for_directory(filename
) == EISDIR
) {
846 sorted_dirnames
= g_list_prepend(sorted_dirnames
, (void *)filename
);
850 /* skip files starting with . */
851 if (name
[0] == '.') {
856 /* skip anything but files with .lua suffix */
857 dot
= strrchr(name
, '.');
858 if (dot
== NULL
|| g_ascii_strcasecmp(dot
+1, "lua") != 0) {
863 if (file_exists(filename
)) {
864 sorted_filenames
= g_list_prepend(sorted_filenames
, (void *)filename
);
873 /* Depth first; ie, process subdirectories (in ASCIIbetical order) before files */
874 if (sorted_dirnames
!= NULL
) {
875 sorted_dirnames
= g_list_sort(sorted_dirnames
, string_compare
);
876 for (l
= sorted_dirnames
; l
!= NULL
; l
= l
->next
) {
877 plugins_counter
+= lua_load_plugins((const char *)l
->data
, cb
, client_data
, count_only
, is_user
, loaded_files
, depth
+ 1);
879 g_list_free_full(sorted_dirnames
, g_free
);
882 /* Process files in ASCIIbetical order */
883 if (sorted_filenames
!= NULL
) {
884 /* If this is not the root of the plugin directory, add it to the path.
885 * XXX - Should we remove it after we're done with this directory? */
887 prepend_path(dirname
);
889 sorted_filenames
= g_list_sort(sorted_filenames
, string_compare
);
890 for (l
= sorted_filenames
; l
!= NULL
; l
= l
->next
) {
891 filename
= (char *)l
->data
;
892 name
= strrchr(filename
, G_DIR_SEPARATOR
) + 1;
894 /* Check if we have already loaded this file name, if provided with a set */
895 if (loaded_files
&& g_hash_table_lookup_extended(loaded_files
, name
, NULL
, NULL
)) {
901 (*cb
)(RA_LUA_PLUGINS
, name
, client_data
);
902 lua_load_plugin_script(name
, filename
, is_user
? dirname
: NULL
, 0);
905 g_hash_table_insert(loaded_files
, g_strdup(name
), NULL
);
910 g_list_free_full(sorted_filenames
, g_free
);
913 return plugins_counter
;
916 static int lua_load_global_plugins(register_cb cb
, void *client_data
,
919 return lua_load_plugins(get_plugins_dir(), cb
, client_data
, count_only
, false, NULL
, 0);
922 static int lua_load_pers_plugins(register_cb cb
, void *client_data
,
925 int plugins_counter
= 0;
927 /* aux table (set) to make sure we only load each file once (by name) */
928 /* XXX - This doesn't prevent users from loading a file a second time
929 * via a different method, e.g., require() or dofile().
931 * It shouldn't be needed now that we're calling require for the plugins.
933 GHashTable
*loaded_user_scripts
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, NULL
);
935 /* load user scripts */
936 plugins_counter
+= lua_load_plugins(get_plugins_pers_dir(), cb
, client_data
, count_only
, true, loaded_user_scripts
, 0);
938 /* for backward compatibility check old plugin directory */
939 char *old_path
= get_persconffile_path("plugins", false);
940 if (strcmp(get_plugins_pers_dir(), old_path
) != 0) {
941 plugins_counter
+= lua_load_plugins(old_path
, cb
, client_data
, count_only
, true, loaded_user_scripts
, 0);
945 g_hash_table_destroy(loaded_user_scripts
);
947 return plugins_counter
;
950 int wslua_count_plugins(void) {
953 /* count global scripts */
954 plugins_counter
= lua_load_global_plugins(NULL
, NULL
, true);
956 /* count user scripts */
957 plugins_counter
+= lua_load_pers_plugins(NULL
, NULL
, true);
959 /* count scripts from command line */
960 plugins_counter
+= ex_opt_count("lua_script");
962 return plugins_counter
;
965 void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback
, void *user_data
) {
966 wslua_plugin
*lua_plug
;
968 for (lua_plug
= wslua_plugin_list
; lua_plug
!= NULL
; lua_plug
= lua_plug
->next
)
970 callback(lua_plug
->name
, lua_plug
->version
, wslua_plugin_type_name(),
971 lua_plug
->filename
, user_data
);
976 print_wslua_plugin_description(const char *name
, const char *version
,
977 const char *description
, const char *filename
,
980 printf("%s\t%s\t%s\t%s\n", name
, version
, description
, filename
);
984 wslua_plugins_dump_all(void)
986 wslua_plugins_get_descriptions(print_wslua_plugin_description
, NULL
);
989 const char *wslua_plugin_type_name(void) {
993 static ei_register_info
* ws_lua_ei
;
994 static int ws_lua_ei_len
;
997 wslua_get_expert_field(const int group
, const int severity
)
1000 const ei_register_info
*ei
= ws_lua_ei
;
1004 for (i
=0; i
< ws_lua_ei_len
; i
++, ei
++) {
1005 if (ei
->eiinfo
.group
== group
&& ei
->eiinfo
.severity
== severity
)
1009 return &ei_lua_error
;
1013 wslua_allocf(void *ud _U_
, void *ptr
, size_t osize _U_
, size_t nsize
)
1015 /* g_realloc frees ptr if nsize==0 and returns NULL (as desired).
1016 * Furthermore it simplifies error handling by aborting on OOM */
1017 return g_realloc(ptr
, nsize
);
1020 #define WSLUA_EPAN_ENUMS_TABLE "_EPAN"
1021 #define WSLUA_WTAP_ENUMS_TABLE "_WTAP"
1023 #define WSLUA_BASE_TABLE "base"
1024 #define WSLUA_FTYPE_TABLE "ftypes"
1025 #define WSLUA_FRAMETYPE_TABLE "frametype"
1026 #define WSLUA_EXPERT_TABLE "expert"
1027 #define WSLUA_EXPERT_GROUP_TABLE "group"
1028 #define WSLUA_EXPERT_SEVERITY_TABLE "severity"
1029 #define WSLUA_WTAP_ENCAPS_TABLE "wtap_encaps"
1030 #define WSLUA_WTAP_TSPREC_TABLE "wtap_tsprecs"
1031 #define WSLUA_WTAP_COMMENTS_TABLE "wtap_comments"
1032 #define WSLUA_WTAP_RECTYPES_TABLE "wtap_rec_types"
1033 #define WSLUA_WTAP_PRESENCE_FLAGS_TABLE "wtap_presence_flags"
1036 add_table_symbol(const char *table
, const char *name
, int value
)
1038 /* Get table from the global environment. */
1039 lua_getglobal(L
, table
);
1040 /* Set symbol in table. */
1041 lua_pushstring(L
, name
);
1042 lua_pushinteger(L
, value
);
1043 lua_settable(L
, -3);
1044 /* Pop table from stack. */
1049 add_global_symbol(const char *name
, int value
)
1051 /* Set symbol in global environment. */
1052 lua_pushinteger(L
, value
);
1053 lua_setglobal(L
, name
);
1057 add_pi_severity_symbol(const char *name
, int value
)
1059 lua_getglobal(L
, WSLUA_EXPERT_TABLE
);
1060 lua_getfield(L
, -1, WSLUA_EXPERT_SEVERITY_TABLE
);
1061 lua_pushinteger(L
, value
);
1062 lua_setfield(L
, -2, name
);
1067 add_pi_group_symbol(const char *name
, int value
)
1069 lua_getglobal(L
, WSLUA_EXPERT_TABLE
);
1070 lua_getfield(L
, -1, WSLUA_EXPERT_GROUP_TABLE
);
1071 lua_pushinteger(L
, value
);
1072 lua_setfield(L
, -2, name
);
1077 add_menu_group_symbol(const char *name
, int value
)
1079 /* Set symbol in global environment. */
1080 lua_pushinteger(L
, value
);
1081 char *str
= g_strdup(name
);
1082 char *s
= strstr(str
, "_GROUP_");
1088 s
+= strlen("_GROUP_");
1089 char *str2
= ws_strdup_printf("MENU_%s_%s", str
, s
);
1090 lua_setglobal(L
, str2
);
1096 * Read introspection constants and add them according to the historical
1097 * (sometimes arbitrary) rules of make-init-lua.py. For efficiency reasons
1098 * we only loop the enums array once.
1101 wslua_add_introspection(void)
1103 const ws_enum_t
*ep
;
1105 /* Add empty tables to be populated. */
1107 lua_setglobal(L
, WSLUA_BASE_TABLE
);
1109 lua_setglobal(L
, WSLUA_FTYPE_TABLE
);
1111 lua_setglobal(L
, WSLUA_FRAMETYPE_TABLE
);
1113 lua_pushstring(L
, WSLUA_EXPERT_GROUP_TABLE
);
1115 lua_settable(L
, -3);
1116 lua_pushstring(L
, WSLUA_EXPERT_SEVERITY_TABLE
);
1118 lua_settable(L
, -3);
1119 lua_setglobal(L
, WSLUA_EXPERT_TABLE
);
1120 /* Add catch-all _EPAN table. */
1122 lua_setglobal(L
, WSLUA_EPAN_ENUMS_TABLE
);
1124 for (ep
= epan_inspect_enums(); ep
->symbol
!= NULL
; ep
++) {
1126 if (g_str_has_prefix(ep
->symbol
, "BASE_")) {
1127 add_table_symbol(WSLUA_BASE_TABLE
, ep
->symbol
+ strlen("BASE_"), ep
->value
);
1129 else if (g_str_has_prefix(ep
->symbol
, "SEP_")) {
1130 add_table_symbol(WSLUA_BASE_TABLE
, ep
->symbol
+ strlen("SEP_"), ep
->value
);
1132 else if (g_str_has_prefix(ep
->symbol
, "ABSOLUTE_TIME_")) {
1133 add_table_symbol(WSLUA_BASE_TABLE
, ep
->symbol
+ strlen("ABSOLUTE_TIME_"), ep
->value
);
1135 else if (g_str_has_prefix(ep
->symbol
, "ENC_")) {
1136 add_global_symbol(ep
->symbol
, ep
->value
);
1138 else if (g_str_has_prefix(ep
->symbol
, "FT_FRAMENUM_")) {
1139 add_table_symbol(WSLUA_FRAMETYPE_TABLE
, ep
->symbol
+ strlen("FT_FRAMENUM_"), ep
->value
);
1141 else if (g_str_has_prefix(ep
->symbol
, "FT_")) {
1142 add_table_symbol(WSLUA_FTYPE_TABLE
, ep
->symbol
+ strlen("FT_"), ep
->value
);
1144 else if (g_str_has_prefix(ep
->symbol
, "PI_")) {
1145 if (ep
->value
& PI_SEVERITY_MASK
) {
1146 add_pi_severity_symbol(ep
->symbol
+ strlen("PI_"), ep
->value
);
1149 add_pi_group_symbol(ep
->symbol
+ strlen("PI_"), ep
->value
);
1151 /* For backward compatibility. */
1152 add_global_symbol(ep
->symbol
, ep
->value
);
1154 else if (g_str_has_prefix(ep
->symbol
, "REGISTER_")) {
1155 add_menu_group_symbol(ep
->symbol
+ strlen("REGISTER_"), ep
->value
);
1157 add_table_symbol(WSLUA_EPAN_ENUMS_TABLE
, ep
->symbol
, ep
->value
);
1160 /* Add empty tables to be populated. */
1162 lua_setglobal(L
, WSLUA_WTAP_ENCAPS_TABLE
);
1164 lua_setglobal(L
, WSLUA_WTAP_TSPREC_TABLE
);
1166 lua_setglobal(L
, WSLUA_WTAP_COMMENTS_TABLE
);
1168 lua_setglobal(L
, WSLUA_WTAP_RECTYPES_TABLE
);
1170 lua_setglobal(L
, WSLUA_WTAP_PRESENCE_FLAGS_TABLE
);
1171 /* Add catch-all _WTAP table. */
1173 lua_setglobal(L
, WSLUA_WTAP_ENUMS_TABLE
);
1175 for (ep
= wtap_inspect_enums(); ep
->symbol
!= NULL
; ep
++) {
1177 if (g_str_has_prefix(ep
->symbol
, "WTAP_ENCAP_")) {
1178 add_table_symbol(WSLUA_WTAP_ENCAPS_TABLE
, ep
->symbol
+ strlen("WTAP_ENCAP_"), ep
->value
);
1180 else if (g_str_has_prefix(ep
->symbol
, "WTAP_TSPREC_")) {
1181 add_table_symbol(WSLUA_WTAP_TSPREC_TABLE
, ep
->symbol
+ strlen("WTAP_TSPREC_"), ep
->value
);
1183 else if (g_str_has_prefix(ep
->symbol
, "WTAP_COMMENT_")) {
1184 add_table_symbol(WSLUA_WTAP_COMMENTS_TABLE
, ep
->symbol
+ strlen("WTAP_COMMENT_"), ep
->value
);
1186 else if (g_str_has_prefix(ep
->symbol
, "REC_TYPE_")) {
1187 add_table_symbol(WSLUA_WTAP_RECTYPES_TABLE
, ep
->symbol
+ strlen("REC_TYPE_"), ep
->value
);
1189 else if (g_str_has_prefix(ep
->symbol
, "WTAP_HAS_")) {
1190 add_table_symbol(WSLUA_WTAP_PRESENCE_FLAGS_TABLE
, ep
->symbol
+ strlen("WTAP_HAS_"), ep
->value
);
1192 add_table_symbol(WSLUA_WTAP_ENUMS_TABLE
, ep
->symbol
, ep
->value
);
1196 static void wslua_add_deprecated(void)
1198 /* For backward compatibility. */
1199 lua_getglobal(L
, "wtap_encaps");
1200 lua_setglobal(L
, "wtap");
1203 * Generate the wtap_filetypes items for file types, for backwards
1205 * We no longer have WTAP_FILE_TYPE_SUBTYPE_ #defines;
1206 * built-in file types are registered the same way that
1207 * plugin file types are registered.
1209 * New code should use wtap_name_to_file_type_subtype to
1210 * look up file types by name.
1212 wslua_init_wtap_filetypes(L
);
1214 /* Old / deprecated menu groups. These shoudn't be used in new code. */
1215 lua_getglobal(L
, "MENU_PACKET_ANALYZE_UNSORTED");
1216 lua_setglobal(L
, "MENU_ANALYZE_UNSORTED");
1217 lua_getglobal(L
, "MENU_ANALYZE_CONVERSATION_FILTER");
1218 lua_setglobal(L
, "MENU_ANALYZE_CONVERSATION");
1219 lua_getglobal(L
, "MENU_STAT_CONVERSATION_LIST");
1220 lua_setglobal(L
, "MENU_STAT_CONVERSATION");
1221 lua_getglobal(L
, "MENU_STAT_ENDPOINT_LIST");
1222 lua_setglobal(L
, "MENU_STAT_ENDPOINT");
1223 lua_getglobal(L
, "MENU_STAT_RESPONSE_TIME");
1224 lua_setglobal(L
, "MENU_STAT_RESPONSE");
1225 lua_getglobal(L
, "MENU_PACKET_STAT_UNSORTED");
1226 lua_setglobal(L
, "MENU_STAT_UNSORTED");
1227 lua_getglobal(L
, "MENU_TELEPHONY_UNSORTED");
1228 lua_setglobal(L
, "MENU_STAT_TELEPHONY");
1229 lua_getglobal(L
, "MENU_TELEPHONY_ANSI");
1230 lua_setglobal(L
, "MENU_STAT_TELEPHONY_ANSI");
1231 lua_getglobal(L
, "MENU_TELEPHONY_GSM");
1232 lua_setglobal(L
, "MENU_STAT_TELEPHONY_GSM");
1233 lua_getglobal(L
, "MENU_TELEPHONY_3GPP_UU");
1234 lua_setglobal(L
, "MENU_STAT_TELEPHONY_3GPP_UU");
1235 lua_getglobal(L
, "MENU_TELEPHONY_MTP3");
1236 lua_setglobal(L
, "MENU_STAT_TELEPHONY_MTP3");
1237 lua_getglobal(L
, "MENU_TELEPHONY_SCTP");
1238 lua_setglobal(L
, "MENU_STAT_TELEPHONY_SCTP");
1240 /* deprecated function names */
1241 lua_getglobal(L
, "Dir");
1242 lua_getfield(L
, -1, "global_config_path");
1243 lua_setglobal(L
, "datafile_path");
1244 lua_getfield(L
, -1, "personal_config_path");
1245 lua_setglobal(L
, "persconffile_path");
1249 static int wslua_console_print(lua_State
*_L
);
1251 static const char *lua_error_msg(int code
)
1254 case LUA_ERRSYNTAX
: return "syntax error during precompilation";
1255 case LUA_ERRMEM
: return "memory allocation error";
1256 #if LUA_VERSION_NUM == 502
1257 case LUA_ERRGCMM
: return "error while running a __gc metamethod";
1259 case LUA_ERRRUN
: return "runtime error";
1260 case LUA_ERRERR
: return "error while running the message handler";
1261 default: break; /* Should not happen. */
1263 return "unknown error";
1266 static int lua_funnel_console_eval(const char *console_input
,
1269 void *callback_data _U_
)
1273 const int curr_top
= lua_gettop(L
);
1275 // If it starts with an equals sign replace it with "return"
1277 while (g_ascii_isspace(*console_input
))
1279 if (*console_input
== '=')
1280 codestr
= ws_strdup_printf("return %s", console_input
+1);
1282 codestr
= (char *)console_input
; /* Violate const safety to avoid a strdup() */
1284 ws_noisy("Console input: %s", codestr
);
1285 lcode
= luaL_loadstring(L
, codestr
);
1286 /* Free only if we called strdup(). */
1287 if (codestr
!= console_input
)
1291 if (lcode
!= LUA_OK
) {
1292 ws_debug("luaL_loadstring(): %s (%d)", lua_error_msg(lcode
), lcode
);
1294 *error_hint
= g_strdup(lua_error_msg(lcode
));
1296 /* If we have an error message return it. */
1297 if (error_ptr
&& !lua_isnil(L
, -1)) {
1298 *error_ptr
= g_strdup(lua_tostring(L
, -1));
1303 lcode
= lua_pcall(L
, 0, LUA_MULTRET
, 0);
1304 if (lcode
!= LUA_OK
) {
1305 ws_debug("lua_pcall(): %s (%d)", lua_error_msg(lcode
), lcode
);
1307 *error_hint
= g_strdup(lua_error_msg(lcode
));
1309 /* If we have an error message return it. */
1310 if (error_ptr
&& !lua_isnil(L
, -1)) {
1311 *error_ptr
= g_strdup(lua_tostring(L
, -1));
1316 // If we have values returned print them all
1317 if (lua_gettop(L
) > curr_top
) { /* any arguments? */
1318 lua_pushcfunction(L
, wslua_console_print
);
1319 lua_insert(L
, curr_top
+1);
1320 lcode
= lua_pcall(L
, lua_gettop(L
)-curr_top
-1, 0, 0);
1321 if (lcode
!= LUA_OK
) {
1322 /* Error printing result */
1324 *error_hint
= ws_strdup_printf("error printing return values: %s", lua_error_msg(lcode
));
1329 // For any new Protos, register their ProtoFields and ProtoExperts with epan
1330 lua_pushcfunction(L
, Proto_commit
);
1331 lcode
= lua_pcall(L
, 0, 0, 0);
1332 if (lcode
!= LUA_OK
) {
1333 /* Error initializing new ProtoFields */
1335 *error_hint
= ws_strdup_printf("error initialzing protocol fields: %s", lua_error_msg(lcode
));
1336 /* If we have an error message return it. */
1337 if (error_ptr
&& !lua_isnil(L
, -1)) {
1338 *error_ptr
= g_strdup(lua_tostring(L
, -1));
1343 // Maintain stack discipline
1344 if (lua_gettop(L
) != curr_top
) {
1345 ws_critical("Expected stack top == %d, have %d", curr_top
, lua_gettop(L
));
1348 ws_noisy("Success");
1352 /* Receives C print function pointer as first upvalue. */
1353 /* Receives C print function data pointer as second upvalue. */
1354 static int wslua_console_print(lua_State
*_L
)
1356 GString
*gstr
= g_string_new(NULL
);
1359 /* Print arguments. */
1360 for (int i
= 1; i
<= lua_gettop(_L
); i
++) {
1361 repr
= luaL_tolstring(_L
, i
, NULL
);
1363 g_string_append_c(gstr
, '\t');
1364 g_string_append(gstr
, repr
);
1367 g_string_append_c(gstr
, '\n');
1369 if (wslua_gui_print_func_ptr
== NULL
) {
1370 ws_critical("GUI print function not registered; Trying to print: %s", gstr
->str
);
1373 wslua_gui_print_func_ptr(gstr
->str
, wslua_gui_print_data_ptr
);
1375 g_string_free(gstr
, TRUE
);
1379 // Replace lua print function with a custom print function.
1380 // We will place the original function in the Lua registry and return the reference.
1381 static void lua_funnel_console_open(void (*print_func_ptr
)(const char *, void *),
1382 void *print_data_ptr
,
1383 void *callback_data _U_
)
1385 /* Store original print value in the registry (even if it is nil). */
1386 lua_getglobal(L
, "print");
1387 wslua_lua_print_func_ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
1389 /* Set new "print" function (to output to the GUI) */
1390 lua_pushcfunction(L
, wslua_console_print
);
1391 lua_setglobal(L
, "print");
1393 /* Save the globals */
1394 ws_assert(print_func_ptr
);
1395 wslua_gui_print_func_ptr
= print_func_ptr
;
1396 wslua_gui_print_data_ptr
= print_data_ptr
;
1399 // Restore original Lua print function. Clean state.
1400 static void lua_funnel_console_close(void *callback_data _U_
)
1402 /* Restore the original print function. */
1403 int ref
= (int)wslua_lua_print_func_ref
;
1404 /* push original function into stack */
1405 lua_rawgeti(L
, LUA_REGISTRYINDEX
, ref
);
1406 lua_setglobal(L
, "print");
1407 /* Release reference */
1408 luaL_unref(L
, LUA_REGISTRYINDEX
, ref
);
1410 /* Clear the globals. */
1411 wslua_gui_print_func_ptr
= NULL
;
1412 wslua_gui_print_data_ptr
= NULL
;
1413 wslua_lua_print_func_ref
= LUA_NOREF
;
1416 static int wslua_file_exists(lua_State
*_L
)
1418 const char *path
= luaL_checkstring(_L
, 1);
1419 lua_pushboolean(_L
, g_file_test(path
, G_FILE_TEST_EXISTS
));
1423 static int wslua_lua_typeof(lua_State
*_L
)
1425 const char *classname
= wslua_typeof(_L
, 1);
1426 lua_pushstring(_L
, classname
);
1430 /* Other useful constants */
1431 void wslua_add_useful_constants(void)
1433 const funnel_ops_t
*ops
= funnel_get_funnel_ops();
1436 WSLUA_REG_GLOBAL_BOOL(L
,"GUI_ENABLED",ops
&& ops
->new_dialog
);
1438 /* DATA_DIR has a trailing directory separator. */
1439 path
= get_datafile_path("");
1440 lua_pushfstring(L
, "%s"G_DIR_SEPARATOR_S
, path
);
1442 lua_setglobal(L
, "DATA_DIR");
1444 /* USER_DIR has a trailing directory separator. */
1445 path
= get_persconffile_path("", false);
1446 lua_pushfstring(L
, "%s"G_DIR_SEPARATOR_S
, path
);
1448 lua_setglobal(L
, "USER_DIR");
1450 lua_pushcfunction(L
, wslua_file_exists
);
1451 lua_setglobal(L
, "file_exists");
1453 lua_pushcfunction(L
, wslua_lua_typeof
);
1454 lua_setglobal(L
, "typeof");
1457 void wslua_init(register_cb cb
, void *client_data
) {
1459 bool enable_lua
= true;
1460 bool run_anyway
= false;
1461 expert_module_t
* expert_lua
;
1463 static bool first_time
= true;
1467 static hf_register_info hf
[] = {
1469 { "Wireshark Lua fake item", "_ws.lua.fake",
1470 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1471 "Fake internal item for Wireshark Lua", HFILL
}},
1473 { "Wireshark Lua text", "_ws.lua.text",
1474 FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1476 static int *ett
[] = {
1477 &ett_wslua_traceback
,
1480 static ei_register_info ei
[] = {
1481 /* the following are created so we can continue to support the TreeItem_add_expert_info()
1482 function to Lua scripts. That function doesn't know what registered protocol to use,
1483 so it uses the "_ws.lua" one. */
1484 /* XXX: it seems to me we should not be offering PI_GROUP_MASK nor PI_SEVERITY_MASK since
1485 they are not real settings, so I'm not adding them below (should they also not be exported
1486 into Lua? they are right now.) */
1487 /* NOTE: do not add expert entries at the top of this array - only at the bottom. This array
1488 is not only used by expert.c, but also by wslua_get_expert_field() to find the appropriate
1489 "dummy" entry. So this array's ordering matters. */
1490 { &ei_lua_proto_checksum_comment
, { "_ws.lua.proto.comment", PI_CHECKSUM
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1491 { &ei_lua_proto_checksum_chat
, { "_ws.lua.proto.chat", PI_CHECKSUM
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1492 { &ei_lua_proto_checksum_note
, { "_ws.lua.proto.note", PI_CHECKSUM
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1493 { &ei_lua_proto_checksum_warn
, { "_ws.lua.proto.warning", PI_CHECKSUM
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1494 { &ei_lua_proto_checksum_error
, { "_ws.lua.proto.error", PI_CHECKSUM
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1496 { &ei_lua_proto_sequence_comment
, { "_ws.lua.proto.comment", PI_SEQUENCE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1497 { &ei_lua_proto_sequence_chat
, { "_ws.lua.proto.chat", PI_SEQUENCE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1498 { &ei_lua_proto_sequence_note
, { "_ws.lua.proto.note", PI_SEQUENCE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1499 { &ei_lua_proto_sequence_warn
, { "_ws.lua.proto.warning", PI_SEQUENCE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1500 { &ei_lua_proto_sequence_error
, { "_ws.lua.proto.error", PI_SEQUENCE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1502 { &ei_lua_proto_response_comment
, { "_ws.lua.proto.comment", PI_RESPONSE_CODE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1503 { &ei_lua_proto_response_chat
, { "_ws.lua.proto.chat", PI_RESPONSE_CODE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1504 { &ei_lua_proto_response_note
, { "_ws.lua.proto.note", PI_RESPONSE_CODE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1505 { &ei_lua_proto_response_warn
, { "_ws.lua.proto.warning", PI_RESPONSE_CODE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1506 { &ei_lua_proto_response_error
, { "_ws.lua.proto.error", PI_RESPONSE_CODE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1508 { &ei_lua_proto_request_comment
, { "_ws.lua.proto.comment", PI_REQUEST_CODE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1509 { &ei_lua_proto_request_chat
, { "_ws.lua.proto.chat", PI_REQUEST_CODE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1510 { &ei_lua_proto_request_note
, { "_ws.lua.proto.note", PI_REQUEST_CODE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1511 { &ei_lua_proto_request_warn
, { "_ws.lua.proto.warning", PI_REQUEST_CODE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1512 { &ei_lua_proto_request_error
, { "_ws.lua.proto.error", PI_REQUEST_CODE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1514 { &ei_lua_proto_undecoded_comment
, { "_ws.lua.proto.comment", PI_UNDECODED
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1515 { &ei_lua_proto_undecoded_chat
, { "_ws.lua.proto.chat", PI_UNDECODED
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1516 { &ei_lua_proto_undecoded_note
, { "_ws.lua.proto.note", PI_UNDECODED
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1517 { &ei_lua_proto_undecoded_warn
, { "_ws.lua.proto.warning", PI_UNDECODED
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1518 { &ei_lua_proto_undecoded_error
, { "_ws.lua.proto.error", PI_UNDECODED
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1520 { &ei_lua_proto_reassemble_comment
, { "_ws.lua.proto.comment", PI_REASSEMBLE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1521 { &ei_lua_proto_reassemble_chat
, { "_ws.lua.proto.chat", PI_REASSEMBLE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1522 { &ei_lua_proto_reassemble_note
, { "_ws.lua.proto.note", PI_REASSEMBLE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1523 { &ei_lua_proto_reassemble_warn
, { "_ws.lua.proto.warning", PI_REASSEMBLE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1524 { &ei_lua_proto_reassemble_error
, { "_ws.lua.proto.error", PI_REASSEMBLE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1526 { &ei_lua_proto_malformed_comment
, { "_ws.lua.proto.comment", PI_MALFORMED
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1527 { &ei_lua_proto_malformed_chat
, { "_ws.lua.proto.chat", PI_MALFORMED
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1528 { &ei_lua_proto_malformed_note
, { "_ws.lua.proto.note", PI_MALFORMED
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1529 { &ei_lua_proto_malformed_warn
, { "_ws.lua.proto.warning", PI_MALFORMED
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1530 { &ei_lua_proto_malformed_error
, { "_ws.lua.proto.error", PI_MALFORMED
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1532 { &ei_lua_proto_debug_comment
, { "_ws.lua.proto.comment", PI_DEBUG
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1533 { &ei_lua_proto_debug_chat
, { "_ws.lua.proto.chat", PI_DEBUG
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1534 { &ei_lua_proto_debug_note
, { "_ws.lua.proto.note", PI_DEBUG
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1535 { &ei_lua_proto_debug_warn
, { "_ws.lua.proto.warning", PI_DEBUG
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1536 { &ei_lua_proto_debug_error
, { "_ws.lua.proto.error", PI_DEBUG
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1538 { &ei_lua_proto_protocol_comment
, { "_ws.lua.proto.comment", PI_PROTOCOL
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1539 { &ei_lua_proto_protocol_chat
, { "_ws.lua.proto.chat", PI_PROTOCOL
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1540 { &ei_lua_proto_protocol_note
, { "_ws.lua.proto.note", PI_PROTOCOL
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1541 { &ei_lua_proto_protocol_warn
, { "_ws.lua.proto.warning", PI_PROTOCOL
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1542 { &ei_lua_proto_protocol_error
, { "_ws.lua.proto.error", PI_PROTOCOL
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1544 { &ei_lua_proto_security_comment
, { "_ws.lua.proto.comment", PI_SECURITY
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1545 { &ei_lua_proto_security_chat
, { "_ws.lua.proto.chat", PI_SECURITY
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1546 { &ei_lua_proto_security_note
, { "_ws.lua.proto.note", PI_SECURITY
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1547 { &ei_lua_proto_security_warn
, { "_ws.lua.proto.warning", PI_SECURITY
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1548 { &ei_lua_proto_security_error
, { "_ws.lua.proto.error", PI_SECURITY
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1550 { &ei_lua_proto_comments_comment
, { "_ws.lua.proto.comment", PI_COMMENTS_GROUP
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1551 { &ei_lua_proto_comments_chat
, { "_ws.lua.proto.chat", PI_COMMENTS_GROUP
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1552 { &ei_lua_proto_comments_note
, { "_ws.lua.proto.note", PI_COMMENTS_GROUP
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1553 { &ei_lua_proto_comments_warn
, { "_ws.lua.proto.warning", PI_COMMENTS_GROUP
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1554 { &ei_lua_proto_comments_error
, { "_ws.lua.proto.error", PI_COMMENTS_GROUP
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1556 { &ei_lua_proto_decryption_comment
, { "_ws.lua.proto.comment", PI_DECRYPTION
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1557 { &ei_lua_proto_decryption_chat
, { "_ws.lua.proto.chat", PI_DECRYPTION
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1558 { &ei_lua_proto_decryption_note
, { "_ws.lua.proto.note", PI_DECRYPTION
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1559 { &ei_lua_proto_decryption_warn
, { "_ws.lua.proto.warning", PI_DECRYPTION
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1560 { &ei_lua_proto_decryption_error
, { "_ws.lua.proto.error", PI_DECRYPTION
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1562 { &ei_lua_proto_assumption_comment
, { "_ws.lua.proto.comment", PI_ASSUMPTION
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1563 { &ei_lua_proto_assumption_chat
, { "_ws.lua.proto.chat", PI_ASSUMPTION
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1564 { &ei_lua_proto_assumption_note
, { "_ws.lua.proto.note", PI_ASSUMPTION
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1565 { &ei_lua_proto_assumption_warn
, { "_ws.lua.proto.warning", PI_ASSUMPTION
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1566 { &ei_lua_proto_assumption_error
, { "_ws.lua.proto.error", PI_ASSUMPTION
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1568 { &ei_lua_proto_deprecated_comment
, { "_ws.lua.proto.comment", PI_DEPRECATED
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1569 { &ei_lua_proto_deprecated_chat
, { "_ws.lua.proto.chat", PI_DEPRECATED
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1570 { &ei_lua_proto_deprecated_note
, { "_ws.lua.proto.note", PI_DEPRECATED
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1571 { &ei_lua_proto_deprecated_warn
, { "_ws.lua.proto.warning", PI_DEPRECATED
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1572 { &ei_lua_proto_deprecated_error
, { "_ws.lua.proto.error", PI_DEPRECATED
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1574 { &ei_lua_proto_receive_comment
, { "_ws.lua.proto.comment", PI_RECEIVE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1575 { &ei_lua_proto_receive_chat
, { "_ws.lua.proto.chat", PI_RECEIVE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1576 { &ei_lua_proto_receive_note
, { "_ws.lua.proto.note", PI_RECEIVE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1577 { &ei_lua_proto_receive_warn
, { "_ws.lua.proto.warning", PI_RECEIVE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1578 { &ei_lua_proto_receive_error
, { "_ws.lua.proto.error", PI_RECEIVE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1580 { &ei_lua_proto_interface_comment
, { "_ws.lua.proto.comment", PI_INTERFACE
, PI_COMMENT
,"Protocol Comment", EXPFILL
}},
1581 { &ei_lua_proto_interface_chat
, { "_ws.lua.proto.chat", PI_INTERFACE
, PI_CHAT
,"Protocol Chat", EXPFILL
}},
1582 { &ei_lua_proto_interface_note
, { "_ws.lua.proto.note", PI_INTERFACE
, PI_NOTE
,"Protocol Note", EXPFILL
}},
1583 { &ei_lua_proto_interface_warn
, { "_ws.lua.proto.warning", PI_INTERFACE
, PI_WARN
,"Protocol Warning", EXPFILL
}},
1584 { &ei_lua_proto_interface_error
, { "_ws.lua.proto.error", PI_INTERFACE
, PI_ERROR
,"Protocol Error", EXPFILL
}},
1586 /* this one is for reporting errors executing Lua code */
1587 { &ei_lua_error
, { "_ws.lua.error", PI_DISSECTOR_BUG
, PI_ERROR
,"Lua Error", EXPFILL
}},
1592 ws_lua_ei_len
= array_length(ei
);
1596 L
= lua_newstate(wslua_allocf
, NULL
);
1602 proto_lua
= proto_register_protocol("Lua Dissection", "Lua Dissection", "_ws.lua");
1603 proto_register_field_array(proto_lua
, hf
, array_length(hf
));
1604 proto_register_subtree_array(ett
, array_length(ett
));
1605 expert_lua
= expert_register_protocol(proto_lua
);
1606 expert_register_field_array(expert_lua
, ei
, array_length(ei
));
1609 lua_atpanic(L
,wslua_panic
);
1612 * The init_routines table (accessible by the user).
1614 * For a table a, a.init is syntactic sugar for a["init"], and
1616 * function t.a.b.c.f () body end
1618 * is syntactic sugar for
1620 * t.a.b.c.f = function () body end
1624 * function proto.init () body end
1628 * proto["init"] = function () body end
1630 * and the Proto class has an "init" method, with Proto_set_init()
1631 * being the setter for that method; that routine adds the Lua
1632 * function passed to it as a Lua argument to the WSLUA_INIT_ROUTINES
1633 * table - i.e., "init_routines".
1636 lua_setglobal(L
, WSLUA_INIT_ROUTINES
);
1638 /* the dissectors table goes in the registry (not accessible) */
1640 lua_dissectors_table_ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
1642 lua_heur_dissectors_table_ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
1644 /* the preferences apply_cb table (accessible by the user) */
1646 lua_setglobal(L
, WSLUA_PREFS_CHANGED
);
1648 /* set running_superuser variable to its proper value */
1649 WSLUA_REG_GLOBAL_BOOL(L
,"running_superuser",started_with_special_privs());
1651 /* special constant used by PDU reassembly handling */
1652 /* see dissect_lua() for notes */
1653 WSLUA_REG_GLOBAL_INTEGER(L
,"DESEGMENT_ONE_MORE_SEGMENT",DESEGMENT_ONE_MORE_SEGMENT
);
1655 /* the possible values for Pinfo's p2p_dir attribute */
1656 WSLUA_REG_GLOBAL_INTEGER(L
,"P2P_DIR_UNKNOWN",-1);
1657 WSLUA_REG_GLOBAL_INTEGER(L
,"P2P_DIR_SENT",0);
1658 WSLUA_REG_GLOBAL_INTEGER(L
,"P2P_DIR_RECV",1);
1660 wslua_add_introspection();
1662 wslua_add_useful_constants();
1664 wslua_add_deprecated();
1666 // Register Lua's console menu (in the GUI)
1668 funnel_register_console_menu("Lua",
1669 lua_funnel_console_eval
,
1670 lua_funnel_console_open
,
1671 lua_funnel_console_close
,
1674 else if (wslua_gui_print_func_ptr
) {
1675 // If we we have an open GUI console dialog re-register the global "print to console" function
1676 lua_funnel_console_open(wslua_gui_print_func_ptr
, wslua_gui_print_data_ptr
, NULL
);
1679 /* load system's init.lua */
1681 /* wslua_dofile / wslua_get_actual_filename look in the datafile dir.
1682 * Should we add that to the path for require() as well, for consistency?
1684 prepend_path(get_datafile_dir());
1686 /* Add the global plugins path for require */
1687 prepend_path(get_plugins_dir());
1688 filename
= g_build_filename(get_plugins_dir(), "init.lua", (char *)NULL
);
1689 if (file_exists(filename
)) {
1690 ws_debug("Loading init.lua file: %s", filename
);
1691 lua_load_internal_script(filename
);
1695 /* load user's init.lua */
1696 /* if we are indeed superuser run user scripts only if told to do so */
1697 if (!started_with_special_privs() || run_anyway
) {
1699 /* wslua_dofile / wslua_get_actual_filename look in the personal configuration
1700 * directory. Should we add that to the path for require() as well, for consistency?
1702 profile_dir
= get_profile_dir(NULL
, false);
1703 prepend_path(profile_dir
);
1704 g_free(profile_dir
);
1706 /* Add the personal plugins path(s) for require() */
1707 char *old_path
= get_persconffile_path("plugins", false);
1708 if (strcmp(get_plugins_pers_dir(), old_path
) != 0) {
1709 prepend_path(old_path
);
1712 prepend_path(get_plugins_pers_dir());
1713 filename
= g_build_filename(get_plugins_pers_dir(), "init.lua", (char *)NULL
);
1714 if (file_exists(filename
)) {
1715 ws_debug("Loading init.lua file: %s", filename
);
1716 lua_load_internal_script(filename
);
1720 /* For backward compatibility also load it from the configuration directory. */
1721 filename
= get_persconffile_path("init.lua", false);
1722 if (file_exists(filename
)) {
1723 ws_message("Loading init.lua file from deprecated path: %s", filename
);
1724 lua_load_internal_script(filename
);
1731 /* check if lua is to be disabled */
1732 lua_getglobal(L
, "disable_lua"); // 2.6 and earlier, deprecated
1733 if (lua_isboolean(L
,-1)) {
1734 enable_lua
= ! lua_toboolean(L
,-1);
1736 lua_pop(L
,1); /* pop the getglobal result */
1738 lua_getglobal(L
, "enable_lua"); // 3.0 and later
1739 if (lua_isboolean(L
,-1)) {
1740 enable_lua
= lua_toboolean(L
,-1);
1742 lua_pop(L
,1); /* pop the getglobal result */
1752 /* load global scripts */
1753 lua_load_global_plugins(cb
, client_data
, false);
1755 /* check whether we should run other scripts even if running superuser */
1756 lua_getglobal(L
,"run_user_scripts_when_superuser");
1758 if (lua_isboolean(L
,-1) && lua_toboolean(L
,-1)) {
1761 lua_pop(L
,1); /* pop the getglobal result */
1763 /* if we are indeed superuser run user scripts only if told to do so */
1764 if (!started_with_special_privs() || run_anyway
) {
1766 /* load user scripts */
1767 lua_load_pers_plugins(cb
, client_data
, false);
1769 /* load scripts from command line */
1770 for (i
= 0; i
< ex_opt_count("lua_script"); i
++) {
1771 const char *script_filename
= ex_opt_get_nth("lua_script", i
);
1772 char* dirname
= g_strdup(script_filename
);
1773 char* dname
= get_dirname(dirname
);
1774 /* Add the command line script directory to the path (unless it's
1775 * the current directory, which should already be in the path by
1777 * XXX - Should we remove it after we're done with this script? */
1779 prepend_path(dname
);
1782 (*cb
)(RA_LUA_PLUGINS
, get_basename(script_filename
), client_data
);
1784 lua_load_plugin_script(ws_dir_get_name(script_filename
),
1794 /* at this point we're set up so register the init and cleanup routines */
1795 register_init_routine(wslua_init_routine
);
1796 register_cleanup_routine(wslua_cleanup_routine
);
1800 * after this point it is too late to register a menu
1801 * disable the function to avoid weirdness
1803 lua_pushcfunction(L
, wslua_not_register_menu
);
1804 lua_setglobal(L
, "register_menu");
1806 /* set up some essential globals */
1811 /* Unfortunately, by waiting to register the hfi and ei now, Lua
1812 * can't figure out which file had the error and provide a traceback,
1813 * so no special error handler.
1815 lua_pushcfunction(L
, Proto_commit
);
1816 error
= lua_pcall(L
, 0, 0, 0);
1820 report_failure("Lua: Error initializing protocols:\n%s", lua_tostring(L
, -1));
1823 report_failure("Lua: Error initializing protocols: out of memory");
1826 report_failure("Lua: Error initializing protocols: error while retrieving error message");
1829 report_failure("Lua: Error initializing protocols: unknown error %d", error
);
1837 void wslua_early_cleanup(void) {
1838 wslua_deregister_protocols(L
);
1841 void wslua_reload_plugins (register_cb cb
, void *client_data
) {
1842 const funnel_ops_t
* ops
= funnel_get_funnel_ops();
1845 (*cb
)(RA_LUA_DEREGISTER
, NULL
, client_data
);
1847 if (ops
->close_dialogs
)
1848 ops
->close_dialogs();
1850 wslua_deregister_heur_dissectors(L
);
1851 wslua_deregister_protocols(L
);
1852 wslua_deregister_dissector_tables(L
);
1853 wslua_deregister_listeners(L
);
1854 wslua_deregister_fields(L
);
1855 wslua_deregister_filehandlers(L
);
1856 wslua_deregister_menus();
1857 wslua_clear_plugin_list();
1860 wslua_init(cb
, client_data
); /* reinitialize */
1863 void wslua_cleanup(void) {
1869 init_routine_initialized
= false;
1872 lua_State
* wslua_state(void) { return L
; }
1875 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1880 * indent-tabs-mode: nil
1883 * vi: set shiftwidth=4 tabstop=8 expandtab:
1884 * :indentSize=4:tabSize=8:noTabs=true: