2006-09-25 01:09:00 +00:00
|
|
|
/*
|
2009-05-10 15:56:57 +00:00
|
|
|
* init_wslua.c
|
2006-09-25 01:09:00 +00:00
|
|
|
*
|
|
|
|
* Wireshark's interface to the Lua Programming Language
|
|
|
|
*
|
2008-08-05 21:03:46 +00:00
|
|
|
* (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
|
2006-09-25 01:09:00 +00:00
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-07 11:26:45 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2006-09-25 01:09:00 +00:00
|
|
|
*/
|
|
|
|
|
2011-04-21 13:13:39 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
#include "wslua.h"
|
2013-08-13 10:38:30 +00:00
|
|
|
#include "init_wslua.h"
|
2009-05-10 15:56:57 +00:00
|
|
|
#include <epan/dissectors/packet-frame.h>
|
2006-09-25 01:09:00 +00:00
|
|
|
#include <math.h>
|
2021-02-27 03:38:15 +00:00
|
|
|
#include <stdio.h>
|
2006-09-25 01:09:00 +00:00
|
|
|
#include <epan/expert.h>
|
|
|
|
#include <epan/ex-opt.h>
|
2008-06-30 17:16:29 +00:00
|
|
|
#include <wsutil/privileges.h>
|
2008-05-22 15:46:27 +00:00
|
|
|
#include <wsutil/file_util.h>
|
2021-06-16 13:11:08 +00:00
|
|
|
#include <wsutil/wslog.h>
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2013-12-02 08:30:29 +00:00
|
|
|
/* linked list of Lua plugins */
|
|
|
|
typedef struct _wslua_plugin {
|
|
|
|
gchar *name; /**< plugin name */
|
|
|
|
gchar *version; /**< plugin version */
|
|
|
|
gchar *filename; /**< plugin filename */
|
|
|
|
struct _wslua_plugin *next;
|
|
|
|
} wslua_plugin;
|
|
|
|
|
|
|
|
static wslua_plugin *wslua_plugin_list = NULL;
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
static lua_State* L = NULL;
|
|
|
|
|
2014-03-10 05:54:51 +00:00
|
|
|
/* XXX: global variables? Really?? Yuck. These could be done differently,
|
|
|
|
using the Lua registry */
|
2006-09-25 01:09:00 +00:00
|
|
|
packet_info* lua_pinfo;
|
|
|
|
struct _wslua_treeitem* lua_tree;
|
|
|
|
tvbuff_t* lua_tvb;
|
2017-12-19 08:40:08 +00:00
|
|
|
wslua_logger_t wslua_logger;
|
2014-03-10 05:54:51 +00:00
|
|
|
int lua_dissectors_table_ref = LUA_NOREF;
|
|
|
|
int lua_heur_dissectors_table_ref = LUA_NOREF;
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2013-10-09 12:56:19 +00:00
|
|
|
static int proto_lua = -1;
|
2015-01-04 00:27:59 +00:00
|
|
|
|
|
|
|
static int hf_wslua_fake = -1;
|
|
|
|
static int hf_wslua_text = -1;
|
|
|
|
|
2013-10-09 12:56:19 +00:00
|
|
|
static expert_field ei_lua_error = EI_INIT;
|
|
|
|
|
2014-03-25 22:11:05 +00:00
|
|
|
static expert_field ei_lua_proto_checksum_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_checksum_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_checksum_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_checksum_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_checksum_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_sequence_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_sequence_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_sequence_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_sequence_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_sequence_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_response_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_response_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_response_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_response_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_response_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_request_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_request_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_request_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_request_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_request_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_undecoded_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_undecoded_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_undecoded_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_undecoded_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_undecoded_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_reassemble_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_reassemble_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_reassemble_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_reassemble_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_reassemble_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_malformed_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_malformed_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_malformed_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_malformed_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_malformed_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_debug_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_debug_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_debug_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_debug_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_debug_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_protocol_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_protocol_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_protocol_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_protocol_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_protocol_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_security_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_security_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_security_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_security_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_security_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_comments_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_comments_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_comments_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_comments_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_comments_error = EI_INIT;
|
|
|
|
|
2021-06-02 04:17:39 +00:00
|
|
|
static expert_field ei_lua_proto_decryption_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_decryption_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_decryption_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_decryption_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_decryption_error = EI_INIT;
|
|
|
|
|
|
|
|
static expert_field ei_lua_proto_assumption_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_assumption_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_assumption_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_assumption_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_assumption_error = EI_INIT;
|
|
|
|
|
2016-07-29 14:00:56 +00:00
|
|
|
static expert_field ei_lua_proto_deprecated_comment = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_deprecated_chat = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_deprecated_note = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_deprecated_warn = EI_INIT;
|
|
|
|
static expert_field ei_lua_proto_deprecated_error = EI_INIT;
|
|
|
|
|
2015-01-24 20:58:30 +00:00
|
|
|
static gboolean
|
|
|
|
lua_pinfo_end(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
|
|
|
|
void *user_data _U_)
|
2009-05-10 15:56:57 +00:00
|
|
|
{
|
|
|
|
clear_outstanding_Tvb();
|
2011-11-06 17:39:13 +00:00
|
|
|
clear_outstanding_TvbRange();
|
2009-05-10 15:56:57 +00:00
|
|
|
clear_outstanding_Pinfo();
|
|
|
|
clear_outstanding_Column();
|
|
|
|
clear_outstanding_Columns();
|
2011-10-18 17:46:00 +00:00
|
|
|
clear_outstanding_PrivateTable();
|
2009-05-10 15:56:57 +00:00
|
|
|
clear_outstanding_TreeItem();
|
2014-01-07 14:46:17 +00:00
|
|
|
clear_outstanding_FieldInfo();
|
2015-01-25 19:30:13 +00:00
|
|
|
clear_outstanding_FuncSavers();
|
2015-01-24 20:58:30 +00:00
|
|
|
|
|
|
|
/* keep invoking this callback later? */
|
|
|
|
return FALSE;
|
2009-05-10 15:56:57 +00:00
|
|
|
}
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2010-10-21 12:41:15 +00:00
|
|
|
static int wslua_not_register_menu(lua_State* LS) {
|
2006-09-25 01:09:00 +00:00
|
|
|
luaL_error(LS,"too late to register a menu");
|
2007-10-16 15:58:25 +00:00
|
|
|
return 0;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2015-01-04 00:27:59 +00:00
|
|
|
/* a getter for wslua_tree.c's TreeItem_add_item_any() to use */
|
|
|
|
int get_hf_wslua_text(void) {
|
|
|
|
return hf_wslua_text;
|
|
|
|
}
|
|
|
|
|
2012-09-10 21:40:21 +00:00
|
|
|
int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
|
2015-01-02 02:34:16 +00:00
|
|
|
int consumed_bytes = tvb_captured_length(tvb);
|
2016-10-06 14:26:27 +00:00
|
|
|
tvbuff_t *saved_lua_tvb = lua_tvb;
|
|
|
|
packet_info *saved_lua_pinfo = lua_pinfo;
|
|
|
|
struct _wslua_treeitem *saved_lua_tree = lua_tree;
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_pinfo = pinfo;
|
|
|
|
lua_tvb = tvb;
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/*
|
|
|
|
* almost equivalent to Lua:
|
|
|
|
* dissectors[current_proto](tvb,pinfo,tree)
|
|
|
|
*/
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_settop(L,0);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
|
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_pushstring(L, pinfo->current_proto);
|
2007-10-16 15:58:25 +00:00
|
|
|
lua_gettable(L, -2);
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_remove(L,1);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
if (lua_isfunction(L,1)) {
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
push_Tvb(L,tvb);
|
|
|
|
push_Pinfo(L,pinfo);
|
2015-07-08 19:20:50 +00:00
|
|
|
lua_tree = push_TreeItem(L, tree, proto_tree_add_item(tree, hf_wslua_fake, tvb, 0, 0, ENC_NA));
|
2019-04-03 21:32:30 +00:00
|
|
|
proto_item_set_hidden(lua_tree->item);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2008-01-07 21:24:23 +00:00
|
|
|
if ( lua_pcall(L,3,1,0) ) {
|
2013-10-09 12:56:19 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0, "Lua Error: %s", lua_tostring(L,-1));
|
2008-01-07 21:24:23 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
/* if the Lua dissector reported the consumed bytes, pass it to our caller */
|
2010-10-21 02:50:27 +00:00
|
|
|
if (lua_isnumber(L, -1)) {
|
2008-12-15 15:46:53 +00:00
|
|
|
/* we got the consumed bytes or the missing bytes as a negative number */
|
2014-02-27 04:42:15 +00:00
|
|
|
consumed_bytes = wslua_togint(L, -1);
|
2008-11-20 12:54:34 +00:00
|
|
|
lua_pop(L, 1);
|
2008-04-25 19:04:52 +00:00
|
|
|
}
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2008-04-25 19:04:52 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
} else {
|
2013-10-09 12:56:19 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"Lua Error: did not find the %s dissector in the dissectors table", pinfo->current_proto);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2015-01-24 20:58:30 +00:00
|
|
|
wmem_register_callback(pinfo->pool, lua_pinfo_end, NULL);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2016-10-06 14:26:27 +00:00
|
|
|
lua_pinfo = saved_lua_pinfo;
|
|
|
|
lua_tree = saved_lua_tree;
|
|
|
|
lua_tvb = saved_lua_tvb;
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2008-01-07 21:24:23 +00:00
|
|
|
return consumed_bytes;
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2014-03-10 05:54:51 +00:00
|
|
|
/** Type of a heuristic dissector, used in heur_dissector_add().
|
|
|
|
*
|
|
|
|
* @param tvb the tvbuff with the (remaining) packet data
|
|
|
|
* @param pinfo the packet info of this packet (additional info)
|
|
|
|
* @param tree the protocol tree to be build or NULL
|
|
|
|
* @return TRUE if the packet was recognized by the sub-dissector (stop dissection here)
|
|
|
|
*/
|
|
|
|
gboolean heur_dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
|
|
|
|
gboolean result = FALSE;
|
2016-10-06 14:26:27 +00:00
|
|
|
tvbuff_t *saved_lua_tvb = lua_tvb;
|
|
|
|
packet_info *saved_lua_pinfo = lua_pinfo;
|
|
|
|
struct _wslua_treeitem *saved_lua_tree = lua_tree;
|
2014-03-10 05:54:51 +00:00
|
|
|
lua_tvb = tvb;
|
|
|
|
lua_pinfo = pinfo;
|
|
|
|
|
2021-03-20 01:58:26 +00:00
|
|
|
ws_assert(tvb && pinfo);
|
2014-12-24 20:04:01 +00:00
|
|
|
|
|
|
|
if (!pinfo->heur_list_name || !pinfo->current_proto) {
|
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"internal error in heur_dissect_lua: NULL list name or current proto");
|
2014-03-10 05:54:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* heuristic functions are stored in a table in the registry; the registry has a
|
|
|
|
* table at reference lua_heur_dissectors_table_ref, and that table has keys for
|
|
|
|
* the heuristic listname (e.g., "udp", "tcp", etc.), and that key's value is a
|
|
|
|
* table of keys of the Proto->name, and their value is the function.
|
|
|
|
* So it's like registry[table_ref][heur_list_name][proto_name] = func
|
|
|
|
*/
|
|
|
|
|
|
|
|
lua_settop(L,0);
|
|
|
|
|
|
|
|
/* get the table of all lua heuristic dissector lists */
|
|
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_heur_dissectors_table_ref);
|
|
|
|
|
|
|
|
/* get the table inside that, for the lua heuristic dissectors of the requested heur list */
|
|
|
|
if (!wslua_get_table(L, -1, pinfo->heur_list_name)) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
lua_settop(L,0);
|
2014-12-24 20:04:01 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"internal error in heur_dissect_lua: no %s heur list table", pinfo->heur_list_name);
|
2014-03-10 05:54:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the table inside that, for the specific lua heuristic dissector */
|
|
|
|
if (!wslua_get_field(L,-1,pinfo->current_proto)) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
lua_settop(L,0);
|
2014-12-24 20:04:01 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"internal error in heur_dissect_lua: no %s heuristic dissector for list %s",
|
2014-03-10 05:54:51 +00:00
|
|
|
pinfo->current_proto, pinfo->heur_list_name);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove the table of all lists (the one in the registry) */
|
|
|
|
lua_remove(L,1);
|
|
|
|
/* remove the heur_list_name heur list table */
|
|
|
|
lua_remove(L,1);
|
|
|
|
|
|
|
|
if (!lua_isfunction(L,-1)) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
lua_settop(L,0);
|
2014-12-24 20:04:01 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"internal error in heur_dissect_lua: %s heuristic dissector is not a function", pinfo->current_proto);
|
2014-03-10 05:54:51 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
push_Tvb(L,tvb);
|
|
|
|
push_Pinfo(L,pinfo);
|
2015-07-08 19:20:50 +00:00
|
|
|
lua_tree = push_TreeItem(L, tree, proto_tree_add_item(tree, hf_wslua_fake, tvb, 0, 0, ENC_NA));
|
2019-04-03 21:32:30 +00:00
|
|
|
proto_item_set_hidden(lua_tree->item);
|
2014-03-10 05:54:51 +00:00
|
|
|
|
|
|
|
if ( lua_pcall(L,3,1,0) ) {
|
2014-12-24 20:04:01 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"Lua Error: error calling %s heuristic dissector: %s", pinfo->current_proto, lua_tostring(L,-1));
|
2014-03-10 05:54:51 +00:00
|
|
|
lua_settop(L,0);
|
|
|
|
} else {
|
|
|
|
if (lua_isboolean(L, -1) || lua_isnil(L, -1)) {
|
|
|
|
result = lua_toboolean(L, -1);
|
2014-12-30 01:49:05 +00:00
|
|
|
} else if (lua_type(L, -1) == LUA_TNUMBER) {
|
|
|
|
result = lua_tointeger(L,-1) != 0 ? TRUE : FALSE;
|
2014-03-10 05:54:51 +00:00
|
|
|
} else {
|
2014-12-24 20:04:01 +00:00
|
|
|
proto_tree_add_expert_format(tree, pinfo, &ei_lua_error, tvb, 0, 0,
|
|
|
|
"Lua Error: invalid return value from Lua %s heuristic dissector", pinfo->current_proto);
|
2014-03-10 05:54:51 +00:00
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2015-01-24 20:58:30 +00:00
|
|
|
wmem_register_callback(pinfo->pool, lua_pinfo_end, NULL);
|
2014-03-10 05:54:51 +00:00
|
|
|
|
2016-10-06 14:26:27 +00:00
|
|
|
lua_pinfo = saved_lua_pinfo;
|
|
|
|
lua_tree = saved_lua_tree;
|
|
|
|
lua_tvb = saved_lua_tvb;
|
2014-03-10 05:54:51 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-06-25 20:28:14 +00:00
|
|
|
static void iter_table_and_call(lua_State* LS, const gchar* table_name, lua_CFunction error_handler) {
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_settop(LS,0);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_pushcfunction(LS,error_handler);
|
2012-06-25 20:28:14 +00:00
|
|
|
lua_getglobal(LS, table_name);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
if (!lua_istable(LS, 2)) {
|
|
|
|
report_failure("Lua: either `%s' does not exist or it is not a table!\n",table_name);
|
|
|
|
lua_close(LS);
|
|
|
|
L = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushnil(LS);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
while (lua_next(LS, 2)) {
|
|
|
|
const gchar* name = lua_tostring(L,-2);
|
|
|
|
|
|
|
|
if (lua_isfunction(LS,-1)) {
|
|
|
|
|
|
|
|
if ( lua_pcall(LS,0,0,1) ) {
|
|
|
|
lua_pop(LS,1);
|
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
} else {
|
|
|
|
report_failure("Lua: Something not a function got its way into the %s.%s",table_name,name);
|
|
|
|
lua_close(LS);
|
|
|
|
L = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_settop(LS,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-21 12:41:15 +00:00
|
|
|
static int init_error_handler(lua_State* LS) {
|
2006-09-25 01:09:00 +00:00
|
|
|
const gchar* error = lua_tostring(LS,1);
|
2020-10-29 15:01:27 +00:00
|
|
|
report_failure("Lua: Error during execution of initialization:\n %s",error);
|
2006-09-25 01:09:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
static gboolean init_routine_initialized = FALSE;
|
2010-10-21 12:41:15 +00:00
|
|
|
static void wslua_init_routine(void) {
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
if ( ! init_routine_initialized ) {
|
2015-07-04 05:12:56 +00:00
|
|
|
/*
|
|
|
|
* This must be done only once during the entire life of
|
|
|
|
* tshark/wireshark, because it must be done only once per the life of
|
|
|
|
* the Lua state/engine, so we guard this with the boolean above;
|
|
|
|
* otherwise it would occur every time a file is opened (every time
|
|
|
|
* epan_new() is called).
|
|
|
|
*
|
|
|
|
* If we ever allow the Lua state to be restarted, or to have multiple
|
|
|
|
* Lua states, we'll need to change this.
|
|
|
|
*/
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_prime_all_fields(NULL);
|
2015-08-11 12:08:08 +00:00
|
|
|
init_routine_initialized = TRUE;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
if (L) {
|
2012-06-25 20:28:14 +00:00
|
|
|
iter_table_and_call(L, WSLUA_INIT_ROUTINES,init_error_handler);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-07-04 05:12:56 +00:00
|
|
|
static void wslua_cleanup_routine(void) {
|
|
|
|
if (L) {
|
|
|
|
iter_table_and_call(L, WSLUA_INIT_ROUTINES,init_error_handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-07 11:27:38 +00:00
|
|
|
static int prefs_changed_error_handler(lua_State* LS) {
|
|
|
|
const gchar* error = lua_tostring(LS,1);
|
2020-10-29 15:01:27 +00:00
|
|
|
report_failure("Lua: Error during execution of prefs apply callback:\n %s",error);
|
2013-09-07 11:27:38 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wslua_prefs_changed(void) {
|
|
|
|
if (L) {
|
|
|
|
iter_table_and_call(L, WSLUA_PREFS_CHANGED,prefs_changed_error_handler);
|
|
|
|
}
|
|
|
|
}
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2010-10-21 12:41:15 +00:00
|
|
|
static const char *getF(lua_State *LS _U_, void *ud, size_t *size)
|
2006-09-25 01:09:00 +00:00
|
|
|
{
|
|
|
|
FILE *f=(FILE *)ud;
|
|
|
|
static char buff[512];
|
|
|
|
if (feof(f)) return NULL;
|
|
|
|
*size=fread(buff,1,sizeof(buff),f);
|
|
|
|
return (*size>0) ? buff : NULL;
|
|
|
|
}
|
|
|
|
|
2019-01-27 18:03:21 +00:00
|
|
|
static int error_handler_with_callback(lua_State *LS) {
|
|
|
|
#if LUA_VERSION_NUM >= 502
|
|
|
|
const char *msg = lua_tostring(LS, 1);
|
|
|
|
luaL_traceback(LS, LS, msg, 1); /* push message with traceback. */
|
|
|
|
lua_remove(LS, -2); /* remove original msg */
|
|
|
|
#else
|
|
|
|
/* Return error message, unmodified */
|
|
|
|
(void)LS;
|
|
|
|
#endif
|
|
|
|
return 1;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
static void wslua_add_plugin(const gchar *name, const gchar *version, const gchar *filename)
|
2009-10-23 17:52:18 +00:00
|
|
|
{
|
|
|
|
wslua_plugin *new_plug, *lua_plug;
|
|
|
|
|
|
|
|
lua_plug = wslua_plugin_list;
|
2020-12-21 02:30:28 +00:00
|
|
|
new_plug = g_new(wslua_plugin, 1);
|
2009-10-23 17:52:18 +00:00
|
|
|
|
|
|
|
if (!lua_plug) { /* the list is empty */
|
|
|
|
wslua_plugin_list = new_plug;
|
|
|
|
} else {
|
|
|
|
while (lua_plug->next != NULL) {
|
|
|
|
lua_plug = lua_plug->next;
|
|
|
|
}
|
|
|
|
lua_plug->next = new_plug;
|
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
new_plug->name = g_strdup(name);
|
|
|
|
new_plug->version = g_strdup(version);
|
|
|
|
new_plug->filename = g_strdup(filename);
|
2009-10-23 17:52:18 +00:00
|
|
|
new_plug->next = NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
static void wslua_clear_plugin_list(void)
|
|
|
|
{
|
|
|
|
wslua_plugin *lua_plug;
|
|
|
|
|
|
|
|
while (wslua_plugin_list) {
|
|
|
|
lua_plug = wslua_plugin_list;
|
|
|
|
wslua_plugin_list = wslua_plugin_list->next;
|
|
|
|
g_free (lua_plug->name);
|
|
|
|
g_free (lua_plug->version);
|
|
|
|
g_free (lua_plug->filename);
|
|
|
|
g_free (lua_plug);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-09 19:27:51 +00:00
|
|
|
static int lua_script_push_args(const int script_num) {
|
|
|
|
gchar* argname = g_strdup_printf("lua_script%d", script_num);
|
|
|
|
const gchar* argvalue = NULL;
|
2016-04-08 21:28:45 +00:00
|
|
|
int i, count = ex_opt_count(argname);
|
2014-02-09 19:27:51 +00:00
|
|
|
|
2016-04-08 21:28:45 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
argvalue = ex_opt_get_nth(argname, i);
|
2014-02-09 19:27:51 +00:00
|
|
|
lua_pushstring(L,argvalue);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(argname);
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2014-03-26 06:24:51 +00:00
|
|
|
#define FILE_NAME_KEY "__FILE__"
|
|
|
|
#define DIR_NAME_KEY "__DIR__"
|
2014-03-26 23:12:04 +00:00
|
|
|
#define DIR_SEP_NAME_KEY "__DIR_SEPARATOR__"
|
2014-03-26 06:24:51 +00:00
|
|
|
/* assumes a loaded chunk's function is on top of stack */
|
|
|
|
static void set_file_environment(const gchar* filename, const gchar* dirname) {
|
2014-03-26 23:12:04 +00:00
|
|
|
const char* path;
|
|
|
|
|
2014-03-26 06:24:51 +00:00
|
|
|
lua_newtable(L); /* environment for script (index 3) */
|
|
|
|
|
|
|
|
lua_pushstring(L, filename); /* tell the script about its filename */
|
|
|
|
lua_setfield(L, -2, FILE_NAME_KEY); /* make it accessible at __FILE__ */
|
|
|
|
|
|
|
|
lua_pushstring(L, dirname); /* tell the script about its dirname */
|
|
|
|
lua_setfield(L, -2, DIR_NAME_KEY); /* make it accessible at __DIR__ */
|
|
|
|
|
2014-03-26 23:12:04 +00:00
|
|
|
lua_pushstring(L, G_DIR_SEPARATOR_S); /* tell the script the directory separator */
|
|
|
|
lua_setfield(L, -2, DIR_SEP_NAME_KEY); /* make it accessible at __DIR__ */
|
|
|
|
|
|
|
|
lua_newtable(L); /* new metatable */
|
2014-03-26 06:24:51 +00:00
|
|
|
|
|
|
|
#if LUA_VERSION_NUM >= 502
|
|
|
|
lua_pushglobaltable(L);
|
|
|
|
#else
|
|
|
|
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
|
|
|
#endif
|
2014-03-26 23:12:04 +00:00
|
|
|
/* prepend the directory name to _G.package.path */
|
|
|
|
lua_getfield(L, -1, "package"); /* get the package table from the global table */
|
|
|
|
lua_getfield(L, -1, "path"); /* get the path field from the package table */
|
|
|
|
path = luaL_checkstring(L, -1); /* get the path string */
|
|
|
|
lua_pop(L, 1); /* pop the path string */
|
|
|
|
/* prepend the various paths */
|
|
|
|
lua_pushfstring(L, "%s" G_DIR_SEPARATOR_S "?.lua;%s" G_DIR_SEPARATOR_S "?.lua;%s" G_DIR_SEPARATOR_S "?.lua;%s",
|
2017-09-18 14:45:17 +00:00
|
|
|
dirname, get_plugins_pers_dir(), get_plugins_dir(), path);
|
2014-03-26 23:12:04 +00:00
|
|
|
lua_setfield(L, -2, "path"); /* set the new string to be the path field of the package table */
|
|
|
|
lua_setfield(L, -2, "package"); /* set the package table to be the package field of the global */
|
|
|
|
|
|
|
|
lua_setfield(L, -2, "__index"); /* make metatable's __index point to global table */
|
2014-03-26 06:24:51 +00:00
|
|
|
|
|
|
|
lua_setmetatable(L, -2); /* pop metatable, set it as metatable of environment */
|
|
|
|
|
|
|
|
#if LUA_VERSION_NUM >= 502
|
|
|
|
lua_setupvalue(L, -2, 1); /* pop environment and assign it to upvalue 1 */
|
|
|
|
#else
|
|
|
|
lua_setfenv(L, -2); /* pop environment and set it as the func's environment */
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-07-10 15:34:04 +00:00
|
|
|
|
2014-02-09 19:27:51 +00:00
|
|
|
/* If file_count > 0 then it's a command-line-added user script, and the count
|
|
|
|
* represents which user script it is (first=1, second=2, etc.).
|
2014-03-26 06:24:51 +00:00
|
|
|
* If dirname != NULL, then it's a user script and the dirname will get put in a file environment
|
|
|
|
* If dirname == NULL then it's a wireshark script and no file environment is created
|
2014-02-09 19:27:51 +00:00
|
|
|
*/
|
2014-03-26 06:24:51 +00:00
|
|
|
static gboolean lua_load_script(const gchar* filename, const gchar* dirname, const int file_count) {
|
2006-09-25 01:09:00 +00:00
|
|
|
FILE* file;
|
2009-10-23 17:52:18 +00:00
|
|
|
int error;
|
2014-02-09 19:27:51 +00:00
|
|
|
int numargs = 0;
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2008-05-22 15:46:27 +00:00
|
|
|
if (! ( file = ws_fopen(filename,"r")) ) {
|
2006-09-25 01:09:00 +00:00
|
|
|
report_open_failure(filename,errno,FALSE);
|
2009-10-23 17:52:18 +00:00
|
|
|
return FALSE;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lua_settop(L,0);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2019-01-27 18:03:21 +00:00
|
|
|
lua_pushcfunction(L, error_handler_with_callback);
|
2020-03-03 02:58:58 +00:00
|
|
|
/* The source argument should start with '@' to indicate a file. */
|
2018-09-06 13:27:58 +00:00
|
|
|
lua_pushfstring(L, "@%s", filename);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2012-06-25 20:28:14 +00:00
|
|
|
#if LUA_VERSION_NUM >= 502
|
2018-09-06 13:27:58 +00:00
|
|
|
error = lua_load(L, getF, file, lua_tostring(L, -1), NULL);
|
2012-06-25 20:28:14 +00:00
|
|
|
#else
|
2018-09-06 13:27:58 +00:00
|
|
|
error = lua_load(L, getF, file, lua_tostring(L, -1));
|
2012-06-25 20:28:14 +00:00
|
|
|
#endif
|
2014-03-26 06:24:51 +00:00
|
|
|
|
2009-10-23 17:52:18 +00:00
|
|
|
switch (error) {
|
2017-08-08 21:02:45 +00:00
|
|
|
case 0: /* LUA_OK */
|
2014-03-26 06:24:51 +00:00
|
|
|
if (dirname) {
|
|
|
|
set_file_environment(filename, dirname);
|
|
|
|
}
|
2014-02-09 19:27:51 +00:00
|
|
|
if (file_count > 0) {
|
|
|
|
numargs = lua_script_push_args(file_count);
|
|
|
|
}
|
2019-01-27 18:03:21 +00:00
|
|
|
error = lua_pcall(L, numargs, 0, 1);
|
2019-01-28 11:25:18 +00:00
|
|
|
if (error) {
|
2019-01-27 18:03:21 +00:00
|
|
|
switch (error) {
|
|
|
|
case LUA_ERRRUN:
|
|
|
|
report_failure("Lua: Error during loading:\n%s", lua_tostring(L, -1));
|
|
|
|
break;
|
|
|
|
case LUA_ERRMEM:
|
|
|
|
report_failure("Lua: Error during loading: out of memory");
|
|
|
|
break;
|
|
|
|
case LUA_ERRERR:
|
|
|
|
report_failure("Lua: Error during loading: error while retrieving error message");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
report_failure("Lua: Error during loading: unknown error %d", error);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-09-06 13:27:58 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LUA_ERRSYNTAX:
|
2019-01-28 08:09:08 +00:00
|
|
|
report_failure("Lua: syntax error: %s", lua_tostring(L, -1));
|
2018-09-06 13:27:58 +00:00
|
|
|
break;
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
case LUA_ERRMEM:
|
2019-01-28 08:09:08 +00:00
|
|
|
report_failure("Lua: memory allocation error during precompilation of %s", filename);
|
2018-09-06 13:27:58 +00:00
|
|
|
break;
|
|
|
|
|
2012-06-25 20:28:14 +00:00
|
|
|
default:
|
2019-01-28 08:09:08 +00:00
|
|
|
report_failure("Lua: unknown error during precompilation of %s: %d", filename, error);
|
2018-09-06 13:27:58 +00:00
|
|
|
break;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2018-09-06 13:27:58 +00:00
|
|
|
fclose(file);
|
|
|
|
lua_pop(L, 2); /* pop the filename and error handler */
|
|
|
|
return error == 0;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2015-07-10 15:34:04 +00:00
|
|
|
/* This one is used to load the init.lua scripts, or anything else
|
|
|
|
* that shouldn't really be considered a real plugin.
|
|
|
|
*/
|
|
|
|
static gboolean lua_load_internal_script(const gchar* filename) {
|
|
|
|
return lua_load_script(filename, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This one is used to load plugins: either from the plugin directories,
|
|
|
|
* or from the command line.
|
|
|
|
*/
|
|
|
|
static gboolean lua_load_plugin_script(const gchar* name,
|
|
|
|
const gchar* filename,
|
|
|
|
const gchar* dirname,
|
|
|
|
const int file_count)
|
|
|
|
{
|
|
|
|
if (lua_load_script(filename, dirname, file_count)) {
|
2015-08-11 12:08:08 +00:00
|
|
|
wslua_add_plugin(name, get_current_plugin_version(), filename);
|
2015-07-10 15:34:04 +00:00
|
|
|
clear_current_plugin_version();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-16 13:11:08 +00:00
|
|
|
static void basic_logger(const gchar *log_domain,
|
|
|
|
enum ws_log_level log_level,
|
2010-10-21 12:41:15 +00:00
|
|
|
const gchar *message,
|
|
|
|
gpointer user_data _U_) {
|
2021-06-16 13:11:08 +00:00
|
|
|
ws_log(log_domain, log_level, "%s", message);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2010-10-21 12:41:15 +00:00
|
|
|
static int wslua_panic(lua_State* LS) {
|
2021-06-14 23:06:02 +00:00
|
|
|
ws_error("LUA PANIC: %s",lua_tostring(LS,-1));
|
|
|
|
/** ws_error() does an abort() and thus never returns **/
|
2011-01-31 04:23:46 +00:00
|
|
|
return 0; /* keep gcc happy */
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2021-03-17 11:19:14 +00:00
|
|
|
static gint string_compare(gconstpointer a, gconstpointer b) {
|
|
|
|
return strcmp((const char*)a, (const char*)b);
|
|
|
|
}
|
|
|
|
|
2014-03-26 06:24:51 +00:00
|
|
|
static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client_data,
|
2017-09-19 11:12:31 +00:00
|
|
|
gboolean count_only, const gboolean is_user, GHashTable *loaded_files)
|
2014-03-26 06:24:51 +00:00
|
|
|
{
|
2009-10-23 17:52:18 +00:00
|
|
|
WS_DIR *dir; /* scanned directory */
|
|
|
|
WS_DIRENT *file; /* current file */
|
2009-10-24 13:36:16 +00:00
|
|
|
gchar *filename, *dot;
|
|
|
|
const gchar *name;
|
2013-08-13 10:38:30 +00:00
|
|
|
int plugins_counter = 0;
|
2021-03-17 11:19:14 +00:00
|
|
|
GList *sorted_dirnames = NULL;
|
|
|
|
GList *sorted_filenames = NULL;
|
|
|
|
GList *l = NULL;
|
2009-10-23 17:52:18 +00:00
|
|
|
|
|
|
|
if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) {
|
|
|
|
while ((file = ws_dir_read_name(dir)) != NULL) {
|
|
|
|
name = ws_dir_get_name(file);
|
|
|
|
|
|
|
|
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
|
|
|
|
continue; /* skip "." and ".." */
|
|
|
|
|
2009-10-24 13:36:16 +00:00
|
|
|
filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dirname, name);
|
|
|
|
if (test_for_directory(filename) == EISDIR) {
|
2021-03-17 11:19:14 +00:00
|
|
|
sorted_dirnames = g_list_prepend(sorted_dirnames, (gpointer)filename);
|
2009-10-24 13:36:16 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-08-13 11:18:44 +00:00
|
|
|
/* skip files starting wih . */
|
|
|
|
if (name[0] == '.') {
|
|
|
|
g_free(filename);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-10-23 17:52:18 +00:00
|
|
|
/* skip anything but files with .lua suffix */
|
|
|
|
dot = strrchr(name, '.');
|
2011-08-25 19:01:05 +00:00
|
|
|
if (dot == NULL || g_ascii_strcasecmp(dot+1, "lua") != 0) {
|
2009-10-24 13:36:16 +00:00
|
|
|
g_free(filename);
|
2009-10-23 17:52:18 +00:00
|
|
|
continue;
|
2009-10-24 13:36:16 +00:00
|
|
|
}
|
2009-10-23 17:52:18 +00:00
|
|
|
|
2021-03-17 11:19:14 +00:00
|
|
|
if (file_exists(filename)) {
|
|
|
|
sorted_filenames = g_list_prepend(sorted_filenames, (gpointer)filename);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g_free(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ws_dir_close(dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Depth first; ie, process subdirectories (in ASCIIbetical order) before files */
|
|
|
|
if (sorted_dirnames != NULL) {
|
|
|
|
sorted_dirnames = g_list_sort(sorted_dirnames, string_compare);
|
|
|
|
for (l = sorted_dirnames; l != NULL; l = l->next) {
|
|
|
|
plugins_counter += lua_load_plugins((const char *)l->data, cb, client_data, count_only, is_user, loaded_files);
|
|
|
|
}
|
|
|
|
g_list_free_full(sorted_dirnames, g_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Process files in ASCIIbetical order */
|
|
|
|
if (sorted_filenames != NULL) {
|
|
|
|
sorted_filenames = g_list_sort(sorted_filenames, string_compare);
|
|
|
|
for (l = sorted_filenames; l != NULL; l = l->next) {
|
|
|
|
filename = (gchar *)l->data;
|
|
|
|
name = strrchr(filename, G_DIR_SEPARATOR) + 1;
|
|
|
|
|
2017-09-19 11:12:31 +00:00
|
|
|
/* Check if we have already loaded this file name, if provided with a set */
|
|
|
|
if (loaded_files && g_hash_table_lookup_extended(loaded_files, name, NULL, NULL)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-03-17 11:19:14 +00:00
|
|
|
if (!count_only) {
|
|
|
|
if (cb)
|
|
|
|
(*cb)(RA_LUA_PLUGINS, name, client_data);
|
|
|
|
lua_load_plugin_script(name, filename, is_user ? dirname : NULL, 0);
|
|
|
|
|
2017-09-19 11:12:31 +00:00
|
|
|
if (loaded_files) {
|
|
|
|
g_hash_table_insert(loaded_files, g_strdup(name), NULL);
|
|
|
|
}
|
2009-10-23 17:52:18 +00:00
|
|
|
}
|
2021-03-17 11:19:14 +00:00
|
|
|
plugins_counter++;
|
2009-10-23 17:52:18 +00:00
|
|
|
}
|
2021-03-17 11:19:14 +00:00
|
|
|
g_list_free_full(sorted_filenames, g_free);
|
2009-10-23 17:52:18 +00:00
|
|
|
}
|
2013-08-13 10:38:30 +00:00
|
|
|
|
|
|
|
return plugins_counter;
|
|
|
|
}
|
|
|
|
|
2017-09-19 11:12:31 +00:00
|
|
|
static int lua_load_global_plugins(register_cb cb, gpointer client_data,
|
|
|
|
gboolean count_only)
|
|
|
|
{
|
|
|
|
return lua_load_plugins(get_plugins_dir(), cb, client_data, count_only, FALSE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lua_load_pers_plugins(register_cb cb, gpointer client_data,
|
|
|
|
gboolean count_only)
|
|
|
|
{
|
|
|
|
int plugins_counter = 0;
|
|
|
|
|
|
|
|
/* aux table (set) to make sure we only load each file once (by name) */
|
|
|
|
GHashTable *loaded_user_scripts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
|
|
|
|
/* load user scripts */
|
|
|
|
plugins_counter += lua_load_plugins(get_plugins_pers_dir(), cb, client_data, count_only, TRUE, loaded_user_scripts);
|
|
|
|
|
|
|
|
/* for backward compatibility check old plugin directory */
|
|
|
|
char *old_path = get_persconffile_path("plugins", FALSE);
|
|
|
|
if (strcmp(get_plugins_pers_dir(), old_path) != 0) {
|
|
|
|
plugins_counter += lua_load_plugins(old_path, cb, client_data, count_only, TRUE, loaded_user_scripts);
|
|
|
|
}
|
|
|
|
g_free(old_path);
|
|
|
|
|
|
|
|
g_hash_table_destroy(loaded_user_scripts);
|
|
|
|
|
|
|
|
return plugins_counter;
|
|
|
|
}
|
|
|
|
|
2013-08-13 10:38:30 +00:00
|
|
|
int wslua_count_plugins(void) {
|
|
|
|
gchar* filename;
|
|
|
|
int plugins_counter;
|
|
|
|
|
|
|
|
/* count global scripts */
|
2017-09-19 11:12:31 +00:00
|
|
|
plugins_counter = lua_load_global_plugins(NULL, NULL, TRUE);
|
2013-08-13 10:38:30 +00:00
|
|
|
|
|
|
|
/* count users init.lua */
|
|
|
|
filename = get_persconffile_path("init.lua", FALSE);
|
|
|
|
if ((file_exists(filename))) {
|
|
|
|
plugins_counter++;
|
|
|
|
}
|
|
|
|
g_free(filename);
|
|
|
|
|
|
|
|
/* count user scripts */
|
2017-09-19 11:12:31 +00:00
|
|
|
plugins_counter += lua_load_pers_plugins(NULL, NULL, TRUE);
|
2013-08-13 10:38:30 +00:00
|
|
|
|
|
|
|
/* count scripts from command line */
|
|
|
|
plugins_counter += ex_opt_count("lua_script");
|
|
|
|
|
|
|
|
return plugins_counter;
|
2009-10-23 17:52:18 +00:00
|
|
|
}
|
|
|
|
|
2013-12-02 08:30:29 +00:00
|
|
|
void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback, void *user_data) {
|
|
|
|
wslua_plugin *lua_plug;
|
|
|
|
|
|
|
|
for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
|
|
|
|
{
|
2018-01-29 22:40:45 +00:00
|
|
|
callback(lua_plug->name, lua_plug->version, wslua_plugin_type_name(),
|
2013-12-02 08:30:29 +00:00
|
|
|
lua_plug->filename, user_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_wslua_plugin_description(const char *name, const char *version,
|
|
|
|
const char *description, const char *filename,
|
|
|
|
void *user_data _U_)
|
|
|
|
{
|
2021-02-27 03:38:15 +00:00
|
|
|
printf("%s\t%s\t%s\t%s\n", name, version, description, filename);
|
2013-12-02 08:30:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
wslua_plugins_dump_all(void)
|
|
|
|
{
|
|
|
|
wslua_plugins_get_descriptions(print_wslua_plugin_description, NULL);
|
|
|
|
}
|
|
|
|
|
2018-01-29 22:40:45 +00:00
|
|
|
const char *wslua_plugin_type_name(void) {
|
|
|
|
return "lua script";
|
|
|
|
}
|
|
|
|
|
2014-03-25 22:11:05 +00:00
|
|
|
static ei_register_info* ws_lua_ei = NULL;
|
|
|
|
static int ws_lua_ei_len = 0;
|
|
|
|
|
|
|
|
expert_field*
|
|
|
|
wslua_get_expert_field(const int group, const int severity)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
const ei_register_info *ei = ws_lua_ei;
|
|
|
|
|
2021-03-20 01:58:26 +00:00
|
|
|
ws_assert(ei);
|
2014-03-25 22:11:05 +00:00
|
|
|
|
|
|
|
for (i=0; i < ws_lua_ei_len; i++, ei++) {
|
|
|
|
if (ei->eiinfo.group == group && ei->eiinfo.severity == severity)
|
|
|
|
return ei->ids;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ei_lua_error;
|
|
|
|
}
|
|
|
|
|
2016-04-02 22:12:32 +00:00
|
|
|
static void *
|
|
|
|
wslua_allocf(void *ud _U_, void *ptr, size_t osize _U_, size_t nsize)
|
|
|
|
{
|
|
|
|
/* g_realloc frees ptr if nsize==0 and returns NULL (as desired).
|
|
|
|
* Furthermore it simplifies error handling by aborting on OOM */
|
|
|
|
return g_realloc(ptr, nsize);
|
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
void wslua_init(register_cb cb, gpointer client_data) {
|
2008-02-26 23:05:05 +00:00
|
|
|
gchar* filename;
|
2006-09-25 01:09:00 +00:00
|
|
|
const funnel_ops_t* ops = funnel_get_funnel_ops();
|
2018-07-19 22:06:07 +00:00
|
|
|
gboolean enable_lua = TRUE;
|
2006-09-25 01:09:00 +00:00
|
|
|
gboolean run_anyway = FALSE;
|
2013-10-09 12:56:19 +00:00
|
|
|
expert_module_t* expert_lua;
|
2014-02-09 19:27:51 +00:00
|
|
|
int file_count = 1;
|
2015-08-11 12:08:08 +00:00
|
|
|
static gboolean first_time = TRUE;
|
2016-04-08 21:28:45 +00:00
|
|
|
int i;
|
2013-10-09 12:56:19 +00:00
|
|
|
|
2015-01-04 00:27:59 +00:00
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_wslua_fake,
|
|
|
|
{ "Wireshark Lua fake item", "_ws.lua.fake",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
|
|
"Fake internal item for Wireshark Lua", HFILL }},
|
|
|
|
{ &hf_wslua_text,
|
|
|
|
{ "Wireshark Lua text", "_ws.lua.text",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
|
|
};
|
|
|
|
|
2013-10-09 12:56:19 +00:00
|
|
|
static ei_register_info ei[] = {
|
2014-03-25 22:11:05 +00:00
|
|
|
/* the following are created so we can continue to support the TreeItem_add_expert_info()
|
|
|
|
function to Lua scripts. That function doesn't know what registered protocol to use,
|
|
|
|
so it uses the "_ws.lua" one. */
|
|
|
|
/* XXX: it seems to me we should not be offering PI_GROUP_MASK nor PI_SEVERITY_MASK since
|
|
|
|
they are not real settings, so I'm not adding them below (should they also not be exported
|
|
|
|
into Lua? they are right now.) */
|
|
|
|
/* NOTE: do not add expert entries at the top of this array - only at the bottom. This array
|
|
|
|
is not only used by expert.c, but also by wslua_get_expert_field() to find the appropriate
|
|
|
|
"dummy" entry. So this array's ordering matters. */
|
|
|
|
{ &ei_lua_proto_checksum_comment, { "_ws.lua.proto.comment", PI_CHECKSUM, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_checksum_chat, { "_ws.lua.proto.chat", PI_CHECKSUM, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_checksum_note, { "_ws.lua.proto.note", PI_CHECKSUM, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_checksum_warn, { "_ws.lua.proto.warning", PI_CHECKSUM, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_checksum_error, { "_ws.lua.proto.error", PI_CHECKSUM, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_sequence_comment, { "_ws.lua.proto.comment", PI_SEQUENCE, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_sequence_chat, { "_ws.lua.proto.chat", PI_SEQUENCE, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_sequence_note, { "_ws.lua.proto.note", PI_SEQUENCE, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_sequence_warn, { "_ws.lua.proto.warning", PI_SEQUENCE, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_sequence_error, { "_ws.lua.proto.error", PI_SEQUENCE, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_response_comment, { "_ws.lua.proto.comment", PI_RESPONSE_CODE, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_response_chat, { "_ws.lua.proto.chat", PI_RESPONSE_CODE, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_response_note, { "_ws.lua.proto.note", PI_RESPONSE_CODE, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_response_warn, { "_ws.lua.proto.warning", PI_RESPONSE_CODE, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_response_error, { "_ws.lua.proto.error", PI_RESPONSE_CODE, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_request_comment, { "_ws.lua.proto.comment", PI_REQUEST_CODE, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_request_chat, { "_ws.lua.proto.chat", PI_REQUEST_CODE, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_request_note, { "_ws.lua.proto.note", PI_REQUEST_CODE, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_request_warn, { "_ws.lua.proto.warning", PI_REQUEST_CODE, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_request_error, { "_ws.lua.proto.error", PI_REQUEST_CODE, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_undecoded_comment, { "_ws.lua.proto.comment", PI_UNDECODED, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_undecoded_chat, { "_ws.lua.proto.chat", PI_UNDECODED, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_undecoded_note, { "_ws.lua.proto.note", PI_UNDECODED, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_undecoded_warn, { "_ws.lua.proto.warning", PI_UNDECODED, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_undecoded_error, { "_ws.lua.proto.error", PI_UNDECODED, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_reassemble_comment, { "_ws.lua.proto.comment", PI_REASSEMBLE, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_reassemble_chat, { "_ws.lua.proto.chat", PI_REASSEMBLE, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_reassemble_note, { "_ws.lua.proto.note", PI_REASSEMBLE, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_reassemble_warn, { "_ws.lua.proto.warning", PI_REASSEMBLE, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_reassemble_error, { "_ws.lua.proto.error", PI_REASSEMBLE, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_malformed_comment, { "_ws.lua.proto.comment", PI_MALFORMED, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_malformed_chat, { "_ws.lua.proto.chat", PI_MALFORMED, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_malformed_note, { "_ws.lua.proto.note", PI_MALFORMED, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_malformed_warn, { "_ws.lua.proto.warning", PI_MALFORMED, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_malformed_error, { "_ws.lua.proto.error", PI_MALFORMED, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_debug_comment, { "_ws.lua.proto.comment", PI_DEBUG, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_debug_chat, { "_ws.lua.proto.chat", PI_DEBUG, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_debug_note, { "_ws.lua.proto.note", PI_DEBUG, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_debug_warn, { "_ws.lua.proto.warning", PI_DEBUG, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_debug_error, { "_ws.lua.proto.error", PI_DEBUG, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_protocol_comment, { "_ws.lua.proto.comment", PI_PROTOCOL, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_protocol_chat, { "_ws.lua.proto.chat", PI_PROTOCOL, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_protocol_note, { "_ws.lua.proto.note", PI_PROTOCOL, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_protocol_warn, { "_ws.lua.proto.warning", PI_PROTOCOL, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_protocol_error, { "_ws.lua.proto.error", PI_PROTOCOL, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_security_comment, { "_ws.lua.proto.comment", PI_SECURITY, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_security_chat, { "_ws.lua.proto.chat", PI_SECURITY, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_security_note, { "_ws.lua.proto.note", PI_SECURITY, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_security_warn, { "_ws.lua.proto.warning", PI_SECURITY, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_security_error, { "_ws.lua.proto.error", PI_SECURITY, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_comments_comment, { "_ws.lua.proto.comment", PI_COMMENTS_GROUP, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_comments_chat, { "_ws.lua.proto.chat", PI_COMMENTS_GROUP, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_comments_note, { "_ws.lua.proto.note", PI_COMMENTS_GROUP, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_comments_warn, { "_ws.lua.proto.warning", PI_COMMENTS_GROUP, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_comments_error, { "_ws.lua.proto.error", PI_COMMENTS_GROUP, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
2021-06-02 04:17:39 +00:00
|
|
|
{ &ei_lua_proto_decryption_comment, { "_ws.lua.proto.comment", PI_DECRYPTION, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_decryption_chat, { "_ws.lua.proto.chat", PI_DECRYPTION, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_decryption_note, { "_ws.lua.proto.note", PI_DECRYPTION, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_decryption_warn, { "_ws.lua.proto.warning", PI_DECRYPTION, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_decryption_error, { "_ws.lua.proto.error", PI_DECRYPTION, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
|
|
|
{ &ei_lua_proto_assumption_comment, { "_ws.lua.proto.comment", PI_ASSUMPTION, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_assumption_chat, { "_ws.lua.proto.chat", PI_ASSUMPTION, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_assumption_note, { "_ws.lua.proto.note", PI_ASSUMPTION, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_assumption_warn, { "_ws.lua.proto.warning", PI_ASSUMPTION, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_assumption_error, { "_ws.lua.proto.error", PI_ASSUMPTION, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
2016-07-29 14:00:56 +00:00
|
|
|
{ &ei_lua_proto_deprecated_comment, { "_ws.lua.proto.comment", PI_DEPRECATED, PI_COMMENT ,"Protocol Comment", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_deprecated_chat, { "_ws.lua.proto.chat", PI_DEPRECATED, PI_CHAT ,"Protocol Chat", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_deprecated_note, { "_ws.lua.proto.note", PI_DEPRECATED, PI_NOTE ,"Protocol Note", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_deprecated_warn, { "_ws.lua.proto.warning", PI_DEPRECATED, PI_WARN ,"Protocol Warning", EXPFILL }},
|
|
|
|
{ &ei_lua_proto_deprecated_error, { "_ws.lua.proto.error", PI_DEPRECATED, PI_ERROR ,"Protocol Error", EXPFILL }},
|
|
|
|
|
2014-03-25 22:11:05 +00:00
|
|
|
/* this one is for reporting errors executing Lua code */
|
2013-10-09 12:56:19 +00:00
|
|
|
{ &ei_lua_error, { "_ws.lua.error", PI_UNDECODED, PI_ERROR ,"Lua Error", EXPFILL }},
|
|
|
|
};
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
if (first_time) {
|
|
|
|
ws_lua_ei = ei;
|
|
|
|
ws_lua_ei_len = array_length(ei);
|
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2017-12-19 08:40:08 +00:00
|
|
|
/* set up the logger */
|
|
|
|
wslua_logger = ops ? ops->logger : basic_logger;
|
|
|
|
|
2008-04-25 19:04:52 +00:00
|
|
|
if (!L) {
|
2016-04-02 22:12:32 +00:00
|
|
|
L = lua_newstate(wslua_allocf, NULL);
|
2008-04-25 19:04:52 +00:00
|
|
|
}
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2008-04-25 19:04:52 +00:00
|
|
|
WSLUA_INIT(L);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2019-05-02 02:08:15 +00:00
|
|
|
#if LUA_VERSION_NUM == 501
|
|
|
|
/* table.unpack was introduced with Lua 5.2, alias it to unpack. */
|
|
|
|
lua_getglobal(L, "table");
|
|
|
|
lua_getglobal(L, "unpack");
|
|
|
|
lua_setfield(L, -2, "unpack");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
#endif
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
if (first_time) {
|
|
|
|
proto_lua = proto_register_protocol("Lua Dissection", "Lua Dissection", "_ws.lua");
|
|
|
|
proto_register_field_array(proto_lua, hf, array_length(hf));
|
|
|
|
expert_lua = expert_register_protocol(proto_lua);
|
|
|
|
expert_register_field_array(expert_lua, ei, array_length(ei));
|
|
|
|
}
|
2013-10-09 12:56:19 +00:00
|
|
|
|
2008-04-25 19:04:52 +00:00
|
|
|
lua_atpanic(L,wslua_panic);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2021-02-06 06:02:54 +00:00
|
|
|
/*
|
|
|
|
* The init_routines table (accessible by the user).
|
|
|
|
*
|
|
|
|
* For a table a, a.init is syntactic sugar for a["init"], and
|
|
|
|
*
|
|
|
|
* function t.a.b.c.f () body end
|
|
|
|
*
|
|
|
|
* is syntactic sugar for
|
|
|
|
*
|
|
|
|
* t.a.b.c.f = function () body end
|
|
|
|
*
|
|
|
|
* so
|
|
|
|
*
|
|
|
|
* function proto.init () body end
|
|
|
|
*
|
|
|
|
* means
|
|
|
|
*
|
|
|
|
* proto["init"] = function () body end
|
|
|
|
*
|
|
|
|
* and the Proto class has an "init" method, with Proto_set_init()
|
|
|
|
* being the setter for that method; that routine adds the Lua
|
|
|
|
* function passed to it as a Lua argument to the WSLUA_INIT_ROUTINES
|
|
|
|
* table - i.e., "init_routines".
|
|
|
|
*/
|
2006-09-25 01:09:00 +00:00
|
|
|
lua_newtable (L);
|
2013-03-11 20:50:19 +00:00
|
|
|
lua_setglobal(L, WSLUA_INIT_ROUTINES);
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/* the dissectors table goes in the registry (not accessible) */
|
|
|
|
lua_newtable (L);
|
|
|
|
lua_dissectors_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
2014-03-10 05:54:51 +00:00
|
|
|
lua_newtable (L);
|
|
|
|
lua_heur_dissectors_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2013-09-07 11:27:38 +00:00
|
|
|
/* the preferences apply_cb table (accessible by the user) */
|
|
|
|
lua_newtable (L);
|
|
|
|
lua_setglobal(L, WSLUA_PREFS_CHANGED);
|
|
|
|
|
2013-02-26 02:38:52 +00:00
|
|
|
/* set running_superuser variable to its proper value */
|
2008-04-25 19:04:52 +00:00
|
|
|
WSLUA_REG_GLOBAL_BOOL(L,"running_superuser",started_with_special_privs());
|
2010-10-21 02:50:27 +00:00
|
|
|
|
2008-11-21 15:47:14 +00:00
|
|
|
/* special constant used by PDU reassembly handling */
|
|
|
|
/* see dissect_lua() for notes */
|
|
|
|
WSLUA_REG_GLOBAL_NUMBER(L,"DESEGMENT_ONE_MORE_SEGMENT",DESEGMENT_ONE_MORE_SEGMENT);
|
2006-09-25 01:09:00 +00:00
|
|
|
|
|
|
|
/* load system's init.lua */
|
cmake,wslua,wsutil: load files from run/ instead of source tree
Fixes Lua on macOS, tested with an out-of-tree build:
WS_BIN_PATH=$PWD/run ../wireshark/test/test.sh -s wslua
Previously programs that were ran from the build directory would load
data files (radius/, diameter/, init.lua) from the source directory.
Then in the case of Lua, files were loaded from the program directory
($BUILDDIR/run/init.lua on Linux) or source directory
(sSOURCEDIR/epan/wslua/console.lua).
On macOS, this does not work for Lua since files are installed into
$BUILDDIR/run/Wireshark.app/Contents/Resources/share/wireshark/init.lua
instead. Since CMake always copies data files (radius, console.lua,
etc.) into the build directory, make get_datafile_dir() return this
"run" directory instead.
Change-Id: If97d2f5686271caf9ad4d4e4fc58e902dc592a98
Reviewed-on: https://code.wireshark.org/review/19330
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Graham Bloice <graham.bloice@trihedral.com>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2016-12-18 15:49:24 +00:00
|
|
|
filename = get_datafile_path("init.lua");
|
2006-09-25 01:09:00 +00:00
|
|
|
if (( file_exists(filename))) {
|
2015-07-10 15:34:04 +00:00
|
|
|
lua_load_internal_script(filename);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2008-02-26 19:52:21 +00:00
|
|
|
g_free(filename);
|
|
|
|
filename = NULL;
|
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/* check if lua is to be disabled */
|
2018-07-19 22:06:07 +00:00
|
|
|
lua_getglobal(L, "disable_lua"); // 2.6 and earlier, deprecated
|
|
|
|
if (lua_isboolean(L,-1)) {
|
|
|
|
enable_lua = ! lua_toboolean(L,-1);
|
|
|
|
}
|
|
|
|
lua_pop(L,1); /* pop the getglobal result */
|
|
|
|
|
|
|
|
lua_getglobal(L, "enable_lua"); // 3.0 and later
|
|
|
|
if (lua_isboolean(L,-1)) {
|
|
|
|
enable_lua = lua_toboolean(L,-1);
|
|
|
|
}
|
|
|
|
lua_pop(L,1); /* pop the getglobal result */
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2018-07-19 22:06:07 +00:00
|
|
|
if (!enable_lua) {
|
2008-04-25 19:04:52 +00:00
|
|
|
/* disable lua */
|
|
|
|
lua_close(L);
|
|
|
|
L = NULL;
|
2015-08-11 12:08:08 +00:00
|
|
|
first_time = FALSE;
|
2016-02-28 16:53:52 +00:00
|
|
|
return;
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2006-12-22 05:48:57 +00:00
|
|
|
|
2009-10-23 17:52:18 +00:00
|
|
|
/* load global scripts */
|
2017-09-19 11:12:31 +00:00
|
|
|
lua_load_global_plugins(cb, client_data, FALSE);
|
2009-10-23 17:52:18 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/* check whether we should run other scripts even if running superuser */
|
2012-06-25 20:28:14 +00:00
|
|
|
lua_getglobal(L,"run_user_scripts_when_superuser");
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
if (lua_isboolean(L,-1) && lua_toboolean(L,-1)) {
|
|
|
|
run_anyway = TRUE;
|
|
|
|
}
|
2014-01-31 07:25:42 +00:00
|
|
|
lua_pop(L,1); /* pop the getglobal result */
|
2006-09-25 01:09:00 +00:00
|
|
|
|
|
|
|
/* if we are indeed superuser run user scripts only if told to do so */
|
|
|
|
if ( (!started_with_special_privs()) || run_anyway ) {
|
2013-08-13 10:38:30 +00:00
|
|
|
/* load users init.lua */
|
2013-04-09 02:48:03 +00:00
|
|
|
filename = get_persconffile_path("init.lua", FALSE);
|
2009-10-24 13:36:16 +00:00
|
|
|
if ((file_exists(filename))) {
|
2013-08-13 10:38:30 +00:00
|
|
|
if (cb)
|
|
|
|
(*cb)(RA_LUA_PLUGINS, get_basename(filename), client_data);
|
2015-07-10 15:34:04 +00:00
|
|
|
lua_load_internal_script(filename);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
2009-10-23 17:52:18 +00:00
|
|
|
g_free(filename);
|
|
|
|
|
|
|
|
/* load user scripts */
|
2017-09-19 11:12:31 +00:00
|
|
|
lua_load_pers_plugins(cb, client_data, FALSE);
|
2009-10-23 17:52:18 +00:00
|
|
|
|
|
|
|
/* load scripts from command line */
|
2016-04-08 21:28:45 +00:00
|
|
|
for (i = 0; i < ex_opt_count("lua_script"); i++) {
|
|
|
|
const gchar *script_filename = ex_opt_get_nth("lua_script", i);
|
2014-03-26 06:24:51 +00:00
|
|
|
char* dirname = g_strdup(script_filename);
|
|
|
|
char* dname = get_dirname(dirname);
|
|
|
|
|
2013-08-13 10:38:30 +00:00
|
|
|
if (cb)
|
2014-01-14 18:12:14 +00:00
|
|
|
(*cb)(RA_LUA_PLUGINS, get_basename(script_filename), client_data);
|
2014-03-26 06:24:51 +00:00
|
|
|
|
2015-07-10 15:34:04 +00:00
|
|
|
lua_load_plugin_script(ws_dir_get_name(script_filename),
|
|
|
|
script_filename,
|
|
|
|
dname ? dname : "",
|
|
|
|
file_count);
|
2014-02-09 19:27:51 +00:00
|
|
|
file_count++;
|
2014-03-26 06:24:51 +00:00
|
|
|
g_free(dirname);
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
if (first_time) {
|
|
|
|
/* at this point we're set up so register the init and cleanup routines */
|
|
|
|
register_init_routine(wslua_init_routine);
|
|
|
|
register_cleanup_routine(wslua_cleanup_routine);
|
|
|
|
}
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/*
|
|
|
|
* after this point it is too late to register a menu
|
|
|
|
* disable the function to avoid weirdness
|
|
|
|
*/
|
|
|
|
lua_pushcfunction(L, wslua_not_register_menu);
|
2012-06-25 20:28:14 +00:00
|
|
|
lua_setglobal(L, "register_menu");
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2006-09-25 01:09:00 +00:00
|
|
|
/* set up some essential globals */
|
|
|
|
lua_pinfo = NULL;
|
|
|
|
lua_tree = NULL;
|
|
|
|
lua_tvb = NULL;
|
2007-10-16 15:58:25 +00:00
|
|
|
|
2008-04-25 19:04:52 +00:00
|
|
|
Proto_commit(L);
|
2006-09-25 01:09:00 +00:00
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
first_time = FALSE;
|
|
|
|
}
|
|
|
|
|
2019-01-25 21:55:24 +00:00
|
|
|
void wslua_early_cleanup(void) {
|
|
|
|
wslua_deregister_protocols(L);
|
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
void wslua_reload_plugins (register_cb cb, gpointer client_data) {
|
|
|
|
const funnel_ops_t* ops = funnel_get_funnel_ops();
|
|
|
|
|
|
|
|
if (cb)
|
|
|
|
(*cb)(RA_LUA_DEREGISTER, NULL, client_data);
|
|
|
|
|
|
|
|
if (ops->close_dialogs)
|
|
|
|
ops->close_dialogs();
|
|
|
|
|
2016-03-11 19:54:26 +00:00
|
|
|
wslua_deregister_heur_dissectors(L);
|
2015-08-12 13:21:46 +00:00
|
|
|
wslua_deregister_protocols(L);
|
|
|
|
wslua_deregister_dissector_tables(L);
|
|
|
|
wslua_deregister_listeners(L);
|
2016-04-09 12:30:07 +00:00
|
|
|
wslua_deregister_fields(L);
|
2015-08-12 13:21:46 +00:00
|
|
|
wslua_deregister_filehandlers(L);
|
|
|
|
wslua_deregister_menus();
|
|
|
|
wslua_clear_plugin_list();
|
|
|
|
|
|
|
|
wslua_cleanup();
|
2015-08-11 12:08:08 +00:00
|
|
|
wslua_init(cb, client_data); /* reinitialize */
|
2006-09-25 01:09:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-11 12:08:08 +00:00
|
|
|
void wslua_cleanup(void) {
|
2013-10-23 16:47:02 +00:00
|
|
|
/* cleanup lua */
|
2015-08-11 12:08:08 +00:00
|
|
|
if (L) {
|
2015-06-04 17:30:35 +00:00
|
|
|
lua_close(L);
|
|
|
|
L = NULL;
|
|
|
|
}
|
2015-08-11 12:08:08 +00:00
|
|
|
init_routine_initialized = FALSE;
|
2013-10-23 16:47:02 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 22:18:32 +00:00
|
|
|
lua_State* wslua_state(void) { return L; }
|
2013-03-11 20:50:19 +00:00
|
|
|
|
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2013-03-11 20:50:19 +00:00
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
2016-02-25 21:34:07 +00:00
|
|
|
* tab-width: 8
|
2013-03-11 20:50:19 +00:00
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
2016-02-25 21:34:07 +00:00
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
2013-03-11 20:50:19 +00:00
|
|
|
*/
|