summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/README.wslua10
-rw-r--r--docbook/CMakeLists.txt14
-rw-r--r--docbook/Makefile.common14
-rwxr-xr-xdocbook/make-wsluarm.pl57
-rw-r--r--epan/wslua/CMakeLists.txt34
-rw-r--r--epan/wslua/Makefile.am55
-rw-r--r--epan/wslua/Makefile.nmake68
-rw-r--r--epan/wslua/wslua.h1
-rw-r--r--epan/wslua/wslua_address.c275
-rw-r--r--epan/wslua/wslua_byte_array.c410
-rw-r--r--epan/wslua/wslua_capture_info.c513
-rw-r--r--epan/wslua/wslua_column.c393
-rw-r--r--epan/wslua/wslua_dissector.c692
-rw-r--r--epan/wslua/wslua_file.c1966
-rw-r--r--epan/wslua/wslua_file_common.c205
-rw-r--r--epan/wslua/wslua_file_common.h86
-rw-r--r--epan/wslua/wslua_file_handler.c997
-rw-r--r--epan/wslua/wslua_frame_info.c415
-rw-r--r--epan/wslua/wslua_nstime.c210
-rw-r--r--epan/wslua/wslua_pinfo.c730
-rw-r--r--epan/wslua/wslua_pinfo_common.h35
-rw-r--r--epan/wslua/wslua_pref.c463
-rw-r--r--epan/wslua/wslua_proto.c2146
-rw-r--r--epan/wslua/wslua_proto_expert.c145
-rw-r--r--epan/wslua/wslua_proto_field.c997
-rw-r--r--epan/wslua/wslua_tvb.c555
26 files changed, 6166 insertions, 5320 deletions
diff --git a/doc/README.wslua b/doc/README.wslua
index 5bee84b090..74074904e3 100644
--- a/doc/README.wslua
+++ b/doc/README.wslua
@@ -289,6 +289,14 @@ to make new wslua files generate documentation, it is not sufficient to just
add this macro to a new file and add the file to the CMakeLists.txt; you also
have to add the module name into docbook/user-guide.xml, and docbook/wsluarm.xml.
+
+WSLUA_CONTINUE_MODULE - like WSLUA_MODULE, except used at the top of a .c file
+to continue defining classes/functions/etc. within a previously declared module
+in a previous file (i.e., one that used WSLUA_MODULE). The module name must match
+the original one, and the .c file must be listed after the original one in the
+CMakeLists.txt/Makefile.common lists in the docbook directory.
+
+
WSLUA_ATTRIBUTE - this is another documentation-only "macro", only used within
comments. It makes the API docs generate documentation for a member variable
of a class, i.e. a key of a Lua table that is not called as a function in Lua,
@@ -327,6 +335,7 @@ Example:
WSLUA_RETURN(1); /* A boolean: true if it is enabled, false if it isn't. */
}
+
WSLUA_CLASS_DEFINE - this is used to define/create a new Lua class type (i.e.,
table with methods). A Class name must begin with an uppercase letter,
followed by any upper or lower case letters but not underscores; in other
@@ -338,6 +347,7 @@ Example:
WSLUA_CLASS_DEFINE(ProgDlg,NOP,NOP); /* Manages a progress bar dialog. */
+
WSLUA_CONSTRUCTOR - this is used to define a function of a class that is a
static function rather than a per-object method; i.e., from a Lua perspective
the function is called as 'myObj.func()' instead of 'myObj:func()'. From a
diff --git a/docbook/CMakeLists.txt b/docbook/CMakeLists.txt
index e218bbc259..5c3164516b 100644
--- a/docbook/CMakeLists.txt
+++ b/docbook/CMakeLists.txt
@@ -255,6 +255,9 @@ set(WSDG_SOURCE
${WSDG_GRAPHICS}
)
+# Note: file order here MATTERS!
+# new WSLUA_MODULE files must come right before any WSLUA_CONTINUE_MODULE
+# files for the same module
set(WSLUA_MODULES
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_dumper.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_field.c
@@ -262,10 +265,21 @@ set(WSLUA_MODULES
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_int64.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_listener.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_pinfo.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_address.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_column.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_nstime.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_proto.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_dissector.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_pref.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_proto_expert.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_proto_field.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_tree.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_tvb.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_byte_array.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_file.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_file_handler.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_frame_info.c
+ ${CMAKE_SOURCE_DIR}/epan/wslua/wslua_capture_info.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_dir.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_util.c
${CMAKE_SOURCE_DIR}/epan/wslua/wslua_struct.c
diff --git a/docbook/Makefile.common b/docbook/Makefile.common
index 4c9e941334..a2edd2e393 100644
--- a/docbook/Makefile.common
+++ b/docbook/Makefile.common
@@ -253,18 +253,32 @@ CLEANDIRS = \
wsug_html_chunked \
wsluarm_src
+# Note: file order here MATTERS!
+# new WSLUA_MODULE files must come right before any WSLUA_CONTINUE_MODULE
+# files for the same module
WSLUA_MODULES = \
$(top_srcdir)/epan/wslua/wslua_dumper.c \
$(top_srcdir)/epan/wslua/wslua_field.c \
$(top_srcdir)/epan/wslua/wslua_gui.c \
$(top_srcdir)/epan/wslua/wslua_listener.c \
$(top_srcdir)/epan/wslua/wslua_pinfo.c \
+ $(top_srcdir)/epan/wslua/wslua_address.c \
+ $(top_srcdir)/epan/wslua/wslua_column.c \
+ $(top_srcdir)/epan/wslua/wslua_nstime.c \
$(top_srcdir)/epan/wslua/wslua_proto.c \
+ $(top_srcdir)/epan/wslua/wslua_dissector.c \
+ $(top_srcdir)/epan/wslua/wslua_pref.c \
+ $(top_srcdir)/epan/wslua/wslua_proto_expert.c \
+ $(top_srcdir)/epan/wslua/wslua_proto_field.c \
$(top_srcdir)/epan/wslua/wslua_int64.c \
$(top_srcdir)/epan/wslua/wslua_struct.c \
$(top_srcdir)/epan/wslua/wslua_tree.c \
$(top_srcdir)/epan/wslua/wslua_tvb.c \
+ $(top_srcdir)/epan/wslua/wslua_byte_array.c \
$(top_srcdir)/epan/wslua/wslua_file.c \
+ $(top_srcdir)/epan/wslua/wslua_file_handler.c \
+ $(top_srcdir)/epan/wslua/wslua_frame_info.c \
+ $(top_srcdir)/epan/wslua/wslua_capture_info.c \
$(top_srcdir)/epan/wslua/wslua_dir.c \
$(top_srcdir)/epan/wslua/wslua_util.c
diff --git a/docbook/make-wsluarm.pl b/docbook/make-wsluarm.pl
index 35f92a8644..4bba10b9c0 100755
--- a/docbook/make-wsluarm.pl
+++ b/docbook/make-wsluarm.pl
@@ -545,16 +545,19 @@ for (@control) {
$anymatch .= ')';
# for each file given in the command line args
-my $file;
-while ( $file = shift) {
+my $file = shift;
+my $docfile = 0;
- next unless -f $file;
+while ( $file ) {
- %module = ();
+ # continue to next loop if the file is not plain text
+ next unless -f $file;
- my $docfile = $file;
- $docfile =~ s#.*/##;
- $docfile =~ s/\.c$/.$out_extension/;
+ if (!$docfile) {
+ $docfile = $file;
+ $docfile =~ s#.*/##;
+ $docfile =~ s/\.c$/.$out_extension/;
+ }
open C, "< $file" or die "Can't open input file $file: $!";
open D, "> wsluarm_src/$docfile" or die "Can't open output file wsluarm_src/$docfile: $!";
@@ -562,6 +565,8 @@ while ( $file = shift) {
my $b = '';
$b .= $_ while (<C>);
+ close C;
+
while ($b =~ /$anymatch/ms ) {
my $match = $1;
# print "\n-----\n$match\n-----\n";
@@ -575,6 +580,34 @@ while ( $file = shift) {
}
}
+ # peek at next file to see if it's continuing this module
+ $file = shift;
+ # make sure we get the next plain text file
+ while ($file and !(-f $file)) {
+ $file = shift;
+ }
+
+ if ($file) {
+ # we have another file - check it out
+
+ open C, "< $file" or die "Can't open input file $file: $!";
+
+ my $peek_for_continue = '';
+ $peek_for_continue .= $_ while (<C>);
+
+ close C;
+
+ if ($peek_for_continue =~ /WSLUA_CONTINUE_MODULE\s*([A-Z][a-zA-Z0-9]+)/) {
+ if ($module{name} ne $1) {
+ die "Input file $file continues a different module: $1 (previous module is $module{name})!";
+ }
+ # ok, we're continuing the same module
+ next;
+ }
+ }
+
+ # if we got here, we're not continuing the module
+
$modules{$module{name}} = $docfile;
print "Generating source XML for: $module{name}\n";
@@ -640,15 +673,17 @@ while ( $file = shift) {
print D ${$template_ref}{global_functions_footer};
}
+ printf D ${$template_ref}{module_footer}, $module{name};
+
+ close D;
+
+ %module = ();
%classes = ();
$class = undef;
$function = undef;
@functions = ();
- close C;
+ $docfile = 0;
- printf D ${$template_ref}{module_footer}, $module{name};
-
- close D;
}
sub function_descr {
diff --git a/epan/wslua/CMakeLists.txt b/epan/wslua/CMakeLists.txt
index e3c2b75a2b..8669e101bb 100644
--- a/epan/wslua/CMakeLists.txt
+++ b/epan/wslua/CMakeLists.txt
@@ -20,24 +20,36 @@
#
set(WSLUA_MODULES
- ${CMAKE_CURRENT_SOURCE_DIR}/lua_bitop.c
${CMAKE_CURRENT_SOURCE_DIR}/lrexlib.c
${CMAKE_CURRENT_SOURCE_DIR}/lrexlib_glib.c
${CMAKE_CURRENT_SOURCE_DIR}/lrexlib_glib_f.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_int64.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_tvb.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_proto.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_tree.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_pinfo.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_listener.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_gui.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/lua_bitop.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_address.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_byte_array.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_capture_info.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_column.c
${CMAKE_CURRENT_SOURCE_DIR}/wslua_dir.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_util.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_dissector.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_dumper.c
${CMAKE_CURRENT_SOURCE_DIR}/wslua_field.c
${CMAKE_CURRENT_SOURCE_DIR}/wslua_file.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_struct.c
- ${CMAKE_CURRENT_SOURCE_DIR}/wslua_dumper.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_file_common.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_file_handler.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_frame_info.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_gui.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_int64.c
${CMAKE_CURRENT_SOURCE_DIR}/wslua_internals.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_listener.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_nstime.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_pinfo.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_pref.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_proto.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_proto_expert.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_proto_field.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_struct.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_tree.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_tvb.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wslua_util.c
)
set (WSLUA_MODULES ${WSLUA_MODULES} PARENT_SCOPE)
diff --git a/epan/wslua/Makefile.am b/epan/wslua/Makefile.am
index 9dd866f33f..fcc15450d2 100644
--- a/epan/wslua/Makefile.am
+++ b/epan/wslua/Makefile.am
@@ -27,25 +27,37 @@ AM_CPPFLAGS = -I$(top_srcdir) @LUA_CFLAGS@
noinst_LTLIBRARIES = libwslua.la
-wslua_modules = \
- lua_bitop.c \
- lrexlib.c \
- lrexlib_glib.c \
- lrexlib_glib_f.c \
- wslua_tvb.c \
- wslua_proto.c \
- wslua_int64.c \
- wslua_tree.c \
- wslua_pinfo.c \
- wslua_listener.c \
- wslua_gui.c \
- wslua_dir.c \
- wslua_util.c \
- wslua_field.c \
- wslua_file.c \
- wslua_struct.c \
- wslua_dumper.c \
- wslua_internals.c
+wslua_modules = \
+ lrexlib.c \
+ lrexlib_glib.c \
+ lrexlib_glib_f.c \
+ lua_bitop.c \
+ wslua_address.c \
+ wslua_byte_array.c \
+ wslua_capture_info.c \
+ wslua_column.c \
+ wslua_dir.c \
+ wslua_dissector.c \
+ wslua_dumper.c \
+ wslua_field.c \
+ wslua_file.c \
+ wslua_file_common.c \
+ wslua_file_handler.c \
+ wslua_frame_info.c \
+ wslua_gui.c \
+ wslua_int64.c \
+ wslua_internals.c \
+ wslua_listener.c \
+ wslua_nstime.c \
+ wslua_pinfo.c \
+ wslua_pref.c \
+ wslua_proto.c \
+ wslua_proto_expert.c \
+ wslua_proto_field.c \
+ wslua_struct.c \
+ wslua_tree.c \
+ wslua_tvb.c \
+ wslua_util.c
libwslua_la_SOURCES = \
$(wslua_modules) \
@@ -86,7 +98,10 @@ MAINTAINERCLEANFILES = \
EXTRA_DIST = \
declare_wslua.h \
lua_bitop.h \
- lrexlib.h \
+ lrexlib.h \
+ lrexlib_algo.h \
+ wslua_file_common.h \
+ wslua_pinfo_common.h \
lrexlib_algo.h \
register_wslua.c \
taps \
diff --git a/epan/wslua/Makefile.nmake b/epan/wslua/Makefile.nmake
index 9a8e9e344a..9ad3ac5c88 100644
--- a/epan/wslua/Makefile.nmake
+++ b/epan/wslua/Makefile.nmake
@@ -13,47 +13,71 @@ CFLAGS=$(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \
$(CC) $(CFLAGS) -Fd.\ -c $<
MODULES = \
- lua_bitop.c \
lrexlib.c \
lrexlib_glib.c \
lrexlib_glib_f.c \
- wslua_tvb.c \
- wslua_proto.c \
- wslua_int64.c \
- wslua_tree.c \
- wslua_pinfo.c \
- wslua_listener.c \
- wslua_gui.c \
+ lua_bitop.c \
+ wslua_address.c \
+ wslua_byte_array.c \
+ wslua_capture_info.c \
+ wslua_column.c \
wslua_dir.c \
- wslua_util.c \
+ wslua_dissector.c \
+ wslua_dumper.c \
wslua_field.c \
wslua_file.c \
+ wslua_file_common.c \
+ wslua_file_handler.c \
+ wslua_frame_info.c \
+ wslua_gui.c \
+ wslua_int64.c \
+ wslua_internals.c \
+ wslua_listener.c \
+ wslua_nstime.c \
+ wslua_pinfo.c \
+ wslua_pref.c \
+ wslua_proto.c \
+ wslua_proto_expert.c \
+ wslua_proto_field.c \
wslua_struct.c \
- wslua_dumper.c \
- wslua_internals.c
+ wslua_tree.c \
+ wslua_tvb.c \
+ wslua_util.c
OBJECTS= \
init_wslua.obj \
register_wslua.obj \
taps_wslua.obj \
- lua_bitop.obj \
lrexlib.obj \
lrexlib_glib.obj \
lrexlib_glib_f.obj \
- wslua_tvb.obj \
- wslua_proto.obj \
- wslua_int64.obj \
- wslua_tree.obj \
- wslua_pinfo.obj \
- wslua_listener.obj \
- wslua_gui.obj \
+ lua_bitop.obj \
+ wslua_address.obj \
+ wslua_byte_array.obj \
+ wslua_capture_info.obj \
+ wslua_column.obj \
wslua_dir.obj \
- wslua_util.obj \
+ wslua_dissector.obj \
+ wslua_dumper.obj \
wslua_field.obj \
wslua_file.obj \
+ wslua_file_common.obj \
+ wslua_file_handler.obj \
+ wslua_frame_info.obj \
+ wslua_gui.obj \
+ wslua_int64.obj \
+ wslua_internals.obj \
+ wslua_listener.obj \
+ wslua_nstime.obj \
+ wslua_pinfo.obj \
+ wslua_pref.obj \
+ wslua_proto.obj \
+ wslua_proto_expert.obj \
+ wslua_proto_field.obj \
wslua_struct.obj \
- wslua_dumper.obj \
- wslua_internals.obj
+ wslua_tree.obj \
+ wslua_tvb.obj \
+ wslua_util.obj
wslua.lib : $(OBJECTS) init.lua
link /lib /NODEFAULTLIB /out:wslua.lib $(OBJECTS)
diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h
index 18ea9d3019..268d498dd2 100644
--- a/epan/wslua/wslua.h
+++ b/epan/wslua/wslua.h
@@ -696,6 +696,7 @@ extern void UInt64_pack(lua_State* L, luaL_Buffer *b, gint idx, gboolean asLittl
extern int UInt64_unpack(lua_State* L, const gchar *buff, gboolean asLittleEndian);
extern Tvb* push_Tvb(lua_State* L, tvbuff_t* tvb);
+extern int push_wsluaTvb(lua_State* L, Tvb t);
extern gboolean push_TvbRange(lua_State* L, tvbuff_t* tvb, int offset, int len);
extern void clear_outstanding_Tvb(void);
extern void clear_outstanding_TvbRange(void);
diff --git a/epan/wslua/wslua_address.c b/epan/wslua/wslua_address.c
new file mode 100644
index 0000000000..eff8ddb488
--- /dev/null
+++ b/epan/wslua/wslua_address.c
@@ -0,0 +1,275 @@
+/*
+ * wslua_address.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+#include <epan/addr_resolv.h>
+
+/* WSLUA_CONTINUE_MODULE Pinfo */
+
+
+WSLUA_CLASS_DEFINE(Address,FAIL_ON_NULL("Address"),NOP); /* Represents an address. */
+
+WSLUA_CONSTRUCTOR Address_ip(lua_State* L) {
+ /* Creates an Address Object representing an IP address. */
+
+#define WSLUA_ARG_Address_ip_HOSTNAME 1 /* The address or name of the IP host. */
+ Address addr = (Address)g_malloc(sizeof(address));
+ guint32* ip_addr = (guint32 *)g_malloc(sizeof(guint32));
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Address_ip_HOSTNAME);
+
+ if (! get_host_ipaddr(name, (guint32*)ip_addr)) {
+ *ip_addr = 0;
+ }
+
+ SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
+ pushAddress(L,addr);
+ WSLUA_RETURN(1); /* The Address object. */
+}
+
+#if 0
+/* TODO */
+static int Address_ipv6(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_ss7(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_eth(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_sna(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_atalk(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_vines(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_osi(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_arcnet(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_fc(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_string(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_eui64(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_uri(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+static int Address_tipc(lua_State* L) {
+ Address addr = g_malloc(sizeof(address));
+
+ SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
+
+ pushAddress(L,addr);
+ return 1;
+}
+#endif
+
+WSLUA_METHODS Address_methods[] = {
+ WSLUA_CLASS_FNREG(Address,ip),
+ WSLUA_CLASS_FNREG_ALIAS(Address,ipv4,ip),
+#if 0
+ WSLUA_CLASS_FNREG(Address,ipv6),
+ WSLUA_CLASS_FNREG_ALIAS(Address,ss7pc,ss7),
+ WSLUA_CLASS_FNREG(Address,eth),
+ WSLUA_CLASS_FNREG(Address,sna},
+ WSLUA_CLASS_FNREG(Address,atalk),
+ WSLUA_CLASS_FNREG(Address,vines),
+ WSLUA_CLASS_FNREG(Address,osi),
+ WSLUA_CLASS_FNREG(Address,arcnet),
+ WSLUA_CLASS_FNREG(Address,fc),
+ WSLUA_CLASS_FNREG(Address,string),
+ WSLUA_CLASS_FNREG(Address,eui64),
+ WSLUA_CLASS_FNREG(Address,uri),
+ WSLUA_CLASS_FNREG(Address,tipc),
+#endif
+ { NULL, NULL }
+};
+
+WSLUA_METAMETHOD Address__tostring(lua_State* L) {
+ Address addr = checkAddress(L,1);
+ const gchar *str = address_to_display(NULL, addr);
+
+ lua_pushstring(L, str);
+
+ wmem_free(NULL, (void*) str);
+
+ WSLUA_RETURN(1); /* The string representing the address. */
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int Address__gc(lua_State* L) {
+ Address addr = toAddress(L,1);
+
+ if (addr) {
+ g_free((void*)(addr->data));
+ g_free((void*)(addr));
+ }
+
+ return 0;
+}
+
+WSLUA_METAMETHOD Address__eq(lua_State* L) { /* Compares two Addresses. */
+ Address addr1 = checkAddress(L,1);
+ Address addr2 = checkAddress(L,2);
+ gboolean result = FALSE;
+
+ if (ADDRESSES_EQUAL(addr1, addr2))
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD Address__le(lua_State* L) { /* Compares two Addresses. */
+ Address addr1 = checkAddress(L,1);
+ Address addr2 = checkAddress(L,2);
+ gboolean result = FALSE;
+
+ if (CMP_ADDRESS(addr1, addr2) <= 0)
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD Address__lt(lua_State* L) { /* Compares two Addresses. */
+ Address addr1 = checkAddress(L,1);
+ Address addr2 = checkAddress(L,2);
+ gboolean result = FALSE;
+
+ if (CMP_ADDRESS(addr1, addr2) < 0)
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_META Address_meta[] = {
+ WSLUA_CLASS_MTREG(Address,tostring),
+ WSLUA_CLASS_MTREG(Address,eq),
+ WSLUA_CLASS_MTREG(Address,le),
+ WSLUA_CLASS_MTREG(Address,lt),
+ { NULL, NULL }
+};
+
+
+int Address_register(lua_State *L) {
+ WSLUA_REGISTER_CLASS(Address);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_byte_array.c b/epan/wslua/wslua_byte_array.c
new file mode 100644
index 0000000000..53843f9407
--- /dev/null
+++ b/epan/wslua/wslua_byte_array.c
@@ -0,0 +1,410 @@
+/*
+ * wslua_byte_array.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+#include "wsutil/base64.h"
+
+
+/* WSLUA_CONTINUE_MODULE Tvb */
+
+
+WSLUA_CLASS_DEFINE(ByteArray,FAIL_ON_NULL("ByteArray"),NOP);
+
+WSLUA_CONSTRUCTOR ByteArray_new(lua_State* L) {
+ /* Creates a `ByteArray` object.
+
+ Starting in version 1.11.3, if the second argument is a boolean `true`,
+ then the first argyument is treated as a raw Lua string of bytes to use,
+ instead of a hexadecimal string.
+ */
+#define WSLUA_OPTARG_ByteArray_new_HEXBYTES 1 /* A string consisting of hexadecimal bytes like "00 B1 A2" or "1a2b3c4d". */
+#define WSLUA_OPTARG_ByteArray_new_SEPARATOR 2 /* A string separator between hex bytes/words (default=" "),
+ or if the boolean value `true` is used, then the first argument
+ is treated as raw binary data */
+ GByteArray* ba = g_byte_array_new();
+ const gchar* s;
+ size_t len = 0;
+ const gchar* sep = " ";
+ gboolean ishex = TRUE;
+
+ if (lua_gettop(L) >= 1) {
+ s = luaL_checklstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES,&len);
+
+ if (lua_gettop(L) >= 2) {
+ if (lua_type(L,2) == LUA_TBOOLEAN && lua_toboolean(L,2)) {
+ ishex = FALSE;
+ } else {
+ sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_new_SEPARATOR," ");
+ }
+ }
+
+ if (ishex) {
+ wslua_hex2bin(L, s, (guint)len, sep); /* this pushes a new string on top of stack */
+ s = luaL_checklstring(L, -1, &len); /* get the new binary string */
+ g_byte_array_append(ba,s,(guint)len); /* copy it into ByteArray */
+ lua_pop(L,1); /* pop the newly created string */
+ } else {
+ g_byte_array_append(ba,s,(guint)len);
+ }
+ }
+
+ pushByteArray(L,ba);
+
+ WSLUA_RETURN(1); /* The new ByteArray object. */
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int ByteArray__gc(lua_State* L) {
+ ByteArray ba = toByteArray(L,1);
+
+ if (!ba) return 0;
+
+ g_byte_array_free(ba,TRUE);
+ return 0;
+}
+
+WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
+ /* Concatenate two `ByteArrays`. */
+#define WSLUA_ARG_ByteArray__cat_FIRST 1 /* First array. */
+#define WSLUA_ARG_ByteArray__cat_SECOND 2 /* Second array. */
+
+ ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_FIRST);
+ ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_SECOND);
+ ByteArray ba;
+
+ ba = g_byte_array_new();
+ g_byte_array_append(ba,ba1->data,ba1->len);
+ g_byte_array_append(ba,ba2->data,ba2->len);
+
+ pushByteArray(L,ba);
+ WSLUA_RETURN(1); /* The new composite `ByteArray`. */
+}
+
+WSLUA_METAMETHOD ByteArray__eq(lua_State* L) {
+ /* Compares two ByteArray values.
+
+ @since 1.11.4
+ */
+#define WSLUA_ARG_ByteArray__eq_FIRST 1 /* First array. */
+#define WSLUA_ARG_ByteArray__eq_SECOND 2 /* Second array. */
+ ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_FIRST);
+ ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_SECOND);
+ gboolean result = FALSE;
+
+ if (ba1->len == ba2->len) {
+ if (memcmp(ba1->data, ba2->data, ba1->len) == 0)
+ result = TRUE;
+ }
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_METHOD ByteArray_prepend(lua_State* L) {
+ /* Prepend a `ByteArray` to this `ByteArray`. */
+#define WSLUA_ARG_ByteArray_prepend_PREPENDED 2 /* `ByteArray` to be prepended. */
+ ByteArray ba = checkByteArray(L,1);
+ ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_prepend_PREPENDED);
+
+ g_byte_array_prepend(ba,ba2->data,ba2->len);
+
+ return 0;
+}
+
+WSLUA_METHOD ByteArray_append(lua_State* L) {
+ /* Append a `ByteArray` to this `ByteArray`. */
+#define WSLUA_ARG_ByteArray_append_APPENDED 2 /* `ByteArray` to be appended. */
+ ByteArray ba = checkByteArray(L,1);
+ ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_append_APPENDED);
+
+ g_byte_array_append(ba,ba2->data,ba2->len);
+
+ return 0;
+}
+
+WSLUA_METHOD ByteArray_set_size(lua_State* L) {
+ /* Sets the size of a `ByteArray`, either truncating it or filling it with zeros. */
+#define WSLUA_ARG_ByteArray_set_size_SIZE 2 /* New size of the array. */
+
+ ByteArray ba = checkByteArray(L,1);
+ int siz = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_size_SIZE);
+ guint8* padding;
+
+ if (siz < 0) {
+ WSLUA_ERROR(ByteArray_set_size,"ByteArray size must be non-negative");
+ return 0;
+ }
+
+ if (ba->len >= (guint)siz) { /* truncate */
+ g_byte_array_set_size(ba,siz);
+ } else { /* fill */
+ padding = (guint8 *)g_malloc0(sizeof(guint8)*(siz - ba->len));
+ g_byte_array_append(ba,padding,siz - ba->len);
+ g_free(padding);
+ }
+ return 0;
+}
+
+WSLUA_METHOD ByteArray_set_index(lua_State* L) {
+ /* Sets the value of an index of a `ByteArray`. */
+#define WSLUA_ARG_ByteArray_set_index_INDEX 2 /* The position of the byte to be set. */
+#define WSLUA_ARG_ByteArray_set_index_VALUE 3 /* The char value to set [0-255]. */
+ ByteArray ba = checkByteArray(L,1);
+ int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_INDEX);
+ int v = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_VALUE);
+
+ if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
+ luaL_argerror(L,2,"bad index");
+ return 0;
+ }
+
+ if (idx < 0 || (guint)idx >= ba->len) {
+ luaL_argerror(L,2,"index out of range");
+ return 0;
+ }
+
+ if (v < 0 || v > 255) {
+ luaL_argerror(L,3,"Byte out of range");
+ return 0;
+ }
+
+ ba->data[idx] = (guint8)v;
+
+ return 0;
+}
+
+
+WSLUA_METHOD ByteArray_get_index(lua_State* L) {
+ /* Get the value of a byte in a `ByteArray`. */
+#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the byte to get. */
+ ByteArray ba = checkByteArray(L,1);
+ int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_get_index_INDEX);
+
+ if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
+ luaL_argerror(L,2,"bad index");
+ return 0;
+ }
+
+ if (idx < 0 || (guint)idx >= ba->len) {
+ luaL_argerror(L,2,"index out of range");
+ return 0;
+ }
+ lua_pushnumber(L,ba->data[idx]);
+
+ WSLUA_RETURN(1); /* The value [0-255] of the byte. */
+}
+
+WSLUA_METHOD ByteArray_len(lua_State* L) {
+ /* Obtain the length of a `ByteArray`. */
+ ByteArray ba = checkByteArray(L,1);
+
+ lua_pushnumber(L,(lua_Number)ba->len);
+
+ WSLUA_RETURN(1); /* The length of the `ByteArray`. */
+}
+
+WSLUA_METHOD ByteArray_subset(lua_State* L) {
+ /* Obtain a segment of a `ByteArray`, as a new `ByteArray`. */
+#define WSLUA_ARG_ByteArray_set_index_OFFSET 2 /* The position of the first byte (0=first). */
+#define WSLUA_ARG_ByteArray_set_index_LENGTH 3 /* The length of the segment. */
+ ByteArray ba = checkByteArray(L,1);
+ int offset = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_OFFSET);
+ int len = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_LENGTH);
+ ByteArray sub;
+
+ if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+
+ sub = g_byte_array_new();
+ g_byte_array_append(sub,ba->data + offset,len);
+
+ pushByteArray(L,sub);
+
+ WSLUA_RETURN(1); /* A `ByteArray` containing the requested segment. */
+}
+
+WSLUA_METHOD ByteArray_base64_decode(lua_State* L) {
+ /* Obtain a base64 decoded `ByteArray`.
+
+ @since 1.11.3
+ */
+ ByteArray ba = checkByteArray(L,1);
+ ByteArray ba2;
+ gchar *data;
+ size_t len;
+
+ ba2 = g_byte_array_new();
+ data = (gchar*)g_malloc (ba->len + 1);
+ memcpy(data, ba->data, ba->len);
+ data[ba->len] = '\0';
+
+ len = ws_base64_decode_inplace(data);
+ g_byte_array_append(ba2,data,(int)len);
+ g_free(data);
+
+ pushByteArray(L,ba2);
+ WSLUA_RETURN(1); /* The created `ByteArray`. */
+}
+
+WSLUA_METHOD ByteArray_raw(lua_State* L) {
+ /* Obtain a Lua string of the binary bytes in a `ByteArray`.
+
+ @since 1.11.3
+ */
+#define WSLUA_OPTARG_ByteArray_raw_OFFSET 2 /* The position of the first byte (default=0/first). */
+#define WSLUA_OPTARG_ByteArray_raw_LENGTH 3 /* The length of the segment to get (default=all). */
+ ByteArray ba = checkByteArray(L,1);
+ guint offset = (guint) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_OFFSET,0);
+ int len;
+
+ if (!ba) return 0;
+ if (offset > ba->len) {
+ WSLUA_OPTARG_ERROR(ByteArray_raw,OFFSET,"offset beyond end of byte array");
+ return 0;
+ }
+
+ len = (int) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_LENGTH, ba->len - offset);
+ if ((len < 0) || ((guint)len > (ba->len - offset)))
+ len = ba->len - offset;
+
+ lua_pushlstring(L, &(ba->data[offset]), len);
+
+ WSLUA_RETURN(1); /* A Lua string of the binary bytes in the ByteArray. */
+}
+
+WSLUA_METHOD ByteArray_tohex(lua_State* L) {
+ /* Obtain a Lua string of the bytes in a `ByteArray` as hex-ascii, with given separator
+
+ @since 1.11.3
+ */
+#define WSLUA_OPTARG_ByteArray_tohex_LOWERCASE 2 /* True to use lower-case hex characters (default=false). */
+#define WSLUA_OPTARG_ByteArray_tohex_SEPARATOR 3 /* A string separator to insert between hex bytes (default=nil). */
+ ByteArray ba = checkByteArray(L,1);
+ gboolean lowercase = FALSE;
+ const gchar* sep = NULL;
+
+ if (!ba) return 0;
+
+ lowercase = wslua_optbool(L,WSLUA_OPTARG_ByteArray_tohex_LOWERCASE,FALSE);
+ sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_tohex_SEPARATOR,NULL);
+
+ wslua_bin2hex(L, ba->data, ba->len, lowercase, sep);
+
+ WSLUA_RETURN(1); /* A hex-ascii string representation of the `ByteArray`. */
+}
+
+WSLUA_METAMETHOD ByteArray__tostring(lua_State* L) {
+ /* Obtain a Lua string containing the bytes in a `ByteArray` so that it can be used in
+ display filters (e.g. "01FE456789AB"). */
+ ByteArray ba = checkByteArray(L,1);
+
+ if (!ba) return 0;
+
+ wslua_bin2hex(L, ba->data, ba->len, FALSE, NULL);
+
+ WSLUA_RETURN(1); /* A hex-ascii string representation of the `ByteArray`. */
+}
+
+/*
+ * ByteArray_tvb(name)
+ */
+WSLUA_CONSTRUCTOR ByteArray_tvb (lua_State *L) {
+ /* Creates a new `Tvb` from a `ByteArray` (it gets added to the current frame too). */
+#define WSLUA_ARG_ByteArray_tvb_NAME 2 /* The name to be given to the new data-source. */
+ ByteArray ba = checkByteArray(L,1);
+ const gchar* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Unnamed") ;
+ guint8* data;
+ Tvb tvb;
+
+ if (!lua_tvb) {
+ luaL_error(L,"Tvbs can only be created and used in dissectors");
+ return 0;
+ }
+
+ data = (guint8 *)g_memdup(ba->data, ba->len);
+
+ tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
+ tvb->ws_tvb = tvb_new_real_data(data, ba->len,ba->len);
+ tvb->expired = FALSE;
+ tvb->need_free = TRUE;
+ tvb_set_free_cb(tvb->ws_tvb, g_free);
+
+ add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
+ push_wsluaTvb(L,tvb);
+ WSLUA_RETURN(1); /* The created `Tvb`. */
+}
+
+
+WSLUA_METHODS ByteArray_methods[] = {
+ WSLUA_CLASS_FNREG(ByteArray,new),
+ WSLUA_CLASS_FNREG(ByteArray,len),
+ WSLUA_CLASS_FNREG(ByteArray,prepend),
+ WSLUA_CLASS_FNREG(ByteArray,append),
+ WSLUA_CLASS_FNREG(ByteArray,subset),
+ WSLUA_CLASS_FNREG(ByteArray,set_size),
+ WSLUA_CLASS_FNREG(ByteArray,tvb),
+ WSLUA_CLASS_FNREG(ByteArray,base64_decode),
+ WSLUA_CLASS_FNREG(ByteArray,get_index),
+ WSLUA_CLASS_FNREG(ByteArray,set_index),
+ WSLUA_CLASS_FNREG(ByteArray,tohex),
+ WSLUA_CLASS_FNREG(ByteArray,raw),
+ { NULL, NULL }
+};
+
+WSLUA_META ByteArray_meta[] = {
+ WSLUA_CLASS_MTREG(ByteArray,tostring),
+ WSLUA_CLASS_MTREG(ByteArray,concat),
+ WSLUA_CLASS_MTREG(ByteArray,eq),
+ {"__call",ByteArray_subset},
+ { NULL, NULL }
+};
+
+int ByteArray_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(ByteArray);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_capture_info.c b/epan/wslua/wslua_capture_info.c
new file mode 100644
index 0000000000..eb83a94089
--- /dev/null
+++ b/epan/wslua/wslua_capture_info.c
@@ -0,0 +1,513 @@
+/*
+ * wslua_capture_info.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ * for capture file data and meta-data.
+ *
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "wslua_file_common.h"
+
+#include <epan/addr_resolv.h>
+
+
+/* WSLUA_CONTINUE_MODULE File */
+
+
+WSLUA_CLASS_DEFINE(CaptureInfo,FAIL_ON_NULL_MEMBER_OR_EXPIRED("CaptureInfo",wth),NOP);
+/*
+ A `CaptureInfo` object, passed into Lua as an argument by `FileHandler` callback
+ function `read_open()`, `read()`, `seek_read()`, `seq_read_close()`, and `read_close()`.
+ This object represents capture file data and meta-data (data about the
+ capture file) being read into Wireshark/Tshark.
+
+ This object's fields can be written-to by Lua during the read-based function callbacks.
+ In other words, when the Lua plugin's `FileHandler.read_open()` function is invoked, a
+ `CaptureInfo` object will be passed in as one of the arguments, and its fields
+ should be written to by your Lua code to tell Wireshark about the capture.
+
+ @since 1.11.3
+ */
+
+CaptureInfo* push_CaptureInfo(lua_State* L, wtap *wth, const gboolean first_time) {
+ CaptureInfo f = (CaptureInfo) g_malloc0(sizeof(struct _wslua_captureinfo));
+ f->wth = wth;
+ f->wdh = NULL;
+ f->expired = FALSE;
+
+ if (first_time) {
+ /* XXX: need to do this? */
+ wth->file_encap = WTAP_ENCAP_UNKNOWN;
+ wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
+ wth->snapshot_length = 0;
+ }
+
+ return pushCaptureInfo(L,f);
+}
+
+WSLUA_METAMETHOD CaptureInfo__tostring(lua_State* L) {
+ /* Generates a string of debug info for the CaptureInfo */
+ CaptureInfo fi = toCaptureInfo(L,1);
+
+ if (!fi || !fi->wth) {
+ lua_pushstring(L,"CaptureInfo pointer is NULL!");
+ } else {
+ wtap *wth = fi->wth;
+ lua_pushfstring(L, "CaptureInfo: file_type_subtype=%d, snapshot_length=%d, pkt_encap=%d, file_tsprec='%s'",
+ wth->file_type_subtype, wth->snapshot_length, wth->phdr.pkt_encap, wth->file_tsprec);
+ }
+
+ WSLUA_RETURN(1); /* String of debug information. */
+}
+
+
+static int CaptureInfo__gc(lua_State* L _U_) {
+ CaptureInfo fc = toCaptureInfo(L,1);
+ if (fc)
+ g_free(fc);
+ return 0;
+}
+
+/* WSLUA_ATTRIBUTE CaptureInfo_encap RW The packet encapsulation type for the whole file.
+
+ See `wtap_encaps` in `init.lua` for available types. Set to `wtap_encaps.PER_PACKET` if packets can
+ have different types, then later set `FrameInfo.encap` for each packet during `read()`/`seek_read()`.
+ */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,encap,wth->file_encap);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,encap,wth->file_encap,int);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_time_precision RW The precision of the packet timestamps in the file.
+
+ See `wtap_file_tsprec` in `init.lua` for available precisions.
+ */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,time_precision,wth->file_tsprec);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,time_precision,wth->file_tsprec,int);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_snapshot_length RW The maximum packet length that could be recorded.
+
+ Setting it to `0` means unknown. Wireshark cannot handle anything bigger than 65535 bytes.
+ */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,snapshot_length,wth->snapshot_length);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,snapshot_length,wth->snapshot_length,guint);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_comment RW A string comment for the whole capture file,
+ or nil if there is no `comment`. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment,TRUE);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_hardware RW A string containing the description of
+ the hardware used to create the capture, or nil if there is no `hardware` string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware,TRUE);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_os RW A string containing the name of
+ the operating system used to create the capture, or nil if there is no `os` string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,os,wth->shb_hdr.shb_os);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,os,wth->shb_hdr.shb_os,TRUE);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_user_app RW A string containing the name of
+ the application used to create the capture, or nil if there is no `user_app` string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl,TRUE);
+
+/* WSLUA_ATTRIBUTE CaptureInfo_hosts WO Sets resolved ip-to-hostname information.
+
+ The value set must be a Lua table of two key-ed names: `ipv4_addresses` and `ipv6_addresses`.
+ The value of each of these names are themselves array tables, of key-ed tables, such that the inner table has a key
+ `addr` set to the raw 4-byte or 16-byte IP address Lua string and a `name` set to the resolved name.
+
+ For example, if the capture file identifies one resolved IPv4 address of 1.2.3.4 to `foo.com`, then you must set
+ `CaptureInfo.hosts` to a table of:
+ @code { ipv4_addresses = { { addr = "\01\02\03\04", name = "foo.com" } } } @endcode
+
+ Note that either the `ipv4_addresses` or the `ipv6_addresses` table, or both, may be empty or nil.
+ */
+static int CaptureInfo_set_hosts(lua_State* L) {
+ CaptureInfo fi = checkCaptureInfo(L,1);
+ wtap *wth = fi->wth;
+ const char *addr = NULL;
+ const char *name = NULL;
+ size_t addr_len = 0;
+ size_t name_len = 0;
+ guint32 v4_addr = 0;
+ struct e_in6_addr v6_addr = { {0} };
+
+ if (!wth->add_new_ipv4 || !wth->add_new_ipv6) {
+ return luaL_error(L, "CaptureInfo wtap has no IPv4 or IPv6 name resolution");
+ }
+
+ if (!lua_istable(L,-1)) {
+ return luaL_error(L, "CaptureInfo.host must be set to a table");
+ }
+
+ /* get the ipv4_addresses table */
+ lua_getfield(L, -1, "ipv4_addresses");
+
+ if (lua_istable(L,-1)) {
+ /* now walk the table */
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ /* 'key' (at index -2) and 'value' (at index -1) */
+ if (!lua_istable(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv4_addresses table does not contain a table");
+ }
+
+ lua_getfield(L, -1, "addr");
+ if (!lua_isstring(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv4_addresses table's table does not contain an 'addr' field");
+ }
+ addr = luaL_checklstring(L,-1,&addr_len);
+ if (addr_len != 4) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv4_addresses 'addr' value is not 4 bytes long");
+ }
+ memcpy(&v4_addr, addr, 4);
+
+ lua_getfield(L, -1, "name");
+ if (!lua_isstring(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv4_addresses table's table does not contain an 'addr' field");
+ }
+ name = luaL_checklstring(L,-1,&name_len);
+
+ wth->add_new_ipv4(v4_addr, name);
+
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+ }
+
+ /* wasn't a table, or it was and we walked it; either way pop it */
+ lua_pop(L,1);
+
+
+ /* get the ipv6_addresses table */
+ lua_getfield(L, -1, "ip6_addresses");
+
+ if (lua_istable(L,-1)) {
+ /* now walk the table */
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ /* 'key' (at index -2) and 'value' (at index -1) */
+ if (!lua_istable(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv6_addresses table does not contain a table");
+ }
+
+ lua_getfield(L, -1, "addr");
+ if (!lua_isstring(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv6_addresses table's table does not contain an 'addr' field");
+ }
+ addr = luaL_checklstring(L,-1,&addr_len);
+ if (addr_len != 16) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv6_addresses 'addr' value is not 16 bytes long");
+ }
+ memcpy(&v6_addr, addr, 16);
+
+ lua_getfield(L, -1, "name");
+ if (!lua_isstring(L,-1)) {
+ lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
+ return luaL_error(L, "CaptureInfo.host ipv6_addresses table's table does not contain an 'addr' field");
+ }
+ name = luaL_checklstring(L,-1,&name_len);
+
+ wth->add_new_ipv6((const void *)(&v6_addr), name);
+
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+ }
+
+ /* wasn't a table, or it was and we walked it; either way pop it */
+ lua_pop(L,1);
+
+ return 0;
+}
+
+
+/* WSLUA_ATTRIBUTE CaptureInfo_private_table RW A private Lua value unique to this file.
+
+ The `private_table` is a field you set/get with your own Lua table.
+ This is provided so that a Lua script can save per-file reading/writing
+ state, because multiple files can be opened and read at the same time.
+
+ For example, if the user issued a reload-file command, or Lua called the
+ `reload()` function, then the current capture file is still open while a new one
+ is being opened, and thus Wireshark will invoke `read_open()` while the previous
+ capture file has not caused `read_close()` to be called; and if the `read_open()`
+ succeeds then `read_close()` will be called right after that for the previous
+ file, rather than the one just opened. Thus the Lua script can use this
+ `private_table` to store a table of values specific to each file, by setting
+ this `private_table` in the `read_open()` function, which it can then later get back
+ inside its `read()`, `seek_read()`, and `read_close()` functions.
+*/
+static int CaptureInfo_get_private_table(lua_State* L) {
+ CaptureInfo fi = checkCaptureInfo(L,1);
+ return get_wth_priv_table_ref(L, fi->wth);
+}
+
+static int CaptureInfo_set_private_table(lua_State* L) {
+ CaptureInfo fi = checkCaptureInfo(L,1);
+ return set_wth_priv_table_ref(L, fi->wth);
+}
+
+WSLUA_ATTRIBUTES CaptureInfo_attributes[] = {
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,encap),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,time_precision),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,snapshot_length),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,comment),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,hardware),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,os),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,user_app),
+ WSLUA_ATTRIBUTE_WOREG(CaptureInfo,hosts),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfo,private_table),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_META CaptureInfo_meta[] = {
+ WSLUA_CLASS_MTREG(CaptureInfo,tostring),
+ { NULL, NULL }
+};
+
+int CaptureInfo_register(lua_State* L) {
+ WSLUA_REGISTER_META(CaptureInfo);
+ WSLUA_REGISTER_ATTRIBUTES(CaptureInfo);
+ return 0;
+}
+
+
+WSLUA_CLASS_DEFINE(CaptureInfoConst,FAIL_ON_NULL_MEMBER_OR_EXPIRED("CaptureInfoConst",wdh),NOP);
+/*
+ A `CaptureInfoConst` object, passed into Lua as an argument to the `FileHandler` callback
+ function `write_open()`.
+
+ This object represents capture file data and meta-data (data about the
+ capture file) for the current capture in Wireshark/Tshark.
+
+ This object's fields are read-from when used by `write_open` function callback.
+ In other words, when the Lua plugin's FileHandler `write_open` function is invoked, a
+ `CaptureInfoConst` object will be passed in as one of the arguments, and its fields
+ should be read from by your Lua code to get data about the capture that needs to be written.
+
+ @since 1.11.3
+ */
+
+CaptureInfoConst* push_CaptureInfoConst(lua_State* L, wtap_dumper *wdh) {
+ CaptureInfoConst f = (CaptureInfoConst) g_malloc0(sizeof(struct _wslua_captureinfo));
+ f->wth = NULL;
+ f->wdh = wdh;
+ f->expired = FALSE;
+ return pushCaptureInfoConst(L,f);
+}
+
+WSLUA_METAMETHOD CaptureInfoConst__tostring(lua_State* L) {
+ /* Generates a string of debug info for the CaptureInfoConst */
+ CaptureInfoConst fi = toCaptureInfoConst(L,1);
+
+ if (!fi || !fi->wdh) {
+ lua_pushstring(L,"CaptureInfoConst pointer is NULL!");
+ } else {
+ wtap_dumper *wdh = fi->wdh;
+ lua_pushfstring(L, "CaptureInfoConst: file_type_subtype=%d, snaplen=%d, encap=%d, compressed=%d, file_tsprec='%s'",
+ wdh->file_type_subtype, wdh->snaplen, wdh->encap, wdh->compressed, wdh->tsprecision);
+ }
+
+ WSLUA_RETURN(1); /* String of debug information. */
+}
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_type RO The file type. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,type,wdh->file_type_subtype);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_snapshot_length RO The maximum packet length that is actually recorded (vs. the original
+ length of any given packet on-the-wire). A value of `0` means the snapshot length is unknown or there is no one
+ such length for the whole file. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,snapshot_length,wdh->snaplen);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_encap RO The packet encapsulation type for the whole file.
+
+ See `wtap_encaps` in init.lua for available types. It is set to `wtap_encaps.PER_PACKET` if packets can
+ have different types, in which case each Frame identifies its type, in `FrameInfo.packet_encap`. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,encap,wdh->encap);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_comment RW A comment for the whole capture file, if the
+ `wtap_presence_flags.COMMENTS` was set in the presence flags; nil if there is no comment. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,comment,wth->shb_hdr.opt_comment);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_hardware RO A string containing the description of
+ the hardware used to create the capture, or nil if there is no hardware string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,hardware,wth->shb_hdr.shb_hardware);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_os RO A string containing the name of
+ the operating system used to create the capture, or nil if there is no os string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,os,wth->shb_hdr.shb_os);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_user_app RO A string containing the name of
+ the application used to create the capture, or nil if there is no user_app string. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,user_app,wth->shb_hdr.shb_user_appl);
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_hosts RO A ip-to-hostname Lua table of two key-ed names: `ipv4_addresses` and `ipv6_addresses`.
+ The value of each of these names are themselves array tables, of key-ed tables, such that the inner table has a key
+ `addr` set to the raw 4-byte or 16-byte IP address Lua string and a `name` set to the resolved name.
+
+ For example, if the current capture has one resolved IPv4 address of 1.2.3.4 to `foo.com`, then getting
+ `CaptureInfoConst.hosts` will get a table of:
+ @code { ipv4_addresses = { { addr = "\01\02\03\04", name = "foo.com" } }, ipv6_addresses = { } } @endcode
+
+ Note that either the `ipv4_addresses` or the `ipv6_addresses` table, or both, may be empty, however they will not
+ be nil. */
+static int CaptureInfoConst_get_hosts(lua_State* L) {
+ CaptureInfoConst fi = checkCaptureInfoConst(L,1);
+ wtap_dumper *wdh = fi->wdh;
+
+ /* create the main table to return */
+ lua_newtable(L);
+
+ /* create the ipv4_addresses table */
+ lua_newtable(L);
+
+ if (wdh->addrinfo_lists && wdh->addrinfo_lists->ipv4_addr_list) {
+ hashipv4_t *ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, 0);
+ int i, j;
+ for (i=1, j=1; ipv4_hash_list_entry != NULL; i++) {
+ if ((ipv4_hash_list_entry->flags & USED_AND_RESOLVED_MASK) == RESOLVED_ADDRESS_USED) {
+ lua_pushnumber(L, j); /* push numeric index key starting at 1, so it will be an array table */
+ /* create the entry table */
+ lua_newtable(L);
+ /* addr is in network order already */
+ lua_pushlstring(L, (char*)(&ipv4_hash_list_entry->ip), 4);
+ lua_setfield(L, -2, "addr");
+ lua_pushstring(L, ipv4_hash_list_entry->name);
+ lua_setfield(L, -2, "name");
+ /* now our ipv4_addresses table is at -3, key number is -2, and entry table at -2, so we're good */
+ lua_settable(L, -3);
+ j++;
+ }
+ ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
+ }
+ }
+
+ /* set the (possibly empty) ipv4_addresses table into the main table */
+ lua_setfield(L, -2, "ipv4_addresses");
+
+ /* create the ipv6_addresses table */
+ lua_newtable(L);
+
+ if (wdh->addrinfo_lists && wdh->addrinfo_lists->ipv6_addr_list) {
+ hashipv6_t *ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, 0);
+ int i, j;
+ for (i=1, j=1; ipv6_hash_list_entry != NULL; i++) {
+ if ((ipv6_hash_list_entry->flags & USED_AND_RESOLVED_MASK) == RESOLVED_ADDRESS_USED) {
+ lua_pushnumber(L, j); /* push numeric index key starting at 1, so it will be an array table */
+ /* create the entry table */
+ lua_newtable(L);
+ /* addr is in network order already */
+ lua_pushlstring(L, (char*)(&ipv6_hash_list_entry->addr.bytes[0]), 16);
+ lua_setfield(L, -2, "addr");
+ lua_pushstring(L, ipv6_hash_list_entry->name);
+ lua_setfield(L, -2, "name");
+ /* now our ipv6_addresses table is at -3, key number is -2, and entry table at -2, so we're good */
+ lua_settable(L, -3);
+ j++;
+ }
+ ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
+ }
+ }
+
+ /* set the (possibly empty) ipv6_addresses table into the main table */
+ lua_setfield(L, -2, "ip6_addresses");
+
+ /* return the main table */
+ return 1;
+}
+
+/* WSLUA_ATTRIBUTE CaptureInfoConst_private_table RW A private Lua value unique to this file.
+
+ The `private_table` is a field you set/get with your own Lua table.
+ This is provided so that a Lua script can save per-file reading/writing
+ state, because multiple files can be opened and read at the same time.
+
+ For example, if two Lua scripts issue a `Dumper:new_for_current()` call and the
+ current file happens to use your script's writer, then the Wireshark will invoke
+ `write_open()` while the previous capture file has not had `write_close()` called.
+ Thus the Lua script can use this `private_table` to store a table of values
+ specific to each file, by setting this `private_table` in the write_open()
+ function, which it can then later get back inside its `write()`, and `write_close()`
+ functions.
+*/
+static int CaptureInfoConst_get_private_table(lua_State* L) {
+ CaptureInfoConst fi = checkCaptureInfoConst(L,1);
+ return get_wdh_priv_table_ref(L, fi->wdh);
+}
+
+static int CaptureInfoConst_set_private_table(lua_State* L) {
+ CaptureInfoConst fi = checkCaptureInfoConst(L,1);
+ return set_wdh_priv_table_ref(L, fi->wdh);
+}
+
+static int CaptureInfoConst__gc(lua_State* L _U_) {
+ CaptureInfoConst fi = toCaptureInfoConst(L,1);
+ if (fi)
+ g_free(fi);
+ return 0;
+}
+
+WSLUA_ATTRIBUTES CaptureInfoConst_attributes[] = {
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,encap),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,type),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,snapshot_length),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,comment),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,hardware),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,os),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,user_app),
+ WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,hosts),
+ WSLUA_ATTRIBUTE_RWREG(CaptureInfoConst,private_table),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_META CaptureInfoConst_meta[] = {
+ WSLUA_CLASS_MTREG(CaptureInfoConst,tostring),
+ { NULL, NULL }
+};
+
+int CaptureInfoConst_register(lua_State* L) {
+ WSLUA_REGISTER_META(CaptureInfoConst);
+ WSLUA_REGISTER_ATTRIBUTES(CaptureInfoConst);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_column.c b/epan/wslua/wslua_column.c
new file mode 100644
index 0000000000..2a1e781c3d
--- /dev/null
+++ b/epan/wslua/wslua_column.c
@@ -0,0 +1,393 @@
+/*
+ * wslua_column.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "wslua_pinfo_common.h"
+
+
+/* WSLUA_CONTINUE_MODULE Pinfo */
+
+
+static GPtrArray* outstanding_Column = NULL;
+static GPtrArray* outstanding_Columns = NULL;
+
+CLEAR_OUTSTANDING(Column,expired, TRUE)
+CLEAR_OUTSTANDING(Columns,expired, TRUE)
+
+#define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
+
+void Push_Columns(lua_State *L, Columns c)
+{
+ g_ptr_array_add(outstanding_Columns, c);
+ pushColumns(L, c);
+}
+
+
+WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("Column"),NOP); /* A Column in the packet list. */
+
+struct col_names_t {
+ const gchar* name;
+ int id;
+};
+
+static const struct col_names_t colnames[] = {
+ {"number",COL_NUMBER},
+ {"abs_time",COL_ABS_TIME},
+ {"utc_time",COL_UTC_TIME},
+ {"cls_time",COL_CLS_TIME},
+ {"rel_time",COL_REL_TIME},
+ {"date",COL_ABS_YMD_TIME},
+ {"date_doy",COL_ABS_YDOY_TIME},
+ {"utc_date",COL_UTC_YMD_TIME},
+ {"utc_date_doy",COL_UTC_YDOY_TIME},
+ {"delta_time",COL_DELTA_TIME},
+ {"delta_time_displayed",COL_DELTA_TIME_DIS},
+ {"src",COL_DEF_SRC},
+ {"src_res",COL_RES_SRC},
+ {"src_unres",COL_UNRES_SRC},
+ {"dl_src",COL_DEF_DL_SRC},
+ {"dl_src_res",COL_RES_DL_SRC},
+ {"dl_src_unres",COL_UNRES_DL_SRC},
+ {"net_src",COL_DEF_NET_SRC},
+ {"net_src_res",COL_RES_NET_SRC},
+ {"net_src_unres",COL_UNRES_NET_SRC},
+ {"dst",COL_DEF_DST},
+ {"dst_res",COL_RES_DST},
+ {"dst_unres",COL_UNRES_DST},
+ {"dl_dst",COL_DEF_DL_DST},
+ {"dl_dst_res",COL_RES_DL_DST},
+ {"dl_dst_unres",COL_UNRES_DL_DST},
+ {"net_dst",COL_DEF_NET_DST},
+ {"net_dst_res",COL_RES_NET_DST},
+ {"net_dst_unres",COL_UNRES_NET_DST},
+ {"src_port",COL_DEF_SRC_PORT},
+ {"src_port_res",COL_RES_SRC_PORT},
+ {"src_port_unres",COL_UNRES_SRC_PORT},
+ {"dst_port",COL_DEF_DST_PORT},
+ {"dst_port_res",COL_RES_DST_PORT},
+ {"dst_port_unres",COL_UNRES_DST_PORT},
+ {"protocol",COL_PROTOCOL},
+ {"info",COL_INFO},
+ {"packet_len",COL_PACKET_LENGTH},
+ {"cumulative_bytes",COL_CUMULATIVE_BYTES},
+ {"direction",COL_IF_DIR},
+ {"vsan",COL_VSAN},
+ {"tx_rate",COL_TX_RATE},
+ {"rssi",COL_RSSI},
+ {"dce_call",COL_DCE_CALL},
+ {NULL,0}
+};
+
+static gint col_name_to_id(const gchar* name) {
+ const struct col_names_t* cn;
+ for(cn = colnames; cn->name; cn++) {
+ if (g_str_equal(cn->name,name)) {
+ return cn->id;
+ }
+ }
+
+ return 0;
+}
+
+static const gchar* col_id_to_name(gint id) {
+ const struct col_names_t* cn;
+ for(cn = colnames; cn->name; cn++) {
+ if ( cn->id == id ) {
+ return cn->name;
+ }
+ }
+ return NULL;
+}
+
+
+WSLUA_METAMETHOD Column__tostring(lua_State *L) {
+ Column c = checkColumn(L,1);
+ const gchar* text;
+
+ if (!c->cinfo) {
+ text = col_id_to_name(c->col);
+ lua_pushfstring(L, "(%s)", text ? text : "unknown");
+ }
+ else {
+ text = col_get_text(c->cinfo, c->col);
+ lua_pushstring(L, text ? text : "(nil)");
+ }
+
+ WSLUA_RETURN(1); /* The column's string text (in parenthesis if not available). */
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS */
+static int Column__gc(lua_State* L) {
+ Column col = toColumn(L,1);
+
+ if (!col) return 0;
+
+ if (!col->expired)
+ col->expired = TRUE;
+ else
+ g_free(col);
+
+ return 0;
+
+}
+
+WSLUA_METHOD Column_clear(lua_State *L) {
+ /* Clears a Column. */
+ Column c = checkColumn(L,1);
+
+ if (!(c->cinfo)) return 0;
+
+ col_clear(c->cinfo, c->col);
+
+ return 0;
+}
+
+WSLUA_METHOD Column_set(lua_State *L) {
+ /* Sets the text of a Column. */
+#define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column. */
+ Column c = checkColumn(L,1);
+ const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
+
+ if (!(c->cinfo))
+ return 0;
+
+ col_add_str(c->cinfo, c->col, s);
+
+ return 0;
+}
+
+WSLUA_METHOD Column_append(lua_State *L) {
+ /* Appends text to a Column. */
+#define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column. */
+ Column c = checkColumn(L,1);
+ const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
+
+ if (!(c->cinfo))
+ return 0;
+
+ col_append_str(c->cinfo, c->col, s);
+
+ return 0;
+}
+
+WSLUA_METHOD Column_prepend(lua_State *L) {
+ /* Prepends text to a Column. */
+#define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column. */
+ Column c = checkColumn(L,1);
+ const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
+
+ if (!(c->cinfo))
+ return 0;
+
+ col_prepend_fstr(c->cinfo, c->col, "%s",s);
+
+ return 0;
+}
+
+WSLUA_METHOD Column_fence(lua_State *L) {
+ /* Sets Column text fence, to prevent overwriting.
+
+ @since 1.10.6
+ */
+ Column c = checkColumn(L,1);
+
+ if (c->cinfo)
+ col_set_fence(c->cinfo, c->col);
+
+ return 0;
+}
+
+WSLUA_METHOD Column_clear_fence(lua_State *L) {
+ /* Clear Column text fence.
+
+ @since 1.11.3
+ */
+ Column c = checkColumn(L,1);
+
+ if (c->cinfo)
+ col_clear_fence(c->cinfo, c->col);
+
+ return 0;
+}
+
+
+WSLUA_METHODS Column_methods[] = {
+ WSLUA_CLASS_FNREG(Column,clear),
+ WSLUA_CLASS_FNREG(Column,set),
+ WSLUA_CLASS_FNREG(Column,append),
+ WSLUA_CLASS_FNREG(Column,prepend),
+ WSLUA_CLASS_FNREG_ALIAS(Column,preppend,prepend),
+ WSLUA_CLASS_FNREG(Column,fence),
+ WSLUA_CLASS_FNREG(Column,clear_fence),
+ { NULL, NULL }
+};
+
+
+WSLUA_META Column_meta[] = {
+ WSLUA_CLASS_MTREG(Column,tostring),
+ { NULL, NULL }
+};
+
+
+int Column_register(lua_State *L) {
+ WSLUA_REGISTER_CLASS(Column);
+ outstanding_Column = g_ptr_array_new();
+ return 0;
+}
+
+
+WSLUA_CLASS_DEFINE(Columns,NOP,NOP);
+/* The Columns of the packet list. */
+
+WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
+ lua_pushstring(L,"Columns");
+ WSLUA_RETURN(1);
+ /* The string "Columns", no real use, just for debugging purposes. */
+}
+
+/*
+ * To document this is very odd - it won't make sense to a person reading the
+ * API docs to see this metamethod as a method, but oh well.
+ */
+WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
+ /* Sets the text of a specific column. */
+#define WSLUA_ARG_Columns__newindex_COLUMN 2 /* The name of the column to set. */
+#define WSLUA_ARG_Columns__newindex_TEXT 3 /* The text for the column. */
+ Columns cols = checkColumns(L,1);
+ const struct col_names_t* cn;
+ const char* colname;
+ const char* text;
+
+ if (!cols) return 0;
+ if (cols->expired) {
+ luaL_error(L,"expired column");
+ return 0;
+ }
+
+ colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
+ text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
+
+ for(cn = colnames; cn->name; cn++) {
+ if( g_str_equal(cn->name,colname) ) {
+ col_add_str(cols->cinfo, cn->id, text);
+ return 0;
+ }
+ }
+
+ WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
+ return 0;
+}
+
+WSLUA_METAMETHOD Columns__index(lua_State *L) {
+ /* Gets a specific Column. */
+ Columns cols = checkColumns(L,1);
+ const struct col_names_t* cn;
+ const char* colname = luaL_checkstring(L,2);
+
+ if (!cols) {
+ Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
+ c->cinfo = NULL;
+ c->col = col_name_to_id(colname);
+ c->expired = FALSE;
+
+ PUSH_COLUMN(L,c);
+ return 1;
+ }
+
+
+ if (cols->expired) {
+ luaL_error(L,"expired column");
+ return 0;
+ }
+
+ for(cn = colnames; cn->name; cn++) {
+ if( g_str_equal(cn->name,colname) ) {
+ Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
+ c->cinfo = cols->cinfo;
+ c->col = col_name_to_id(colname);
+ c->expired = FALSE;
+
+ PUSH_COLUMN(L,c);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* for internal use - used by Pinfo */
+int get_Columns_index(lua_State *L)
+{
+ return Columns__index(L);
+}
+
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
+static int Columns__gc(lua_State* L) {
+ Columns cols = toColumns(L,1);
+
+ if (!cols) return 0;
+
+ if (!cols->expired)
+ cols->expired = TRUE;
+ else
+ g_free(cols);
+
+ return 0;
+
+}
+
+
+WSLUA_META Columns_meta[] = {
+ WSLUA_CLASS_MTREG(Columns,tostring),
+ WSLUA_CLASS_MTREG(Columns,newindex),
+ WSLUA_CLASS_MTREG(Columns,index),
+ { NULL, NULL }
+};
+
+
+int Columns_register(lua_State *L) {
+ WSLUA_REGISTER_META(Columns);
+ outstanding_Columns = g_ptr_array_new();
+ return 0;
+}
+
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_dissector.c b/epan/wslua/wslua_dissector.c
new file mode 100644
index 0000000000..d3ccc0413f
--- /dev/null
+++ b/epan/wslua/wslua_dissector.c
@@ -0,0 +1,692 @@
+/*
+ * wslua_dissector.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+#include <epan/exceptions.h>
+#include <epan/show_exception.h>
+
+
+/* WSLUA_CONTINUE_MODULE Proto */
+
+
+WSLUA_CLASS_DEFINE(Dissector,NOP,NOP);
+/*
+ A refererence to a dissector, used to call a dissector against a packet or a part of it.
+ */
+
+WSLUA_CONSTRUCTOR Dissector_get (lua_State *L) {
+ /* Obtains a dissector reference by name. */
+#define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector. */
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Dissector_get_NAME);
+ Dissector d;
+
+ if ((d = find_dissector(name))) {
+ pushDissector(L, d);
+ WSLUA_RETURN(1); /* The Dissector reference. */
+ }
+
+ WSLUA_ARG_ERROR(Dissector_get,NAME,"No such dissector");
+ return 0;
+}
+
+/* Allow dissector key names to be sorted alphabetically. */
+static gint
+compare_dissector_key_name(gconstpointer dissector_a, gconstpointer dissector_b)
+{
+ return strcmp((const char*)dissector_a, (const char*)dissector_b);
+}
+
+WSLUA_CONSTRUCTOR Dissector_list (lua_State *L) {
+ /* Gets a Lua array table of all registered Dissector names.
+
+ Note: this is an expensive operation, and should only be used for troubleshooting.
+
+ @since 1.11.3
+ */
+ GList* list = get_dissector_names();
+ GList* elist = NULL;
+ int i = 1;
+
+ if (!list) return luaL_error(L,"Cannot retrieve Dissector name list");
+
+ list = g_list_sort(list, (GCompareFunc)compare_dissector_key_name);
+ elist = g_list_first(list);
+
+ lua_newtable(L);
+ for (i=1; elist; i++, elist = g_list_next(elist)) {
+ lua_pushstring(L,(const char *) elist->data);
+ lua_rawseti(L,1,i);
+ }
+
+ g_list_free(list);
+ WSLUA_RETURN(1); /* The array table of registered dissector names. */
+}
+
+WSLUA_METHOD Dissector_call(lua_State* L) {
+ /* Calls a dissector against a given packet (or part of it). */
+#define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect. */
+#define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info. */
+#define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items. */
+
+ Dissector volatile d = checkDissector(L,1);
+ Tvb tvb = checkTvb(L,WSLUA_ARG_Dissector_call_TVB);
+ Pinfo pinfo = checkPinfo(L,WSLUA_ARG_Dissector_call_PINFO);
+ TreeItem ti = checkTreeItem(L,WSLUA_ARG_Dissector_call_TREE);
+ const char *volatile error = NULL;
+ int len = 0;
+
+ if (! ( d && tvb && pinfo) ) return 0;
+
+ TRY {
+ len = call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree);
+ /* XXX Are we sure about this??? is this the right/only thing to catch */
+ } CATCH_NONFATAL_ERRORS {
+ show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
+ error = "Malformed frame";
+ } ENDTRY;
+
+ if (error) { WSLUA_ERROR(Dissector_call,error); }
+
+ lua_pushnumber(L,(lua_Number)len);
+ WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
+}
+
+WSLUA_METAMETHOD Dissector__call(lua_State* L) {
+ /* Calls a dissector against a given packet (or part of it). */
+#define WSLUA_ARG_Dissector__call_TVB 2 /* The buffer to dissect. */
+#define WSLUA_ARG_Dissector__call_PINFO 3 /* The packet info. */
+#define WSLUA_ARG_Dissector__call_TREE 4 /* The tree on which to add the protocol items. */
+ return Dissector_call(L);
+}
+
+WSLUA_METAMETHOD Dissector__tostring(lua_State* L) {
+ /* Gets the Dissector's protocol short name. */
+ Dissector d = checkDissector(L,1);
+ if (!d) return 0;
+ lua_pushstring(L,dissector_handle_get_short_name(d));
+ WSLUA_RETURN(1); /* A string of the protocol's short name. */
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int Dissector__gc(lua_State* L _U_) {
+ /* do NOT free Dissector */
+ return 0;
+}
+
+WSLUA_METHODS Dissector_methods[] = {
+ WSLUA_CLASS_FNREG(Dissector,get),
+ WSLUA_CLASS_FNREG(Dissector,call),
+ WSLUA_CLASS_FNREG(Dissector,list),
+ { NULL, NULL }
+};
+
+WSLUA_META Dissector_meta[] = {
+ WSLUA_CLASS_MTREG(Dissector,tostring),
+ WSLUA_CLASS_MTREG(Dissector,call),
+ { NULL, NULL }
+};
+
+int Dissector_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(Dissector);
+ return 0;
+}
+
+WSLUA_CLASS_DEFINE(DissectorTable,NOP,NOP);
+/*
+ A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp,
+ sip are added to table "tcp.port").
+
+ Useful to add more dissectors to a table so that they appear in the Decode As... dialog.
+ */
+
+WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
+ /* Creates a new DissectorTable for your dissector's use. */
+#define WSLUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. */
+#define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the User Interface
+ (defaults to the name given). */
+#define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* Either `ftypes.UINT8`, `ftypes.UINT16`,
+ `ftypes.UINT24`, `ftypes.UINT32`, or
+ `ftypes.STRING`
+ (defaults to `ftypes.UINT32`). */
+#define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* Either `base.NONE`, `base.DEC`, `base.HEX`,
+ `base.OCT`, `base.DEC_HEX` or `base.HEX_DEC`
+ (defaults to `base.DEC`). */
+ const gchar* name = (const gchar*)luaL_checkstring(L,WSLUA_ARG_DissectorTable_new_TABLENAME);
+ const gchar* ui_name = (const gchar*)luaL_optstring(L,WSLUA_OPTARG_DissectorTable_new_UINAME,name);
+ enum ftenum type = (enum ftenum)luaL_optinteger(L,WSLUA_OPTARG_DissectorTable_new_TYPE,FT_UINT32);
+ unsigned base = (unsigned)luaL_optinteger(L,WSLUA_OPTARG_DissectorTable_new_BASE,BASE_DEC);
+
+ switch(type) {
+ case FT_STRING:
+ base = BASE_NONE;
+ /* fallthrough */
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ {
+ DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
+
+ name = g_strdup(name);
+ ui_name = g_strdup(ui_name);
+
+ dt->table = register_dissector_table(name, ui_name, type, base);
+ dt->name = name;
+ pushDissectorTable(L, dt);
+ }
+ WSLUA_RETURN(1); /* The newly created DissectorTable. */
+ default:
+ WSLUA_OPTARG_ERROR(DissectorTable_new,TYPE,"must be ftypes.UINT{8,16,24,32} or ftypes.STRING");
+ break;
+ }
+ return 0;
+}
+
+/* this struct is used for passing ourselves user_data through dissector_all_tables_foreach_table(). */
+typedef struct dissector_tables_foreach_table_info {
+ int num;
+ lua_State *L;
+} dissector_tables_foreach_table_info_t;
+
+/* this is the DATFunc_table function used for dissector_all_tables_foreach_table()
+ so we can get all dissector_table names. This pushes the name into a table at stack index 1 */
+static void
+dissector_tables_list_func(const gchar *table_name, const gchar *ui_name _U_, gpointer user_data) {
+ dissector_tables_foreach_table_info_t *data = (dissector_tables_foreach_table_info_t*) user_data;
+ lua_pushstring(data->L, table_name);
+ lua_rawseti(data->L, 1, data->num);
+ data->num = data->num + 1;
+}
+
+WSLUA_CONSTRUCTOR DissectorTable_list (lua_State *L) {
+ /* Gets a Lua array table of all DissectorTable names - i.e., the string names you can
+ use for the first argument to DissectorTable.get().
+
+ Note: this is an expensive operation, and should only be used for troubleshooting.
+
+ @since 1.11.3
+ */
+ dissector_tables_foreach_table_info_t data = { 1, L };
+
+ lua_newtable(L);
+
+ dissector_all_tables_foreach_table(dissector_tables_list_func, (gpointer)&data,
+ (GCompareFunc)compare_dissector_key_name);
+
+ WSLUA_RETURN(1); /* The array table of registered DissectorTable names. */
+}
+
+/* this is the DATFunc_heur_table function used for dissector_all_heur_tables_foreach_table()
+ so we can get all heuristic dissector list names. This pushes the name into a table at stack index 1 */
+static void
+heur_dissector_tables_list_func(const gchar *table_name, heur_dissector_list_t *table _U_, gpointer user_data) {
+ dissector_tables_foreach_table_info_t *data = (dissector_tables_foreach_table_info_t*) user_data;
+ lua_pushstring(data->L, table_name);
+ lua_rawseti(data->L, 1, data->num);
+ data->num = data->num + 1;
+}
+
+WSLUA_CONSTRUCTOR DissectorTable_heuristic_list (lua_State *L) {
+ /* Gets a Lua array table of all heuristic list names - i.e., the string names you can
+ use for the first argument in Proto:register_heuristic().
+
+ Note: this is an expensive operation, and should only be used for troubleshooting.
+
+ @since 1.11.3
+ */
+ dissector_tables_foreach_table_info_t data = { 1, L };
+
+ lua_newtable(L);
+
+ dissector_all_heur_tables_foreach_table(heur_dissector_tables_list_func, (gpointer)&data, NULL);
+
+ WSLUA_RETURN(1); /* The array table of registered heuristic list names */
+}
+
+WSLUA_CONSTRUCTOR DissectorTable_get (lua_State *L) {
+ /*
+ Obtain a reference to an existing dissector table.
+ */
+#define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_TABLENAME);
+ dissector_table_t table = find_dissector_table(name);
+
+ if (table) {
+ DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
+ dt->table = table;
+ dt->name = g_strdup(name);
+
+ pushDissectorTable(L, dt);
+
+ WSLUA_RETURN(1); /* The DissectorTable. */
+ }
+
+ WSLUA_ARG_ERROR(DissectorTable_get,TABLENAME,"no such dissector_table");
+ return 0;
+}
+
+WSLUA_METHOD DissectorTable_add (lua_State *L) {
+ /*
+ Add a `Proto` with a dissector function, or a `Dissector` object, to the dissector table.
+ */
+#define WSLUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer, a
+ integer range or a string depending on the table's type). */
+#define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either a `Proto` or a `Dissector`). */
+
+ DissectorTable dt = checkDissectorTable(L,1);
+ ftenum_t type;
+ Dissector handle;
+
+ if (!dt) return 0;
+
+ if( isProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
+ Proto p;
+ p = checkProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
+ handle = p->handle;
+
+ if (! handle) {
+ WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"a Protocol that does not have a dissector cannot be added to a table");
+ return 0;
+ }
+
+ } else if ( isDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
+ handle = toDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
+ } else {
+ WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector");
+ return 0;
+ }
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ if (type == FT_STRING) {
+ gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
+ dissector_add_string(dt->name, pattern,handle);
+ g_free (pattern);
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ if (lua_isnumber(L, WSLUA_ARG_DissectorTable_add_PATTERN)) {
+ int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_add_PATTERN);
+ dissector_add_uint(dt->name, port, handle);
+ } else {
+ /* Not a number, try as range */
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN);
+ range_t *range = NULL;
+ if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR) {
+ dissector_add_uint_range(dt->name, range, handle);
+ } else {
+ g_free (range);
+ WSLUA_ARG_ERROR(DissectorTable_add,PATTERN,"invalid integer or range");
+ return 0;
+ }
+ g_free (range);
+ }
+ } else {
+ luaL_error(L,"Strange type %d for a DissectorTable",type);
+ }
+
+ return 0;
+}
+
+WSLUA_METHOD DissectorTable_set (lua_State *L) {
+ /*
+ Remove existing dissectors from a table and add a new or a range of new dissectors.
+
+ @since 1.11.3
+ */
+#define WSLUA_ARG_DissectorTable_set_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
+#define WSLUA_ARG_DissectorTable_set_DISSECTOR 3 /* The dissector to add (either a `Proto` or a `Dissector`). */
+
+ DissectorTable dt = checkDissectorTable(L,1);
+ ftenum_t type;
+ Dissector handle;
+
+ if (!dt) return 0;
+
+ if( isProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
+ Proto p;
+ p = checkProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
+ handle = p->handle;
+
+ if (! handle) {
+ WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"a Protocol that does not have a dissector cannot be set to a table");
+ return 0;
+ }
+
+ } else if ( isDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
+ handle = toDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
+ } else {
+ WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"must be either Proto or Dissector");
+ return 0;
+ }
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ if (type == FT_STRING) {
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
+ dissector_delete_all(dt->name, handle);
+ dissector_add_string(dt->name, pattern,handle);
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ if (lua_isnumber(L, WSLUA_ARG_DissectorTable_set_PATTERN)) {
+ int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_set_PATTERN);
+ dissector_delete_all(dt->name, handle);
+ dissector_add_uint(dt->name, port, handle);
+ } else {
+ /* Not a number, try as range */
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
+ range_t *range = NULL;
+ if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR) {
+ dissector_delete_all(dt->name, handle);
+ dissector_add_uint_range(dt->name, range, handle);
+ } else {
+ g_free (range);
+ WSLUA_ARG_ERROR(DissectorTable_set,PATTERN,"invalid integer or range");
+ return 0;
+ }
+ g_free (range);
+ }
+ } else {
+ luaL_error(L,"Strange type %d for a DissectorTable",type);
+ }
+
+ return 0;
+}
+
+WSLUA_METHOD DissectorTable_remove (lua_State *L) {
+ /*
+ Remove a dissector or a range of dissectors from a table
+ */
+#define WSLUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
+#define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to remove (either a `Proto` or a `Dissector`). */
+ DissectorTable dt = checkDissectorTable(L,1);
+ ftenum_t type;
+ Dissector handle;
+
+ if (!dt) return 0;
+
+ if( isProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
+ Proto p;
+ p = checkProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
+ handle = p->handle;
+
+ } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
+ handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
+ } else {
+ WSLUA_ARG_ERROR(DissectorTable_remove,DISSECTOR,"must be either Proto or Dissector");
+ return 0;
+ }
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ if (type == FT_STRING) {
+ gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
+ dissector_delete_string(dt->name, pattern,handle);
+ g_free (pattern);
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ if (lua_isnumber(L, WSLUA_ARG_DissectorTable_remove_PATTERN)) {
+ int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_remove_PATTERN);
+ dissector_delete_uint(dt->name, port, handle);
+ } else {
+ /* Not a number, try as range */
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN);
+ range_t *range = NULL;
+ if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR)
+ dissector_delete_uint_range(dt->name, range, handle);
+ else {
+ g_free (range);
+ WSLUA_ARG_ERROR(DissectorTable_remove,PATTERN,"invalid integer or range");
+ return 0;
+ }
+ g_free (range);
+ }
+ }
+
+ return 0;
+}
+
+WSLUA_METHOD DissectorTable_remove_all (lua_State *L) {
+ /*
+ Remove all dissectors from a table.
+
+ @since 1.11.3
+ */
+#define WSLUA_ARG_DissectorTable_remove_all_DISSECTOR 2 /* The dissector to remove (either a `Proto` or a `Dissector`). */
+ DissectorTable dt = checkDissectorTable(L,1);
+ Dissector handle;
+
+ if (!dt) return 0;
+
+ if( isProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
+ Proto p;
+ p = checkProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
+ handle = p->handle;
+
+ } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
+ handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
+ } else {
+ WSLUA_ARG_ERROR(DissectorTable_remove_all,DISSECTOR,"must be either Proto or Dissector");
+ return 0;
+ }
+
+ dissector_delete_all (dt->name, handle);
+
+ return 0;
+}
+
+WSLUA_METHOD DissectorTable_try (lua_State *L) {
+ /*
+ Try to call a dissector from a table
+ */
+#define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
+#define WSLUA_ARG_DissectorTable_try_TVB 3 /* The buffer to dissect. */
+#define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet info. */
+#define WSLUA_ARG_DissectorTable_try_TREE 5 /* The tree on which to add the protocol items. */
+ DissectorTable volatile dt = checkDissectorTable(L,1);
+ Tvb tvb = checkTvb(L,WSLUA_ARG_DissectorTable_try_TVB);
+ Pinfo pinfo = checkPinfo(L,WSLUA_ARG_DissectorTable_try_PINFO);
+ TreeItem ti = checkTreeItem(L,WSLUA_ARG_DissectorTable_try_TREE);
+ ftenum_t type;
+ gboolean handled = FALSE;
+ const gchar *volatile error = NULL;
+ int len = 0;
+
+ if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ TRY {
+
+ if (type == FT_STRING) {
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
+
+ len = dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree, NULL);
+ if (len > 0) {
+ handled = TRUE;
+ }
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_try_PATTERN);
+
+ len = dissector_try_uint(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
+ if (len > 0) {
+ handled = TRUE;
+ }
+ } else {
+ luaL_error(L,"No such type of dissector_table");
+ }
+
+ if (!handled) {
+ len = call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
+ }
+ /* XXX Are we sure about this??? is this the right/only thing to catch */
+ } CATCH_NONFATAL_ERRORS {
+ show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
+ error = "Malformed frame";
+ } ENDTRY;
+
+ if (error) { WSLUA_ERROR(DissectorTable_try,error); }
+
+ lua_pushnumber(L,(lua_Number)len);
+ WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
+}
+
+WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) {
+ /*
+ Try to obtain a dissector from a table.
+ */
+#define WSLUA_ARG_DissectorTable_get_dissector_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
+
+ DissectorTable dt = checkDissectorTable(L,1);
+ ftenum_t type;
+ dissector_handle_t handle = lua_data_handle;
+
+ if (!dt) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+
+ if (type == FT_STRING) {
+ const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
+ handle = dissector_get_string_handle(dt->table,pattern);
+ } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
+ int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
+ handle = dissector_get_uint_handle(dt->table,port);
+ }
+
+ if (handle) {
+ pushDissector(L,handle);
+ WSLUA_RETURN(1); /* The dissector handle if found. */
+ } else {
+ lua_pushnil(L);
+ WSLUA_RETURN(1); /* nil if not found. */
+ }
+}
+
+WSLUA_METHOD DissectorTable_add_for_decode_as (lua_State *L) {
+ /*
+ Add the given `Proto` to the "Decode as..." list for this DissectorTable.
+ The passed-in `Proto` object's `dissector()` function is used for dissecting.
+
+ @since 1.99.1
+ */
+#define WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO 2 /* The `Proto` to add. */
+ DissectorTable dt = checkDissectorTable(L,1);
+ Proto proto = checkProto(L, WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO);
+ dissector_handle_t handle = NULL;
+
+ if (! proto->handle) {
+ proto->handle = new_register_dissector(proto->loname, dissect_lua, proto->hfid);
+ }
+
+ handle = proto->handle;
+
+ dissector_add_for_decode_as(dt->name, handle);
+
+ return 0;
+}
+
+/* XXX It would be nice to iterate and print which dissectors it has */
+WSLUA_METAMETHOD DissectorTable__tostring(lua_State* L) {
+ /* Gets some debug information about the DissectorTable. */
+ DissectorTable dt = checkDissectorTable(L,1);
+ GString* s;
+ ftenum_t type;
+
+ if (!dt) return 0;
+
+ type = get_dissector_table_selector_type(dt->name);
+ s = g_string_new("DissectorTable ");
+
+ switch(type) {
+ case FT_STRING:
+ {
+ g_string_append_printf(s,"%s String:\n",dt->name);
+ break;
+ }
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ {
+ int base = get_dissector_table_param(dt->name);
+ g_string_append_printf(s,"%s Integer(%i):\n",dt->name,base);
+ break;
+ }
+ default:
+ luaL_error(L,"Strange table type");
+ }
+
+ lua_pushstring(L,s->str);
+ g_string_free(s,TRUE);
+ WSLUA_RETURN(1); /* A string of debug information about the DissectorTable. */
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int DissectorTable__gc(lua_State* L _U_) {
+ /* do NOT free DissectorTable */
+ return 0;
+}
+
+WSLUA_METHODS DissectorTable_methods[] = {
+ WSLUA_CLASS_FNREG(DissectorTable,new),
+ WSLUA_CLASS_FNREG(DissectorTable,get),
+ WSLUA_CLASS_FNREG(DissectorTable,list),
+ WSLUA_CLASS_FNREG(DissectorTable,heuristic_list),
+ WSLUA_CLASS_FNREG(DissectorTable,add),
+ WSLUA_CLASS_FNREG(DissectorTable,set),
+ WSLUA_CLASS_FNREG(DissectorTable,remove),
+ WSLUA_CLASS_FNREG(DissectorTable,remove_all),
+ WSLUA_CLASS_FNREG(DissectorTable,try),
+ WSLUA_CLASS_FNREG(DissectorTable,get_dissector),
+ WSLUA_CLASS_FNREG(DissectorTable,add_for_decode_as),
+ { NULL, NULL }
+};
+
+WSLUA_META DissectorTable_meta[] = {
+ WSLUA_CLASS_MTREG(DissectorTable,tostring),
+ { NULL, NULL }
+};
+
+int DissectorTable_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(DissectorTable);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_file.c b/epan/wslua/wslua_file.c
index e344afe7ef..89a4c3d467 100644
--- a/epan/wslua/wslua_file.c
+++ b/epan/wslua/wslua_file.c
@@ -25,14 +25,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
+#include "wslua_file_common.h"
-#include "wslua.h"
#include <errno.h>
-#include <wiretap/wtap-int.h>
#include <wiretap/file_wrappers.h>
-#include <epan/addr_resolv.h>
-#include <math.h>
#define MAX_LINE_LENGTH 65536
@@ -100,7 +96,7 @@ WSLUA_CLASS_DEFINE(File,FAIL_ON_NULL_OR_EXPIRED("File"),NOP);
can be a wtap_dumper struct during write operations. A wtap_dumper struct
has a WFILE_T member, but we can't only store its pointer here because
dump operations need the whole thing to write out with. Ugh. */
-static File* push_File(lua_State* L, FILE_T ft) {
+File* push_File(lua_State* L, FILE_T ft) {
File f = (File) g_malloc(sizeof(struct _wslua_file));
f->file = ft;
f->wdh = NULL;
@@ -108,7 +104,7 @@ static File* push_File(lua_State* L, FILE_T ft) {
return pushFile(L,f);
}
-static File* push_Wdh(lua_State* L, wtap_dumper *wdh) {
+File* push_Wdh(lua_State* L, wtap_dumper *wdh) {
File f = (File) g_malloc(sizeof(struct _wslua_file));
f->file = (FILE_T)wdh->fh;
f->wdh = wdh;
@@ -512,1962 +508,6 @@ int File_register(lua_State* L) {
}
-/************
- * The following is for handling private data for the duration of the file
- * read_open/read/close cycle, or write_open/write/write_close cycle.
- * In other words it handles the "priv" member of wtap and wtap_dumper,
- * but for the Lua script's use. A Lua script can set a Lua table
- * to CaptureInfo/CaptureInfoConst and have it saved and retrievable this way.
- * We need to offer that, because there needs to be a way for Lua scripts
- * to save state for a given file's operations cycle. Since there can be
- * two files opened at the same time for the same Lua script (due to reload
- * and other such events), the script can't just have one file state.
- */
-
-/* this is way overkill for this one member, but in case we need to add
- more in the future, the plumbing will be here */
-typedef struct _file_priv_t {
- int table_ref;
-} file_priv_t;
-
-/* create and set the wtap->priv private data for the file instance */
-static void create_wth_priv(lua_State* L, wtap *wth) {
- file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
-
- if (wth->priv != NULL) {
- luaL_error(L, "Cannot create wtap private data because there already is private data");
- return;
- }
- priv->table_ref = LUA_NOREF;
- wth->priv = (void*) priv;
-}
-
-/* gets the private data table from wtap */
-static int get_wth_priv_table_ref(lua_State* L, wtap *wth) {
- file_priv_t *priv = (file_priv_t*) wth->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot get wtap private data: it is null");
- return LUA_NOREF;
- }
-
- /* the following might push a nil, but that's ok */
- lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
-
- return 1;
-}
-
-/* sets the private data to wtap - the table is presumed on top of stack */
-static int set_wth_priv_table_ref(lua_State* L, wtap *wth) {
- file_priv_t *priv = (file_priv_t*) wth->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot get wtap private data: it is null");
- return 0;
- }
-
- if (lua_isnil(L, -1)){
- /* user is setting it nil - ok, de-ref any previous one */
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
- priv->table_ref = LUA_NOREF;
- return 0;
- }
-
- if (!lua_istable(L, -1)) {
- luaL_error(L, "The private_table member can only be set to a table or nil");
- return 0;
- }
-
- /* if we had a table already referenced, de-ref it first */
- if (priv->table_ref != LUA_NOREF) {
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
- }
-
- priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
- return 0;
-}
-
-/* remove, deref, and free the wtap->priv data */
-static void remove_wth_priv(lua_State* L, wtap *wth) {
- file_priv_t *priv = (file_priv_t*) wth->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot remove wtap private data: it is null");
- return;
- }
-
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
-
- g_free(wth->priv);
- wth->priv = NULL;
-}
-
-/* create and set the wtap_dumper->priv private data for the file instance */
-static void create_wdh_priv(lua_State* L, wtap_dumper *wdh) {
- file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
-
- if (wdh->priv != NULL) {
- luaL_error(L, "Cannot create wtap_dumper private data because there already is private data");
- return;
- }
- priv->table_ref = LUA_NOREF;
- wdh->priv = (void*) priv;
-}
-
-/* get the private data from wtap_dumper */
-static int get_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
- file_priv_t *priv = (file_priv_t*) wdh->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot get wtap_dumper private data: it is null");
- return LUA_NOREF;
- }
-
- /* the following might push a nil, but that's ok */
- lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
-
- return 1;
-}
-
-/* sets the private data to wtap - the table is presumed on top of stack */
-static int set_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
- file_priv_t *priv = (file_priv_t*) wdh->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot get wtap private data: it is null");
- return 0;
- }
-
- if (lua_isnil(L, -1)){
- /* user is setting it nil - ok, de-ref any previous one */
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
- priv->table_ref = LUA_NOREF;
- return 0;
- }
-
- if (!lua_istable(L, -1)) {
- luaL_error(L, "The private_table member can only be set to a table or nil");
- return 0;
- }
-
- /* if we had a table already referenced, de-ref it first */
- if (priv->table_ref != LUA_NOREF) {
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
- }
-
- priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
- return 0;
-}
-
-/* remove and deref the wtap_dumper->priv data */
-static void remove_wdh_priv(lua_State* L, wtap_dumper *wdh) {
- file_priv_t *priv = (file_priv_t*) wdh->priv;
-
- if (!priv) {
- /* shouldn't be possible */
- luaL_error(L, "Cannot remove wtap_dumper private data: it is null");
- return;
- }
-
- luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
- /* we do NOT free wtap_dumper's priv member - wtap_dump_close() free's it */
-}
-
-
-WSLUA_CLASS_DEFINE(CaptureInfo,FAIL_ON_NULL_MEMBER_OR_EXPIRED("CaptureInfo",wth),NOP);
-/*
- A `CaptureInfo` object, passed into Lua as an argument by `FileHandler` callback
- function `read_open()`, `read()`, `seek_read()`, `seq_read_close()`, and `read_close()`.
- This object represents capture file data and meta-data (data about the
- capture file) being read into Wireshark/Tshark.
-
- This object's fields can be written-to by Lua during the read-based function callbacks.
- In other words, when the Lua plugin's `FileHandler.read_open()` function is invoked, a
- `CaptureInfo` object will be passed in as one of the arguments, and its fields
- should be written to by your Lua code to tell Wireshark about the capture.
-
- @since 1.11.3
- */
-
-static CaptureInfo* push_CaptureInfo(lua_State* L, wtap *wth, const gboolean first_time) {
- CaptureInfo f = (CaptureInfo) g_malloc0(sizeof(struct _wslua_captureinfo));
- f->wth = wth;
- f->wdh = NULL;
- f->expired = FALSE;
-
- if (first_time) {
- /* XXX: need to do this? */
- wth->file_encap = WTAP_ENCAP_UNKNOWN;
- wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
- wth->snapshot_length = 0;
- }
-
- return pushCaptureInfo(L,f);
-}
-
-WSLUA_METAMETHOD CaptureInfo__tostring(lua_State* L) {
- /* Generates a string of debug info for the CaptureInfo */
- CaptureInfo fi = toCaptureInfo(L,1);
-
- if (!fi || !fi->wth) {
- lua_pushstring(L,"CaptureInfo pointer is NULL!");
- } else {
- wtap *wth = fi->wth;
- lua_pushfstring(L, "CaptureInfo: file_type_subtype=%d, snapshot_length=%d, pkt_encap=%d, file_tsprec='%s'",
- wth->file_type_subtype, wth->snapshot_length, wth->phdr.pkt_encap, wth->file_tsprec);
- }
-
- WSLUA_RETURN(1); /* String of debug information. */
-}
-
-
-static int CaptureInfo__gc(lua_State* L _U_) {
- CaptureInfo fc = toCaptureInfo(L,1);
- if (fc)
- g_free(fc);
- return 0;
-}
-
-/* WSLUA_ATTRIBUTE CaptureInfo_encap RW The packet encapsulation type for the whole file.
-
- See `wtap_encaps` in `init.lua` for available types. Set to `wtap_encaps.PER_PACKET` if packets can
- have different types, then later set `FrameInfo.encap` for each packet during `read()`/`seek_read()`.
- */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,encap,wth->file_encap);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,encap,wth->file_encap,int);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_time_precision RW The precision of the packet timestamps in the file.
-
- See `wtap_file_tsprec` in `init.lua` for available precisions.
- */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,time_precision,wth->file_tsprec);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,time_precision,wth->file_tsprec,int);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_snapshot_length RW The maximum packet length that could be recorded.
-
- Setting it to `0` means unknown. Wireshark cannot handle anything bigger than 65535 bytes.
- */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfo,snapshot_length,wth->snapshot_length);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,snapshot_length,wth->snapshot_length,guint);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_comment RW A string comment for the whole capture file,
- or nil if there is no `comment`. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment,TRUE);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_hardware RW A string containing the description of
- the hardware used to create the capture, or nil if there is no `hardware` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware,TRUE);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_os RW A string containing the name of
- the operating system used to create the capture, or nil if there is no `os` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,os,wth->shb_hdr.shb_os);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,os,wth->shb_hdr.shb_os,TRUE);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_user_app RW A string containing the name of
- the application used to create the capture, or nil if there is no `user_app` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl,TRUE);
-
-/* WSLUA_ATTRIBUTE CaptureInfo_hosts WO Sets resolved ip-to-hostname information.
-
- The value set must be a Lua table of two key-ed names: `ipv4_addresses` and `ipv6_addresses`.
- The value of each of these names are themselves array tables, of key-ed tables, such that the inner table has a key
- `addr` set to the raw 4-byte or 16-byte IP address Lua string and a `name` set to the resolved name.
-
- For example, if the capture file identifies one resolved IPv4 address of 1.2.3.4 to `foo.com`, then you must set
- `CaptureInfo.hosts` to a table of:
- @code { ipv4_addresses = { { addr = "\01\02\03\04", name = "foo.com" } } } @endcode
-
- Note that either the `ipv4_addresses` or the `ipv6_addresses` table, or both, may be empty or nil.
- */
-static int CaptureInfo_set_hosts(lua_State* L) {
- CaptureInfo fi = checkCaptureInfo(L,1);
- wtap *wth = fi->wth;
- const char *addr = NULL;
- const char *name = NULL;
- size_t addr_len = 0;
- size_t name_len = 0;
- guint32 v4_addr = 0;
- struct e_in6_addr v6_addr = { {0} };
-
- if (!wth->add_new_ipv4 || !wth->add_new_ipv6) {
- return luaL_error(L, "CaptureInfo wtap has no IPv4 or IPv6 name resolution");
- }
-
- if (!lua_istable(L,-1)) {
- return luaL_error(L, "CaptureInfo.host must be set to a table");
- }
-
- /* get the ipv4_addresses table */
- lua_getfield(L, -1, "ipv4_addresses");
-
- if (lua_istable(L,-1)) {
- /* now walk the table */
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- /* 'key' (at index -2) and 'value' (at index -1) */
- if (!lua_istable(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv4_addresses table does not contain a table");
- }
-
- lua_getfield(L, -1, "addr");
- if (!lua_isstring(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv4_addresses table's table does not contain an 'addr' field");
- }
- addr = luaL_checklstring(L,-1,&addr_len);
- if (addr_len != 4) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv4_addresses 'addr' value is not 4 bytes long");
- }
- memcpy(&v4_addr, addr, 4);
-
- lua_getfield(L, -1, "name");
- if (!lua_isstring(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv4_addresses table's table does not contain an 'addr' field");
- }
- name = luaL_checklstring(L,-1,&name_len);
-
- wth->add_new_ipv4(v4_addr, name);
-
- /* removes 'value'; keeps 'key' for next iteration */
- lua_pop(L, 1);
- }
- }
-
- /* wasn't a table, or it was and we walked it; either way pop it */
- lua_pop(L,1);
-
-
- /* get the ipv6_addresses table */
- lua_getfield(L, -1, "ip6_addresses");
-
- if (lua_istable(L,-1)) {
- /* now walk the table */
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- /* 'key' (at index -2) and 'value' (at index -1) */
- if (!lua_istable(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv6_addresses table does not contain a table");
- }
-
- lua_getfield(L, -1, "addr");
- if (!lua_isstring(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv6_addresses table's table does not contain an 'addr' field");
- }
- addr = luaL_checklstring(L,-1,&addr_len);
- if (addr_len != 16) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv6_addresses 'addr' value is not 16 bytes long");
- }
- memcpy(&v6_addr, addr, 16);
-
- lua_getfield(L, -1, "name");
- if (!lua_isstring(L,-1)) {
- lua_pop(L, 3); /* remove whatever it is, the key, and the ipv4_addreses table */
- return luaL_error(L, "CaptureInfo.host ipv6_addresses table's table does not contain an 'addr' field");
- }
- name = luaL_checklstring(L,-1,&name_len);
-
- wth->add_new_ipv6((const void *)(&v6_addr), name);
-
- /* removes 'value'; keeps 'key' for next iteration */
- lua_pop(L, 1);
- }
- }
-
- /* wasn't a table, or it was and we walked it; either way pop it */
- lua_pop(L,1);
-
- return 0;
-}
-
-
-/* WSLUA_ATTRIBUTE CaptureInfo_private_table RW A private Lua value unique to this file.
-
- The `private_table` is a field you set/get with your own Lua table.
- This is provided so that a Lua script can save per-file reading/writing
- state, because multiple files can be opened and read at the same time.
-
- For example, if the user issued a reload-file command, or Lua called the
- `reload()` function, then the current capture file is still open while a new one
- is being opened, and thus Wireshark will invoke `read_open()` while the previous
- capture file has not caused `read_close()` to be called; and if the `read_open()`
- succeeds then `read_close()` will be called right after that for the previous
- file, rather than the one just opened. Thus the Lua script can use this
- `private_table` to store a table of values specific to each file, by setting
- this `private_table` in the `read_open()` function, which it can then later get back
- inside its `read()`, `seek_read()`, and `read_close()` functions.
-*/
-static int CaptureInfo_get_private_table(lua_State* L) {
- CaptureInfo fi = checkCaptureInfo(L,1);
- return get_wth_priv_table_ref(L, fi->wth);
-}
-
-static int CaptureInfo_set_private_table(lua_State* L) {
- CaptureInfo fi = checkCaptureInfo(L,1);
- return set_wth_priv_table_ref(L, fi->wth);
-}
-
-WSLUA_ATTRIBUTES CaptureInfo_attributes[] = {
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,encap),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,time_precision),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,snapshot_length),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,comment),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,hardware),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,os),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,user_app),
- WSLUA_ATTRIBUTE_WOREG(CaptureInfo,hosts),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfo,private_table),
- { NULL, NULL, NULL }
-};
-
-WSLUA_META CaptureInfo_meta[] = {
- WSLUA_CLASS_MTREG(CaptureInfo,tostring),
- { NULL, NULL }
-};
-
-int CaptureInfo_register(lua_State* L) {
- WSLUA_REGISTER_META(CaptureInfo);
- WSLUA_REGISTER_ATTRIBUTES(CaptureInfo);
- return 0;
-}
-
-
-WSLUA_CLASS_DEFINE(CaptureInfoConst,FAIL_ON_NULL_MEMBER_OR_EXPIRED("CaptureInfoConst",wdh),NOP);
-/*
- A `CaptureInfoConst` object, passed into Lua as an argument to the `FileHandler` callback
- function `write_open()`.
-
- This object represents capture file data and meta-data (data about the
- capture file) for the current capture in Wireshark/Tshark.
-
- This object's fields are read-from when used by `write_open` function callback.
- In other words, when the Lua plugin's FileHandler `write_open` function is invoked, a
- `CaptureInfoConst` object will be passed in as one of the arguments, and its fields
- should be read from by your Lua code to get data about the capture that needs to be written.
-
- @since 1.11.3
- */
-
-static CaptureInfoConst* push_CaptureInfoConst(lua_State* L, wtap_dumper *wdh) {
- CaptureInfoConst f = (CaptureInfoConst) g_malloc0(sizeof(struct _wslua_captureinfo));
- f->wth = NULL;
- f->wdh = wdh;
- f->expired = FALSE;
- return pushCaptureInfoConst(L,f);
-}
-
-WSLUA_METAMETHOD CaptureInfoConst__tostring(lua_State* L) {
- /* Generates a string of debug info for the CaptureInfoConst */
- CaptureInfoConst fi = toCaptureInfoConst(L,1);
-
- if (!fi || !fi->wdh) {
- lua_pushstring(L,"CaptureInfoConst pointer is NULL!");
- } else {
- wtap_dumper *wdh = fi->wdh;
- lua_pushfstring(L, "CaptureInfoConst: file_type_subtype=%d, snaplen=%d, encap=%d, compressed=%d, file_tsprec='%s'",
- wdh->file_type_subtype, wdh->snaplen, wdh->encap, wdh->compressed, wdh->tsprecision);
- }
-
- WSLUA_RETURN(1); /* String of debug information. */
-}
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_type RO The file type. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,type,wdh->file_type_subtype);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_snapshot_length RO The maximum packet length that is actually recorded (vs. the original
- length of any given packet on-the-wire). A value of `0` means the snapshot length is unknown or there is no one
- such length for the whole file. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,snapshot_length,wdh->snaplen);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_encap RO The packet encapsulation type for the whole file.
-
- See `wtap_encaps` in init.lua for available types. It is set to `wtap_encaps.PER_PACKET` if packets can
- have different types, in which case each Frame identifies its type, in `FrameInfo.packet_encap`. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,encap,wdh->encap);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_comment RW A comment for the whole capture file, if the
- `wtap_presence_flags.COMMENTS` was set in the presence flags; nil if there is no comment. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,comment,wth->shb_hdr.opt_comment);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_hardware RO A string containing the description of
- the hardware used to create the capture, or nil if there is no hardware string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,hardware,wth->shb_hdr.shb_hardware);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_os RO A string containing the name of
- the operating system used to create the capture, or nil if there is no os string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,os,wth->shb_hdr.shb_os);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_user_app RO A string containing the name of
- the application used to create the capture, or nil if there is no user_app string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,user_app,wth->shb_hdr.shb_user_appl);
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_hosts RO A ip-to-hostname Lua table of two key-ed names: `ipv4_addresses` and `ipv6_addresses`.
- The value of each of these names are themselves array tables, of key-ed tables, such that the inner table has a key
- `addr` set to the raw 4-byte or 16-byte IP address Lua string and a `name` set to the resolved name.
-
- For example, if the current capture has one resolved IPv4 address of 1.2.3.4 to `foo.com`, then getting
- `CaptureInfoConst.hosts` will get a table of:
- @code { ipv4_addresses = { { addr = "\01\02\03\04", name = "foo.com" } }, ipv6_addresses = { } } @endcode
-
- Note that either the `ipv4_addresses` or the `ipv6_addresses` table, or both, may be empty, however they will not
- be nil. */
-static int CaptureInfoConst_get_hosts(lua_State* L) {
- CaptureInfoConst fi = checkCaptureInfoConst(L,1);
- wtap_dumper *wdh = fi->wdh;
-
- /* create the main table to return */
- lua_newtable(L);
-
- /* create the ipv4_addresses table */
- lua_newtable(L);
-
- if (wdh->addrinfo_lists && wdh->addrinfo_lists->ipv4_addr_list) {
- hashipv4_t *ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, 0);
- int i, j;
- for (i=1, j=1; ipv4_hash_list_entry != NULL; i++) {
- if ((ipv4_hash_list_entry->flags & USED_AND_RESOLVED_MASK) == RESOLVED_ADDRESS_USED) {
- lua_pushnumber(L, j); /* push numeric index key starting at 1, so it will be an array table */
- /* create the entry table */
- lua_newtable(L);
- /* addr is in network order already */
- lua_pushlstring(L, (char*)(&ipv4_hash_list_entry->ip), 4);
- lua_setfield(L, -2, "addr");
- lua_pushstring(L, ipv4_hash_list_entry->name);
- lua_setfield(L, -2, "name");
- /* now our ipv4_addresses table is at -3, key number is -2, and entry table at -2, so we're good */
- lua_settable(L, -3);
- j++;
- }
- ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
- }
- }
-
- /* set the (possibly empty) ipv4_addresses table into the main table */
- lua_setfield(L, -2, "ipv4_addresses");
-
- /* create the ipv6_addresses table */
- lua_newtable(L);
-
- if (wdh->addrinfo_lists && wdh->addrinfo_lists->ipv6_addr_list) {
- hashipv6_t *ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, 0);
- int i, j;
- for (i=1, j=1; ipv6_hash_list_entry != NULL; i++) {
- if ((ipv6_hash_list_entry->flags & USED_AND_RESOLVED_MASK) == RESOLVED_ADDRESS_USED) {
- lua_pushnumber(L, j); /* push numeric index key starting at 1, so it will be an array table */
- /* create the entry table */
- lua_newtable(L);
- /* addr is in network order already */
- lua_pushlstring(L, (char*)(&ipv6_hash_list_entry->addr.bytes[0]), 16);
- lua_setfield(L, -2, "addr");
- lua_pushstring(L, ipv6_hash_list_entry->name);
- lua_setfield(L, -2, "name");
- /* now our ipv6_addresses table is at -3, key number is -2, and entry table at -2, so we're good */
- lua_settable(L, -3);
- j++;
- }
- ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
- }
- }
-
- /* set the (possibly empty) ipv6_addresses table into the main table */
- lua_setfield(L, -2, "ip6_addresses");
-
- /* return the main table */
- return 1;
-}
-
-/* WSLUA_ATTRIBUTE CaptureInfoConst_private_table RW A private Lua value unique to this file.
-
- The `private_table` is a field you set/get with your own Lua table.
- This is provided so that a Lua script can save per-file reading/writing
- state, because multiple files can be opened and read at the same time.
-
- For example, if two Lua scripts issue a `Dumper:new_for_current()` call and the
- current file happens to use your script's writer, then the Wireshark will invoke
- `write_open()` while the previous capture file has not had `write_close()` called.
- Thus the Lua script can use this `private_table` to store a table of values
- specific to each file, by setting this `private_table` in the write_open()
- function, which it can then later get back inside its `write()`, and `write_close()`
- functions.
-*/
-static int CaptureInfoConst_get_private_table(lua_State* L) {
- CaptureInfoConst fi = checkCaptureInfoConst(L,1);
- return get_wdh_priv_table_ref(L, fi->wdh);
-}
-
-static int CaptureInfoConst_set_private_table(lua_State* L) {
- CaptureInfoConst fi = checkCaptureInfoConst(L,1);
- return set_wdh_priv_table_ref(L, fi->wdh);
-}
-
-static int CaptureInfoConst__gc(lua_State* L _U_) {
- CaptureInfoConst fi = toCaptureInfoConst(L,1);
- if (fi)
- g_free(fi);
- return 0;
-}
-
-WSLUA_ATTRIBUTES CaptureInfoConst_attributes[] = {
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,encap),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,type),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,snapshot_length),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,comment),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,hardware),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,os),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,user_app),
- WSLUA_ATTRIBUTE_ROREG(CaptureInfoConst,hosts),
- WSLUA_ATTRIBUTE_RWREG(CaptureInfoConst,private_table),
- { NULL, NULL, NULL }
-};
-
-WSLUA_META CaptureInfoConst_meta[] = {
- WSLUA_CLASS_MTREG(CaptureInfoConst,tostring),
- { NULL, NULL }
-};
-
-int CaptureInfoConst_register(lua_State* L) {
- WSLUA_REGISTER_META(CaptureInfoConst);
- WSLUA_REGISTER_ATTRIBUTES(CaptureInfoConst);
- return 0;
-}
-
-
-WSLUA_CLASS_DEFINE(FrameInfo,FAIL_ON_NULL_OR_EXPIRED("FrameInfo"),NOP);
-/*
- A FrameInfo object, passed into Lua as an argument by FileHandler callback
- functions (e.g., `read`, `seek_read`, etc.).
-
- This object represents frame data and meta-data (data about the frame/packet)
- for a given `read`/`seek_read`/`write`'s frame.
-
- This object's fields are written-to/set when used by read function callbacks, and
- read-from/get when used by file write function callbacks. In other words, when
- the Lua plugin's FileHandler `read`/`seek_read`/etc. functions are invoked, a
- FrameInfo object will be passed in as one of the arguments, and its fields
- should be written-to/set based on the frame information read from the file;
- whereas when the Lua plugin's `FileHandler.write()` function is invoked, the
- `FrameInfo` object passed in should have its fields read-from/get, to write that
- frame information to the file.
-
- @since 1.11.3
- */
-
-static FrameInfo* push_FrameInfo(lua_State* L, struct wtap_pkthdr *phdr, Buffer* buf) {
- FrameInfo f = (FrameInfo) g_malloc0(sizeof(struct _wslua_phdr));
- f->phdr = phdr;
- f->buf = buf;
- f->expired = FALSE;
- return pushFrameInfo(L,f);
-}
-
-WSLUA_METAMETHOD FrameInfo__tostring(lua_State* L) {
- /* Generates a string of debug info for the FrameInfo */
- FrameInfo fi = toFrameInfo(L,1);
-
- if (!fi) {
- lua_pushstring(L,"FrameInfo pointer is NULL!");
- } else {
- if (fi->phdr)
- lua_pushfstring(L, "FrameInfo: rec_type=%u, presence_flags=%d, caplen=%d, len=%d, pkt_encap=%d, opt_comment='%s'",
- fi->phdr->rec_type, fi->phdr->presence_flags, fi->phdr->caplen, fi->phdr->len, fi->phdr->pkt_encap, fi->phdr->opt_comment);
- else
- lua_pushstring(L, "FrameInfo phdr pointer is NULL!");
- }
-
- WSLUA_RETURN(1); /* String of debug information. */
-}
-
-/* XXX: should this function be a method of File instead? */
-WSLUA_METHOD FrameInfo_read_data(lua_State* L) {
- /* Tells Wireshark to read directly from given file into frame data buffer, for length bytes. Returns true if succeeded, else false. */
-#define WSLUA_ARG_FrameInfo_read_data_FILE 2 /* The File object userdata, provided by Wireshark previously in a reading-based callback. */
-#define WSLUA_ARG_FrameInfo_read_data_LENGTH 3 /* The number of bytes to read from the file at the current cursor position. */
- FrameInfo fi = checkFrameInfo(L,1);
- File fh = checkFile(L,WSLUA_ARG_FrameInfo_read_data_FILE);
- guint32 len = wslua_checkguint32(L, WSLUA_ARG_FrameInfo_read_data_LENGTH);
- int err = 0;
- gchar *err_info = NULL;
-
- if (!fi->buf || !fh->file) {
- luaL_error(L, "FrameInfo read_data() got null buffer or file pointer internally");
- return 0;
- }
-
- if (!wtap_read_packet_bytes(fh->file, fi->buf, len, &err, &err_info)) {
- lua_pushboolean(L, FALSE);
- if (err_info) {
- lua_pushstring(L, err_info);
- g_free(err_info); /* is this right? */
- }
- else lua_pushnil(L);
- lua_pushnumber(L, err);
- return 3;
- }
-
- lua_pushboolean(L, TRUE);
-
- WSLUA_RETURN(1); /* True if succeeded, else returns false along with the error number and string error description. */
-}
-
-/* free the struct we created, but not the phdr/buf it points to */
-static int FrameInfo__gc(lua_State* L _U_) {
- FrameInfo fi = toFrameInfo(L,1);
- if (fi)
- g_free(fi);
- return 0;
-}
-
-/* WSLUA_ATTRIBUTE FrameInfo_time RW The packet timestamp as an NSTime object.
-
- Note: Set the `FileHandler.time_precision` to the appropriate `wtap_file_tsprec` value as well.
- */
-static int FrameInfo_set_time (lua_State* L) {
- FrameInfo fi = checkFrameInfo(L,1);
- NSTime nstime = checkNSTime(L,2);
-
- if (!fi->phdr) return 0;
-
- fi->phdr->ts.secs = nstime->secs;
- fi->phdr->ts.nsecs = nstime->nsecs;
-
- return 0;
-}
-
-static int FrameInfo_get_time (lua_State* L) {
- FrameInfo fi = checkFrameInfo(L,1);
- NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
-
- if (!nstime) return 0;
-
- nstime->secs = fi->phdr->ts.secs;
- nstime->nsecs = fi->phdr->ts.nsecs;
-
- pushNSTime(L,nstime);
-
- return 1; /* An NSTime object of the frame's timestamp. */
-}
-
-/* WSLUA_ATTRIBUTE FrameInfo_data RW The data buffer containing the packet.
-
- @note This cannot be cleared once set.
- */
-static int FrameInfo_set_data (lua_State* L) {
- FrameInfo fi = checkFrameInfo(L,1);
-
- if (!fi->phdr) {
- g_warning("Error in FrameInfo set data: NULL pointer");
- return 0;
- }
-
- if (!fi->buf) {
- g_warning("Error in FrameInfo set data: NULL frame_buffer pointer");
- return 0;
- }
-
- if (lua_isstring(L,2)) {
- size_t len = 0;
- const gchar* s = luaL_checklstring(L,2,&len);
-
- /* Make sure we have enough room for the packet */
- ws_buffer_assure_space(fi->buf, len);
- memcpy(ws_buffer_start_ptr(fi->buf), s, len);
- fi->phdr->caplen = (guint32) len;
- fi->phdr->len = (guint32) len;
- }
- else
- luaL_error(L, "FrameInfo's attribute 'data' must be a Lua string");
-
- return 0;
-}
-
-static int FrameInfo_get_data (lua_State* L) {
- FrameInfo fi = checkFrameInfo(L,1);
-
- if (!fi->buf) return 0;
-
- lua_pushlstring(L, ws_buffer_start_ptr(fi->buf), ws_buffer_length(fi->buf));
-
- WSLUA_RETURN(1); /* A Lua string of the frame buffer's data. */
-}
-
-/* WSLUA_ATTRIBUTE FrameInfo_rec_type RW The record type of the packet frame
-
- See `wtap_rec_types` in `init.lua` for values. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,rec_type,phdr->rec_type);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,rec_type,phdr->rec_type,guint);
-
-/* WSLUA_ATTRIBUTE FrameInfo_flags RW The presence flags of the packet frame.
-
- See `wtap_presence_flags` in `init.lua` for bit values. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,flags,phdr->presence_flags);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,flags,phdr->presence_flags,guint32);
-
-/* WSLUA_ATTRIBUTE FrameInfo_captured_length RW The captured packet length,
- and thus the length of the buffer passed to the `FrameInfo.data` field. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,captured_length,phdr->caplen);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,captured_length,phdr->caplen,guint32);
-
-/* WSLUA_ATTRIBUTE FrameInfo_original_length RW The on-the-wire packet length,
- which may be longer than the `captured_length`. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,original_length,phdr->len);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,original_length,phdr->len,guint32);
-
-/* WSLUA_ATTRIBUTE FrameInfo_encap RW The packet encapsulation type for the frame/packet,
- if the file supports per-packet types. See `wtap_encaps` in `init.lua` for possible
- packet encapsulation types to use as the value for this field. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,encap,phdr->pkt_encap);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,encap,phdr->pkt_encap,int);
-
-/* WSLUA_ATTRIBUTE FrameInfo_comment RW A string comment for the packet, if the
- `wtap_presence_flags.COMMENTS` was set in the presence flags; nil if there is no comment. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FrameInfo,comment,phdr->opt_comment);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(FrameInfo,comment,phdr->opt_comment,TRUE);
-
-/* This table is ultimately registered as a sub-table of the class' metatable,
- * and if __index/__newindex is invoked then it calls the appropriate function
- * from this table for getting/setting the members.
- */
-WSLUA_ATTRIBUTES FrameInfo_attributes[] = {
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,rec_type),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,flags),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,captured_length),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,original_length),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,comment),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,encap),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,time),
- WSLUA_ATTRIBUTE_RWREG(FrameInfo,data),
- { NULL, NULL, NULL }
-};
-
-WSLUA_METHODS FrameInfo_methods[] = {
- WSLUA_CLASS_FNREG(FrameInfo,read_data),
- { NULL, NULL }
-};
-
-WSLUA_META FrameInfo_meta[] = {
- WSLUA_CLASS_MTREG(FrameInfo,tostring),
- { NULL, NULL }
-};
-
-int FrameInfo_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(FrameInfo);
- WSLUA_REGISTER_ATTRIBUTES(FrameInfo);
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(FrameInfoConst,FAIL_ON_NULL_OR_EXPIRED("FrameInfo"),NOP);
-/*
- A constant FrameInfo object, passed into Lua as an argument by the FileHandler write
- callback function. This has similar attributes/properties as FrameInfo, but the fields can
- only be read from, not written to.
-
- @since 1.11.3
- */
-
-static FrameInfoConst* push_FrameInfoConst(lua_State* L, const struct wtap_pkthdr *phdr, const guint8 *pd) {
- FrameInfoConst f = (FrameInfoConst) g_malloc(sizeof(struct _wslua_const_phdr));
- f->phdr = phdr;
- f->pd = pd;
- f->expired = FALSE;
- return pushFrameInfoConst(L,f);
-}
-
-WSLUA_METAMETHOD FrameInfoConst__tostring(lua_State* L) {
- /* Generates a string of debug info for the FrameInfo */
- FrameInfoConst fi = toFrameInfoConst(L,1);
-
- if (!fi) {
- lua_pushstring(L,"FrameInfo pointer is NULL!");
- } else {
- if (fi->phdr && !fi->expired)
- lua_pushfstring(L, "FrameInfo: rec_type=%u, presence_flags=%d, caplen=%d, len=%d, pkt_encap=%d, opt_comment='%s'",
- fi->phdr->rec_type, fi->phdr->presence_flags, fi->phdr->caplen, fi->phdr->len, fi->phdr->pkt_encap, fi->phdr->opt_comment);
- else
- lua_pushfstring(L, "FrameInfo has %s", fi->phdr?"expired":"null phdr pointer");
- }
-
- WSLUA_RETURN(1); /* String of debug information. */
-}
-
-/* XXX: should this function be a method of File instead? */
-WSLUA_METHOD FrameInfoConst_write_data(lua_State* L) {
- /* Tells Wireshark to write directly to given file from the frame data buffer, for length bytes. Returns true if succeeded, else false. */
-#define WSLUA_ARG_FrameInfoConst_write_data_FILE 2 /* The File object userdata, provided by Wireshark previously in a writing-based callback. */
-#define WSLUA_OPTARG_FrameInfoConst_write_data_LENGTH 3 /* The number of bytes to write to the file at the current cursor position, or all if not supplied. */
- FrameInfoConst fi = checkFrameInfoConst(L,1);
- File fh = checkFile(L,WSLUA_ARG_FrameInfoConst_write_data_FILE);
- guint32 len = wslua_optguint32(L, WSLUA_OPTARG_FrameInfoConst_write_data_LENGTH, fi->phdr ? fi->phdr->caplen:0);
- int err = 0;
-
- if (!fi->pd || !fi->phdr || !fh->wdh) {
- luaL_error(L, "FrameInfoConst write_data() got null buffer or file pointer internally");
- return 0;
- }
-
- if (len > fi->phdr->caplen)
- len = fi->phdr->caplen;
-
- if (!wtap_dump_file_write(fh->wdh, fi->pd, (size_t)(len), &err)) {
- lua_pushboolean(L, FALSE);
- lua_pushfstring(L, "FrameInfoConst write_data() error: %s", g_strerror(err));
- lua_pushnumber(L, err);
- return 3;
- }
-
- lua_pushboolean(L, TRUE);
-
- WSLUA_RETURN(1); /* True if succeeded, else returns false along with the error number and string error description. */
-}
-
-/* free the struct we created, but not the wtap_pkthdr it points to */
-static int FrameInfoConst__gc(lua_State* L _U_) {
- FrameInfoConst fi = toFrameInfoConst(L,1);
- if (fi)
- g_free(fi);
- return 0;
-}
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_time RO The packet timestamp as an NSTime object. */
-static int FrameInfoConst_get_time (lua_State* L) {
- FrameInfoConst fi = checkFrameInfoConst(L,1);
- NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
-
- if (!nstime) return 0;
-
- nstime->secs = fi->phdr->ts.secs;
- nstime->nsecs = fi->phdr->ts.nsecs;
-
- pushNSTime(L,nstime);
-
- return 1; /* An NSTime object of the frame's timestamp. */
-}
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_data RO The data buffer containing the packet. */
-static int FrameInfoConst_get_data (lua_State* L) {
- FrameInfoConst fi = checkFrameInfoConst(L,1);
-
- if (!fi->pd || !fi->phdr) return 0;
-
- lua_pushlstring(L, fi->pd, fi->phdr->caplen);
-
- return 1;
-}
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_rec_type RO The record type of the packet frame - see `wtap_presence_flags` in `init.lua` for values. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,rec_type,phdr->rec_type);
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_flags RO The presence flags of the packet frame - see `wtap_presence_flags` in `init.lua` for bits. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,flags,phdr->presence_flags);
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_captured_length RO The captured packet length, and thus the length of the buffer in the FrameInfoConst.data field. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,captured_length,phdr->caplen);
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_original_length RO The on-the-wire packet length, which may be longer than the `captured_length`. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,original_length,phdr->len);
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_encap RO The packet encapsulation type, if the file supports per-packet types.
-
- See `wtap_encaps` in `init.lua` for possible packet encapsulation types to use as the value for this field. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,encap,phdr->pkt_encap);
-
-/* WSLUA_ATTRIBUTE FrameInfoConst_comment RO A comment for the packet; nil if there is none. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FrameInfoConst,comment,phdr->opt_comment);
-
-WSLUA_ATTRIBUTES FrameInfoConst_attributes[] = {
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,rec_type),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,flags),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,captured_length),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,original_length),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,encap),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,comment),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,time),
- WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,data),
- { NULL, NULL, NULL }
-};
-
-WSLUA_METHODS FrameInfoConst_methods[] = {
- WSLUA_CLASS_FNREG(FrameInfoConst,write_data),
- { NULL, NULL }
-};
-
-WSLUA_META FrameInfoConst_meta[] = {
- WSLUA_CLASS_MTREG(FrameInfoConst,tostring),
- { NULL, NULL }
-};
-
-int FrameInfoConst_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(FrameInfoConst);
- WSLUA_REGISTER_ATTRIBUTES(FrameInfoConst);
- return 0;
-}
-
-
-WSLUA_CLASS_DEFINE(FileHandler,NOP,NOP);
-/*
- A FileHandler object, created by a call to FileHandler.new(arg1, arg2, ...).
- The FileHandler object lets you create a file-format reader, or writer, or
- both, by setting your own read_open/read or write_open/write functions.
-
- @since 1.11.3
- */
-
-static int filehandler_cb_error_handler(lua_State* L) {
- const gchar* error = lua_tostring(L,1);
- const gchar* functype = luaL_optstring(L, lua_upvalueindex(1), "UNKNOWN");
- report_failure("Lua: Error During execution of FileHandler %s callback:\n %s",functype,error);
- lua_pop(L, 1);
- return 0;
-}
-
-static int push_error_handler(lua_State* L, const gchar* funcname) {
- lua_pushstring(L, funcname);
- lua_pushcclosure(L, filehandler_cb_error_handler, 1);
- return 1;
-}
-
-
-/* During file routines, we cannot allow the FileHandler to get de-registered, since
- that would change the GArray's in file_access.c and hilarity would ensue. So we
- set this to true right before pcall(), and back to false afterwards */
-static gboolean in_routine = FALSE;
-
-/* This does the verification and setup common to all open/read/seek_read/close routines */
-#define INIT_FILEHANDLER_ROUTINE(name,retval) \
- if (!fh) { \
- g_warning("Error in file %s: no Lua FileHandler object", #name); \
- return retval; \
- } \
- if (!fh->registered) { \
- g_warning("Error in file %s: Lua FileHandler is not registered", #name); \
- return retval; \
- } \
- if (!fh->L) { \
- g_warning("Error in file %s: no FileHandler Lua state", #name); \
- return retval; \
- } \
- if (fh->name##_ref == LUA_NOREF) { \
- g_warning("Error in file %s: no FileHandler %s routine reference", #name, #name); \
- return retval; \
- } \
- L = fh->L; \
- lua_settop(L,0); \
- push_error_handler(L, #name " routine"); \
- lua_rawgeti(L, LUA_REGISTRYINDEX, fh->name##_ref); \
- if (!lua_isfunction(L, -1)) { \
- g_warning("Error in file %s: no FileHandler %s routine function in Lua", #name, #name); \
- return retval; \
- } \
- /* now guard against de-registering during pcall() */ \
- in_routine = TRUE;
-
-#define END_FILEHANDLER_ROUTINE() \
- /* now allow de-registering again */ \
- in_routine = TRUE;
-
-
-/* LUA_ERRGCMM is in Lua 5.2 only - making it 9 disables it */
-#ifndef LUA_ERRGCMM
-#define LUA_ERRGCMM 9
-#endif
-
-#define CASE_ERROR(name) \
- case LUA_ERRRUN: \
- g_warning("Run-time error while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRMEM: \
- g_warning("Memory alloc error while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRERR: \
- g_warning("Error in error handling while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRGCMM: \
- g_warning("Error in garbage collector while calling FileHandler %s routine", name); \
- break; \
- default: \
- g_assert_not_reached(); \
- break;
-
-#define CASE_ERROR_ERRINFO(name) \
- case LUA_ERRRUN: \
- g_warning("Run-time error while calling FileHandler %s routine", name); \
- *err_info = g_strdup_printf("Run-time error while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRMEM: \
- g_warning("Memory alloc error while calling FileHandler %s routine", name); \
- *err_info = g_strdup_printf("Memory alloc error while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRERR: \
- g_warning("Error in error handling while calling FileHandler %s routine", name); \
- *err_info = g_strdup_printf("Error in error handling while calling FileHandler %s routine", name); \
- break; \
- case LUA_ERRGCMM: \
- g_warning("Error in garbage collector while calling FileHandler %s routine", name); \
- *err_info = g_strdup_printf("Error in garbage collector while calling FileHandler %s routine", name); \
- break; \
- default: \
- g_assert_not_reached(); \
- break;
-
-
-/* some declarations */
-static gboolean
-wslua_filehandler_read(wtap *wth, int *err, gchar **err_info,
- gint64 *data_offset);
-static gboolean
-wslua_filehandler_seek_read(wtap *wth, gint64 seek_off,
- struct wtap_pkthdr *phdr, Buffer *buf,
- int *err, gchar **err_info);
-static void
-wslua_filehandler_close(wtap *wth);
-static void
-wslua_filehandler_sequential_close(wtap *wth);
-
-
-/* This is our one-and-only open routine for file handling. When called by
- * file_access.c, the wtap wth argument has a void* wslua_data that holds the specific
- * FileHandler for the specific registered file format reader. It has this because
- * we passed it in when we registered the open routine.
- * The open_file_* routines should return:
- * -1 on an I/O error;
- * 1 if the file they're reading is one of the types it handles;
- * 0 if the file they're reading isn't the type they're checking for.
- * If the routine handles this type of file, it should set the "file_type"
- * field in the "struct wtap" to the type of the file.
- */
-static wtap_open_return_val
-wslua_filehandler_open(wtap *wth, int *err, gchar **err_info)
-{
- FileHandler fh = (FileHandler)(wth->wslua_data);
- wtap_open_return_val retval = WTAP_OPEN_NOT_MINE;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfo *fc = NULL;
-
- INIT_FILEHANDLER_ROUTINE(read_open,WTAP_OPEN_NOT_MINE);
-
- create_wth_priv(L, wth);
-
- fp = push_File(L, wth->fh);
- fc = push_CaptureInfo(L, wth, TRUE);
-
- errno = WTAP_ERR_CANT_OPEN;
- switch ( lua_pcall(L,2,1,1) ) {
- case 0:
- retval = (wtap_open_return_val)wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR_ERRINFO("read_open")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
-
- if (retval == WTAP_OPEN_MINE) {
- /* this is our file type - set the routines and settings into wtap */
-
- if (fh->read_ref != LUA_NOREF) {
- wth->subtype_read = wslua_filehandler_read;
- }
- else {
- g_warning("Lua file format module lacks a read routine");
- return WTAP_OPEN_NOT_MINE;
- }
-
- if (fh->seek_read_ref != LUA_NOREF) {
- wth->subtype_seek_read = wslua_filehandler_seek_read;
- }
- else {
- g_warning("Lua file format module lacks a seek-read routine");
- return WTAP_OPEN_NOT_MINE;
- }
-
- /* it's ok to not have a close routine */
- if (fh->read_close_ref != LUA_NOREF)
- wth->subtype_close = wslua_filehandler_close;
- else
- wth->subtype_close = NULL;
-
- /* it's ok to not have a sequential close routine */
- if (fh->seq_read_close_ref != LUA_NOREF)
- wth->subtype_sequential_close = wslua_filehandler_sequential_close;
- else
- wth->subtype_sequential_close = NULL;
-
- wth->file_type_subtype = fh->file_type;
- }
- else if (retval == WTAP_OPEN_ERROR) {
- /* open error - we *must* return an error code! */
- if (err) {
- *err = WTAP_ERR_CANT_OPEN;
- }
- }
- else if (retval == WTAP_OPEN_NOT_MINE) {
- /* not our file type */
- remove_wth_priv(L, wth);
- }
- else {
- /* not a valid return type */
- g_warning("FileHandler read_open routine returned %d", retval);
- if (err) {
- *err = WTAP_ERR_INTERNAL;
- }
- retval = WTAP_OPEN_ERROR;
- }
-
- lua_settop(L,0);
- return retval;
-}
-
-/* The classic wtap read routine. This returns TRUE if it found the next packet,
- * else FALSE.
- * If it finds a frame/packet, it should set the pseudo-header info (ie, let Lua set it).
- * Also Lua needs to set data_offset to the beginning of the line we're returning.
- * This will be the seek_off parameter when this frame is re-read.
-*/
-static gboolean
-wslua_filehandler_read(wtap *wth, int *err, gchar **err_info,
- gint64 *data_offset)
-{
- FileHandler fh = (FileHandler)(wth->wslua_data);
- int retval = -1;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfo *fc = NULL;
- FrameInfo *fi = NULL;
-
- INIT_FILEHANDLER_ROUTINE(read,FALSE);
-
- /* Reset errno */
- if (err) {
- *err = errno = 0;
- }
-
- wth->phdr.opt_comment = NULL;
-
- fp = push_File(L, wth->fh);
- fc = push_CaptureInfo(L, wth, FALSE);
- fi = push_FrameInfo(L, &wth->phdr, wth->frame_buffer);
-
- switch ( lua_pcall(L,3,1,1) ) {
- case 0:
- if (lua_isnumber(L,-1)) {
- *data_offset = wslua_togint64(L, -1);
- retval = 1;
- break;
- }
- retval = wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR_ERRINFO("read")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
- (*fi)->expired = TRUE;
- lua_settop(L,0);
-
- return (retval == 1);
-}
-
-/* Classic wtap seek_read function, called by wtap core. This must return TRUE on
- * success, FALSE on error.
- */
-static gboolean
-wslua_filehandler_seek_read(wtap *wth, gint64 seek_off,
- struct wtap_pkthdr *phdr, Buffer *buf,
- int *err, gchar **err_info)
-{
- FileHandler fh = (FileHandler)(wth->wslua_data);
- int retval = -1;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfo *fc = NULL;
- FrameInfo *fi = NULL;
-
- INIT_FILEHANDLER_ROUTINE(seek_read,FALSE);
-
- /* Reset errno */
- if (err) {
- *err = errno = 0;
- }
- phdr->opt_comment = NULL;
-
- fp = push_File(L, wth->random_fh);
- fc = push_CaptureInfo(L, wth, FALSE);
- fi = push_FrameInfo(L, phdr, buf);
- lua_pushnumber(L, (lua_Number)seek_off);
-
- switch ( lua_pcall(L,4,1,1) ) {
- case 0:
- if (lua_isstring(L,-1)) {
- size_t len = 0;
- const gchar* fd = lua_tolstring(L, -1, &len);
- if (len < WTAP_MAX_PACKET_SIZE)
- memcpy(ws_buffer_start_ptr(buf), fd, len);
- retval = 1;
- break;
- }
- retval = wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR_ERRINFO("seek_read")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
- (*fi)->expired = TRUE;
- lua_settop(L,0);
-
- return (retval == 1);
-}
-
-/* Classic wtap close function, called by wtap core.
- */
-static void
-wslua_filehandler_close(wtap *wth)
-{
- FileHandler fh = (FileHandler)(wth->wslua_data);
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfo *fc = NULL;
-
- INIT_FILEHANDLER_ROUTINE(read_close,);
-
- fp = push_File(L, wth->fh);
- fc = push_CaptureInfo(L, wth, FALSE);
-
- switch ( lua_pcall(L,2,1,1) ) {
- case 0:
- break;
- CASE_ERROR("read_close")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- remove_wth_priv(L, wth);
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
- lua_settop(L,0);
-
- return;
-}
-
-/* Classic wtap sequential close function, called by wtap core.
- */
-static void
-wslua_filehandler_sequential_close(wtap *wth)
-{
- FileHandler fh = (FileHandler)(wth->wslua_data);
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfo *fc = NULL;
-
- INIT_FILEHANDLER_ROUTINE(seq_read_close,);
-
- fp = push_File(L, wth->fh);
- fc = push_CaptureInfo(L, wth, FALSE);
-
- switch ( lua_pcall(L,2,1,1) ) {
- case 0:
- break;
- CASE_ERROR("seq_read_close")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
- lua_settop(L,0);
-
- return;
-}
-
-
-/* basically a dummy function to use for can_write_encap so that the caller calls
- * wslua_can_write_encap instead (which will be wslua_filehandler_can_write_encap)
- */
-static int
-wslua_dummy_can_write_encap(int encap _U_)
-{
- return WTAP_ERR_CHECK_WSLUA;
-}
-
-/* Similar to the classic wtap can_write_encap function.
- * This returns 0 if the encap is ok for this file type.
- */
-static int
-wslua_filehandler_can_write_encap(int encap, void* data)
-{
- FileHandler fh = (FileHandler)(data);
- int retval = WTAP_ERR_UNWRITABLE_ENCAP;
- lua_State* L = NULL;
-
- INIT_FILEHANDLER_ROUTINE(can_write_encap,WTAP_ERR_INTERNAL);
-
- lua_pushnumber(L, encap);
-
- switch ( lua_pcall(L,1,1,1) ) {
- case 0:
- retval = wslua_optboolint(L,-1,WTAP_ERR_UNWRITABLE_ENCAP);
- break;
- CASE_ERROR("can_write_encap")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- /* the retval we got was either a 1 for true, 0 for false, or WTAP_ERR_UNWRITABLE_ENCAP;
- but can_write_encap() expects 0 to be true/yes */
- if (retval == 1) {
- retval = 0;
- } else if (retval == 0) {
- retval = WTAP_ERR_UNWRITABLE_ENCAP;
- }
-
- return retval;
-}
-
-/* some declarations */
-static gboolean
-wslua_filehandler_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
- const guint8 *pd, int *err, gchar **err_info);
-static gboolean
-wslua_filehandler_dump_close(wtap_dumper *wdh, int *err);
-
-
-/* The classic wtap dump_open function.
- * This returns 1 (TRUE) on success.
- */
-static int
-wslua_filehandler_dump_open(wtap_dumper *wdh, int *err)
-{
- FileHandler fh = (FileHandler)(wdh->wslua_data);
- int retval = 0;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfoConst *fc = NULL;
-
- INIT_FILEHANDLER_ROUTINE(write_open,0);
-
- create_wdh_priv(L, wdh);
-
- fp = push_Wdh(L, wdh);
- fc = push_CaptureInfoConst(L,wdh);
-
- /* Reset err */
- if (err) {
- *err = 0;
- }
-
- switch ( lua_pcall(L,2,1,1) ) {
- case 0:
- retval = wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR("write_open")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
-
- if (retval == 1) {
- /* this is our file type - set the routines and settings into wtap */
-
- if (fh->write_ref != LUA_NOREF) {
- wdh->subtype_write = wslua_filehandler_dump;
- }
- else {
- g_warning("FileHandler was not set with a write function, even though write_open() returned true");
- return 0;
- }
-
- /* it's ok to not have a close routine */
- if (fh->write_close_ref != LUA_NOREF)
- wdh->subtype_close = wslua_filehandler_dump_close;
- else
- wdh->subtype_close = NULL;
- }
- else {
- /* not our file type? */
- remove_wdh_priv(L, wdh);
- }
-
- return retval;
-}
-
-/* The classic wtap dump routine. This returns TRUE if it writes the current packet,
- * else FALSE.
-*/
-static gboolean
-wslua_filehandler_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
- const guint8 *pd, int *err, gchar **err_info _U_)
-{
- FileHandler fh = (FileHandler)(wdh->wslua_data);
- int retval = -1;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfoConst *fc = NULL;
- FrameInfoConst *fi = NULL;
-
- INIT_FILEHANDLER_ROUTINE(write,FALSE);
-
- /* Reset errno */
- if (err) {
- *err = errno = 0;
- }
-
- fp = push_Wdh(L, wdh);
- fc = push_CaptureInfoConst(L,wdh);
- fi = push_FrameInfoConst(L, phdr, pd);
-
- errno = WTAP_ERR_CANT_WRITE;
- switch ( lua_pcall(L,3,1,1) ) {
- case 0:
- retval = wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR("write")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
- (*fi)->expired = TRUE;
-
- return (retval == 1);
-}
-
-/* The classic wtap dump_close routine. This returns TRUE if it closes cleanly,
- * else FALSE.
-*/
-static gboolean
-wslua_filehandler_dump_close(wtap_dumper *wdh, int *err)
-{
- FileHandler fh = (FileHandler)(wdh->wslua_data);
- int retval = -1;
- lua_State* L = NULL;
- File *fp = NULL;
- CaptureInfoConst *fc = NULL;
-
- INIT_FILEHANDLER_ROUTINE(write_close,FALSE);
-
- /* Reset errno */
- if (err) {
- *err = errno = 0;
- }
-
- fp = push_Wdh(L, wdh);
- fc = push_CaptureInfoConst(L,wdh);
-
- errno = WTAP_ERR_CANT_CLOSE;
- switch ( lua_pcall(L,2,1,1) ) {
- case 0:
- retval = wslua_optboolint(L,-1,0);
- break;
- CASE_ERROR("write_close")
- }
-
- END_FILEHANDLER_ROUTINE();
-
- remove_wdh_priv(L, wdh);
-
- (*fp)->expired = TRUE;
- (*fc)->expired = TRUE;
-
- return (retval == 1);
-}
-
-
-WSLUA_CONSTRUCTOR FileHandler_new(lua_State* L) {
- /* Creates a new FileHandler */
-#define WSLUA_ARG_FileHandler_new_NAME 1 /* The name of the file type, for display purposes only. E.g., "Wireshark - pcapng" */
-#define WSLUA_ARG_FileHandler_new_SHORTNAME 2 /* the file type short name, used as a shortcut in various places. E.g., "pcapng". Note: the name cannot already be in use. */
-#define WSLUA_ARG_FileHandler_new_DESCRIPTION 3 /* Descriptive text about this file format, for display purposes only */
-#define WSLUA_ARG_FileHandler_new_TYPE 4 /* The type of FileHandler, "r"/"w"/"rw" for reader/writer/both, include "m" for magic, "s" for strong heuristic */
-
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_NAME);
- const gchar* short_name = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_SHORTNAME);
- const gchar* desc = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_DESCRIPTION);
- const gchar* type = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_TYPE);
- FileHandler fh = (FileHandler) g_malloc0(sizeof(struct _wslua_filehandler));
-
- fh->is_reader = (strchr(type,'r') != NULL) ? TRUE : FALSE;
- fh->is_writer = (strchr(type,'w') != NULL) ? TRUE : FALSE;
-
- if (fh->is_reader && wtap_has_open_info(short_name)) {
- return luaL_error(L, "FileHandler.new: '%s' short name already exists for a reader!", short_name);
- }
-
- if (fh->is_writer && wtap_short_string_to_file_type_subtype(short_name) > -1) {
- return luaL_error(L, "FileHandler.new: '%s' short name already exists for a writer!", short_name);
- }
-
- fh->type = g_strdup(type);
- fh->finfo.name = g_strdup(name);
- fh->finfo.short_name = g_strdup(short_name);
- fh->finfo.default_file_extension = NULL;
- fh->finfo.additional_file_extensions = NULL;
- fh->finfo.writing_must_seek = FALSE;
- fh->finfo.has_name_resolution = FALSE;
- fh->finfo.can_write_encap = NULL;
- fh->finfo.dump_open = NULL;
- /* this will be set to a new file_type when registered */
- fh->file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
-
- fh->description = g_strdup(desc);
- fh->L = L;
- fh->read_open_ref = LUA_NOREF;
- fh->read_ref = LUA_NOREF;
- fh->seek_read_ref = LUA_NOREF;
- fh->read_close_ref = LUA_NOREF;
- fh->seq_read_close_ref = LUA_NOREF;
- fh->write_open_ref = LUA_NOREF;
- fh->write_ref = LUA_NOREF;
- fh->write_close_ref = LUA_NOREF;
- fh->can_write_encap_ref = LUA_NOREF;
-
- fh->registered = FALSE;
-
- pushFileHandler(L,fh);
- WSLUA_RETURN(1); /* The newly created FileHandler object */
-}
-
-WSLUA_METAMETHOD FileHandler__tostring(lua_State* L) {
- /* Generates a string of debug info for the FileHandler */
- FileHandler fh = toFileHandler(L,1);
-
- if (!fh) {
- lua_pushstring(L,"FileHandler pointer is NULL!");
- } else {
- lua_pushfstring(L, "FileHandler(%s): short-name='%s', description='%s', read_open=%d, read=%d, write=%d",
- fh->finfo.name, fh->finfo.short_name, fh->description, fh->read_open_ref, fh->read_ref, fh->write_ref);
- }
-
- WSLUA_RETURN(1); /* String of debug information. */
-}
-
-static int FileHandler__gc(lua_State* L _U_) {
- /* do NOT free FileHandler, it's never free'd */
- /* TODO: handle this and other Lua things that should be free'd on exit, in a better way */
- return 0;
-}
-
-/* A Lua File handler must not be expired, and must be either a reader or writer, and
- * a *reader* one MUST at least define read_open, read, and seek_read funcs; and
- * a *writer* one MUST at least define can_write_encap, write_open, and write funcs
- */
-static gboolean verify_filehandler_complete(FileHandler fh) {
- return ((fh->is_reader || fh->is_writer) &&
- (!fh->is_reader ||
- (fh->is_reader &&
- fh->read_open_ref != LUA_NOREF &&
- fh->read_ref != LUA_NOREF &&
- fh->seek_read_ref != LUA_NOREF)) &&
- (!fh->is_writer ||
- (fh->is_writer &&
- fh->can_write_encap_ref != LUA_NOREF &&
- fh->write_open_ref != LUA_NOREF &&
- fh->write_ref != LUA_NOREF)) );
-}
-
-
-WSLUA_FUNCTION wslua_register_filehandler(lua_State* L) {
- /* Register the FileHandler into Wireshark/tshark, so they can read/write this new format.
- All functions and settings must be complete before calling this registration function.
- This function cannot be called inside the reading/writing callback functions. */
-#define WSLUA_ARG_register_filehandler_FILEHANDLER 1 /* the FileHandler object to be registered */
- FileHandler fh = checkFileHandler(L,WSLUA_ARG_register_filehandler_FILEHANDLER);
-
- if (in_routine)
- return luaL_error(L,"a FileHAndler cannot be registered during reading/writing callback functions");
-
- if (fh->registered)
- return luaL_error(L,"this FileHandler is already registered");
-
- if (!verify_filehandler_complete(fh))
- return luaL_error(L,"this FileHandler is not complete enough to register");
-
- if (fh->is_writer) {
- fh->finfo.can_write_encap = wslua_dummy_can_write_encap;
- fh->finfo.wslua_info = (wtap_wslua_file_info_t*) g_malloc0(sizeof(wtap_wslua_file_info_t));
- fh->finfo.wslua_info->wslua_can_write_encap = wslua_filehandler_can_write_encap;
- fh->finfo.wslua_info->wslua_data = (void*)(fh);
- fh->finfo.dump_open = wslua_filehandler_dump_open;
- }
-
- fh->file_type = wtap_register_file_type_subtypes(&(fh->finfo),fh->file_type);
-
- if (fh->is_reader) {
- struct open_info oi = { NULL, OPEN_INFO_HEURISTIC, NULL, NULL, NULL, NULL };
- oi.name = fh->finfo.short_name;
- oi.open_routine = wslua_filehandler_open;
- oi.extensions = fh->finfo.additional_file_extensions;
- oi.wslua_data = (void*)(fh);
- if (strchr(fh->type,'m') != NULL) {
- oi.type = OPEN_INFO_MAGIC;
- } else {
- oi.type = OPEN_INFO_HEURISTIC;
- }
- wtap_register_open_info(&oi, (strchr(fh->type,'s') != NULL));
- }
-
- fh->registered = TRUE;
-
- lua_pushnumber(L, fh->file_type);
-
- WSLUA_RETURN(1); /* the new type number for this file reader/write */
-}
-
-WSLUA_FUNCTION wslua_deregister_filehandler(lua_State* L) {
- /* De-register the FileHandler from Wireshark/tshark, so it no longer gets used for reading/writing/display.
- This function cannot be called inside the reading/writing callback functions. */
-#define WSLUA_ARG_register_filehandler_FILEHANDLER 1 /* the FileHandler object to be de-registered */
- FileHandler fh = checkFileHandler(L,WSLUA_ARG_register_filehandler_FILEHANDLER);
-
- if (in_routine)
- return luaL_error(L,"A FileHAndler cannot be de-registered during reading/writing callback functions");
-
- if (!fh->registered)
- return 0;
-
- /* undo writing stuff, even if it wasn't a writer */
- fh->finfo.can_write_encap = NULL;
- if (fh->finfo.wslua_info) {
- fh->finfo.wslua_info->wslua_can_write_encap = NULL;
- fh->finfo.wslua_info->wslua_data = NULL;
- g_free(fh->finfo.wslua_info);
- fh->finfo.wslua_info = NULL;
- }
- fh->finfo.dump_open = NULL;
-
- if (fh->file_type != WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
- wtap_deregister_file_type_subtype(fh->file_type);
-
- if (fh->is_reader && wtap_has_open_info(fh->finfo.short_name)) {
- wtap_deregister_open_info(fh->finfo.short_name);
- }
-
- fh->registered = FALSE;
-
- return 0;
-}
-
-/* The folllowing macros generate setter functions for Lua, for the following Lua
- function references in _wslua_filehandler struct:
- int read_open_ref;
- int read_ref;
- int seek_read_ref;
- int read_close_ref;
- int seq_read_close_ref;
- int can_write_encap_ref;
- int write_open_ref;
- int write_ref;
- int write_close_ref;
-*/
-
-/* WSLUA_ATTRIBUTE FileHandler_read_open WO The Lua function to be called when Wireshark opens a file for reading.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfo` object
-
- The purpose of the Lua function set to this `read_open` field is to check if the file Wireshark is opening is of its type,
- for example by checking for magic numbers or trying to parse records in the file, etc. The more can be verified
- the better, because Wireshark tries all file readers until it finds one that accepts the file, so accepting an
- incorrect file prevents other file readers from reading their files.
-
- The called Lua function should return true if the file is its type (it accepts it), false if not. The Lua
- function must also set the File offset position (using `file:seek()`) to where it wants it to be for its first
- `read()` call.
- */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read_open);
-
-/* WSLUA_ATTRIBUTE FileHandler_read WO The Lua function to be called when Wireshark wants to read a packet from the file.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfo` object
- 3. A `FrameInfo` object
-
- The purpose of the Lua function set to this `read` field is to read the next packet from the file, and setting the parsed/read
- packet into the frame buffer using `FrameInfo.data = foo` or `FrameInfo:read_data()`.
-
- The called Lua function should return the file offset/position number where the packet begins, or false if it hit an
- error. The file offset will be saved by Wireshark and passed into the set `seek_read()` Lua function later. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read);
-
-/* WSLUA_ATTRIBUTE FileHandler_seek_read WO The Lua function to be called when Wireshark wants to read a packet from the file at the given offset.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfo` object
- 3. A `FrameInfo` object
- 4. The file offset number previously set by the `read()` function call
- */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,seek_read);
-
-/* WSLUA_ATTRIBUTE FileHandler_read_close WO The Lua function to be called when Wireshark wants to close the read file completely.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfo` object
-
- It is not necessary to set this field to a Lua function - FileHandler can be registered without doing so - it
- is available in case there is memory/state to clear in your script when the file is closed. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read_close);
-
-/* WSLUA_ATTRIBUTE FileHandler_seq_read_close WO The Lua function to be called when Wireshark wants to close the sequentially-read file.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfo` object
-
- It is not necessary to set this field to a Lua
- function - FileHandler can be registered without doing so - it is available in case there is memory/state to clear in your script
- when the file is closed for the sequential reading portion. After this point, there will be no more calls to `read()`, only `seek_read()`. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,seq_read_close);
-
-
-/* WSLUA_ATTRIBUTE FileHandler_can_write_encap WO The Lua function to be called when Wireshark wants to write a file,
- by checking if this file writer can handle the wtap packet encapsulation(s).
-
- When later called by Wireshark, the Lua function will be given a Lua number, which matches one of the encapsulations
- in the Lua `wtap_encaps` table. This might be the `wtap_encap.PER_PACKET` number, meaning the capture contains multiple
- encapsulation types, and the file reader should only return true if it can handle multiple encap types in one file. The
- function will then be called again, once for each encap type in the file, to make sure it can write each one.
-
- If the Lua file writer can write the given type of encapsulation into a file, then it returns the boolean true, else false. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,can_write_encap);
-
-/* WSLUA_ATTRIBUTE FileHandler_write_open WO The Lua function to be called when Wireshark opens a file for writing.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfoConst` object
-
- The purpose of the Lua function set to this `write_open` field is similar to the read_open callback function:
- to initialize things necessary for writing the capture to a file. For example, if the output file format has a
- file header, then the file header should be written within this write_open function.
-
- The called Lua function should return true on success, or false if it hit an error.
-
- Also make sure to set the `FileHandler.write` (and potentially `FileHandler.write_close`) functions before
- returning true from this function. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write_open);
-
-/* WSLUA_ATTRIBUTE FileHandler_write WO The Lua function to be called when Wireshark wants to write a packet to the file.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfoConst` object
- 3. A `FrameInfoConst` object of the current frame/packet to be written
-
- The purpose of the Lua function set to this `write` field is to write the next packet to the file.
-
- The called Lua function should return true on success, or false if it hit an error. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write);
-
-/* WSLUA_ATTRIBUTE FileHandler_write_close WO The Lua function to be called when Wireshark wants to close the written file.
-
- When later called by Wireshark, the Lua function will be given:
- 1. A `File` object
- 2. A `CaptureInfoConst` object
-
- It is not necessary to set this field to a Lua function - `FileHandler` can be registered without doing so - it is available
- in case there is memory/state to clear in your script when the file is closed. */
-WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write_close);
-
-/* generate other member accessors setters/getters */
-
-/* WSLUA_ATTRIBUTE FileHandler_type RO The internal file type. This is automatically set with a new
- number when the FileHandler is registered. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FileHandler,type,file_type);
-
-/* WSLUA_ATTRIBUTE FileHandler_extensions RW One or more file extensions that this file type usually uses.
-
- For readers using heuristics to determine file type, Wireshark will try the readers of the file's
- extension first, before trying other readers. But ultimately Wireshark tries all file readers
- for any file extension, until it finds one that accepts the file. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FileHandler,extensions,finfo.additional_file_extensions);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(FileHandler,extensions,finfo.additional_file_extensions,TRUE);
-
-/* WSLUA_ATTRIBUTE FileHandler_writing_must_seek RW true if the ability to seek is required when writing
- this file format, else false.
-
- This will be checked by Wireshark when writing out to compressed
- file formats, because seeking is not possible with compressed files. Usually a file writer only
- needs to be able to seek if it needs to go back in the file to change something, such as a block or
- file length value earlier in the file. */
-WSLUA_ATTRIBUTE_NAMED_BOOLEAN_GETTER(FileHandler,writing_must_seek,finfo.writing_must_seek);
-WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(FileHandler,writing_must_seek,finfo.writing_must_seek);
-
-/* WSLUA_ATTRIBUTE FileHandler_writes_name_resolution RW true if the file format supports name resolution
- records, else false. */
-WSLUA_ATTRIBUTE_NAMED_BOOLEAN_GETTER(FileHandler,writes_name_resolution,finfo.has_name_resolution);
-WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(FileHandler,writes_name_resolution,finfo.has_name_resolution);
-
-/* WSLUA_ATTRIBUTE FileHandler_supported_comment_types RW set to the bit-wise OR'ed number representing
- the type of comments the file writer supports writing, based on the numbers in the `wtap_comments` table. */
-WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FileHandler,supported_comment_types,finfo.supported_comment_types);
-WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FileHandler,supported_comment_types,finfo.supported_comment_types,guint32);
-
-/* This table is ultimately registered as a sub-table of the class' metatable,
- * and if __index/__newindex is invoked then it calls the appropriate function
- * from this table for getting/setting the members.
- */
-WSLUA_ATTRIBUTES FileHandler_attributes[] = {
- WSLUA_ATTRIBUTE_WOREG(FileHandler,read_open),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,read),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,seek_read),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,read_close),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,seq_read_close),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,can_write_encap),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,write_open),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,write),
- WSLUA_ATTRIBUTE_WOREG(FileHandler,write_close),
- WSLUA_ATTRIBUTE_ROREG(FileHandler,type),
- WSLUA_ATTRIBUTE_RWREG(FileHandler,extensions),
- WSLUA_ATTRIBUTE_RWREG(FileHandler,writing_must_seek),
- WSLUA_ATTRIBUTE_RWREG(FileHandler,writes_name_resolution),
- WSLUA_ATTRIBUTE_RWREG(FileHandler,supported_comment_types),
- { NULL, NULL, NULL }
-};
-
-WSLUA_METHODS FileHandler_methods[] = {
- WSLUA_CLASS_FNREG(FileHandler,new),
- { NULL, NULL }
-};
-
-WSLUA_META FileHandler_meta[] = {
- WSLUA_CLASS_MTREG(FileHandler,tostring),
- { NULL, NULL }
-};
-
-int FileHandler_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(FileHandler);
- WSLUA_REGISTER_ATTRIBUTES(FileHandler);
- return 0;
-}
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/wslua/wslua_file_common.c b/epan/wslua/wslua_file_common.c
new file mode 100644
index 0000000000..8b3bb99a4a
--- /dev/null
+++ b/epan/wslua/wslua_file_common.c
@@ -0,0 +1,205 @@
+/*
+ * wslua_file_common.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ * for file handling related source file internal functions.
+ *
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/************
+ * The following is for handling private data for the duration of the file
+ * read_open/read/close cycle, or write_open/write/write_close cycle.
+ * In other words it handles the "priv" member of wtap and wtap_dumper,
+ * but for the Lua script's use. A Lua script can set a Lua table
+ * to CaptureInfo/CaptureInfoConst and have it saved and retrievable this way.
+ * We need to offer that, because there needs to be a way for Lua scripts
+ * to save state for a given file's operations cycle. Since there can be
+ * two files opened at the same time for the same Lua script (due to reload
+ * and other such events), the script can't just have one file state.
+ */
+
+#include "wslua_file_common.h"
+
+
+/* create and set the wtap->priv private data for the file instance */
+void create_wth_priv(lua_State* L, wtap *wth) {
+ file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
+
+ if (wth->priv != NULL) {
+ luaL_error(L, "Cannot create wtap private data because there already is private data");
+ return;
+ }
+ priv->table_ref = LUA_NOREF;
+ wth->priv = (void*) priv;
+}
+
+/* gets the private data table from wtap */
+int get_wth_priv_table_ref(lua_State* L, wtap *wth) {
+ file_priv_t *priv = (file_priv_t*) wth->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot get wtap private data: it is null");
+ return LUA_NOREF;
+ }
+
+ /* the following might push a nil, but that's ok */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
+
+ return 1;
+}
+
+/* sets the private data to wtap - the table is presumed on top of stack */
+int set_wth_priv_table_ref(lua_State* L, wtap *wth) {
+ file_priv_t *priv = (file_priv_t*) wth->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot get wtap private data: it is null");
+ return 0;
+ }
+
+ if (lua_isnil(L, -1)){
+ /* user is setting it nil - ok, de-ref any previous one */
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+ priv->table_ref = LUA_NOREF;
+ return 0;
+ }
+
+ if (!lua_istable(L, -1)) {
+ luaL_error(L, "The private_table member can only be set to a table or nil");
+ return 0;
+ }
+
+ /* if we had a table already referenced, de-ref it first */
+ if (priv->table_ref != LUA_NOREF) {
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+ }
+
+ priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ return 0;
+}
+
+/* remove, deref, and free the wtap->priv data */
+void remove_wth_priv(lua_State* L, wtap *wth) {
+ file_priv_t *priv = (file_priv_t*) wth->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot remove wtap private data: it is null");
+ return;
+ }
+
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+
+ g_free(wth->priv);
+ wth->priv = NULL;
+}
+
+/* create and set the wtap_dumper->priv private data for the file instance */
+void create_wdh_priv(lua_State* L, wtap_dumper *wdh) {
+ file_priv_t *priv = (file_priv_t*)g_malloc(sizeof(file_priv_t));
+
+ if (wdh->priv != NULL) {
+ luaL_error(L, "Cannot create wtap_dumper private data because there already is private data");
+ return;
+ }
+ priv->table_ref = LUA_NOREF;
+ wdh->priv = (void*) priv;
+}
+
+/* get the private data from wtap_dumper */
+int get_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
+ file_priv_t *priv = (file_priv_t*) wdh->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot get wtap_dumper private data: it is null");
+ return LUA_NOREF;
+ }
+
+ /* the following might push a nil, but that's ok */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, priv->table_ref);
+
+ return 1;
+}
+
+/* sets the private data to wtap - the table is presumed on top of stack */
+int set_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh) {
+ file_priv_t *priv = (file_priv_t*) wdh->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot get wtap private data: it is null");
+ return 0;
+ }
+
+ if (lua_isnil(L, -1)){
+ /* user is setting it nil - ok, de-ref any previous one */
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+ priv->table_ref = LUA_NOREF;
+ return 0;
+ }
+
+ if (!lua_istable(L, -1)) {
+ luaL_error(L, "The private_table member can only be set to a table or nil");
+ return 0;
+ }
+
+ /* if we had a table already referenced, de-ref it first */
+ if (priv->table_ref != LUA_NOREF) {
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+ }
+
+ priv->table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ return 0;
+}
+
+/* remove and deref the wtap_dumper->priv data */
+void remove_wdh_priv(lua_State* L, wtap_dumper *wdh) {
+ file_priv_t *priv = (file_priv_t*) wdh->priv;
+
+ if (!priv) {
+ /* shouldn't be possible */
+ luaL_error(L, "Cannot remove wtap_dumper private data: it is null");
+ return;
+ }
+
+ luaL_unref(L, LUA_REGISTRYINDEX, priv->table_ref);
+ /* we do NOT free wtap_dumper's priv member - wtap_dump_close() free's it */
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_file_common.h b/epan/wslua/wslua_file_common.h
new file mode 100644
index 0000000000..f581e8dc2b
--- /dev/null
+++ b/epan/wslua/wslua_file_common.h
@@ -0,0 +1,86 @@
+/*
+ * wslua_file_common.h
+ *
+ * Wireshark's interface to the Lua Programming Language
+ * for file handling related source files.
+ *
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/* See wslua_file_common.c for details */
+
+#include "config.h"
+
+#include "wslua.h"
+#include <wiretap/wtap-int.h>
+
+/* this is way overkill for this one member, but in case we need to add
+ more in the future, the plumbing will be here */
+typedef struct _file_priv_t {
+ int table_ref;
+} file_priv_t;
+
+/* create and set the wtap->priv private data for the file instance */
+extern void create_wth_priv(lua_State* L, wtap *wth);
+
+/* gets the private data table from wtap */
+extern int get_wth_priv_table_ref(lua_State* L, wtap *wth);
+
+/* sets the private data to wtap - the table is presumed on top of stack */
+extern int set_wth_priv_table_ref(lua_State* L, wtap *wth);
+
+/* remove, deref, and free the wtap->priv data */
+extern void remove_wth_priv(lua_State* L, wtap *wth);
+
+/* create and set the wtap_dumper->priv private data for the file instance */
+extern void create_wdh_priv(lua_State* L, wtap_dumper *wdh);
+
+/* get the private data from wtap_dumper */
+extern int get_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh);
+
+/* sets the private data to wtap - the table is presumed on top of stack */
+extern int set_wdh_priv_table_ref(lua_State* L, wtap_dumper *wdh);
+
+/* remove and deref the wtap_dumper->priv data */
+extern void remove_wdh_priv(lua_State* L, wtap_dumper *wdh);
+
+/* implemented in other c files than wslua_file_common.c */
+extern CaptureInfo* push_CaptureInfo(lua_State* L, wtap *wth, const gboolean first_time);
+extern CaptureInfoConst* push_CaptureInfoConst(lua_State* L, wtap_dumper *wdh);
+extern File* push_File(lua_State* L, FILE_T ft);
+extern File* push_Wdh(lua_State* L, wtap_dumper *wdh);
+extern FrameInfo* push_FrameInfo(lua_State* L, struct wtap_pkthdr *phdr, Buffer* buf);
+extern FrameInfoConst* push_FrameInfoConst(lua_State* L, const struct wtap_pkthdr *phdr, const guint8 *pd);
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_file_handler.c b/epan/wslua/wslua_file_handler.c
new file mode 100644
index 0000000000..1ea8cb4555
--- /dev/null
+++ b/epan/wslua/wslua_file_handler.c
@@ -0,0 +1,997 @@
+/*
+ * wslua_file_handler.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ * for custom file reading/writing.
+ *
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "wslua_file_common.h"
+
+
+/* WSLUA_CONTINUE_MODULE File */
+
+
+WSLUA_CLASS_DEFINE(FileHandler,NOP,NOP);
+/*
+ A FileHandler object, created by a call to FileHandler.new(arg1, arg2, ...).
+ The FileHandler object lets you create a file-format reader, or writer, or
+ both, by setting your own read_open/read or write_open/write functions.
+
+ @since 1.11.3
+ */
+
+static int filehandler_cb_error_handler(lua_State* L) {
+ const gchar* error = lua_tostring(L,1);
+ const gchar* functype = luaL_optstring(L, lua_upvalueindex(1), "UNKNOWN");
+ report_failure("Lua: Error During execution of FileHandler %s callback:\n %s",functype,error);
+ lua_pop(L, 1);
+ return 0;
+}
+
+static int push_error_handler(lua_State* L, const gchar* funcname) {
+ lua_pushstring(L, funcname);
+ lua_pushcclosure(L, filehandler_cb_error_handler, 1);
+ return 1;
+}
+
+
+/* During file routines, we cannot allow the FileHandler to get de-registered, since
+ that would change the GArray's in file_access.c and hilarity would ensue. So we
+ set this to true right before pcall(), and back to false afterwards */
+static gboolean in_routine = FALSE;
+
+/* This does the verification and setup common to all open/read/seek_read/close routines */
+#define INIT_FILEHANDLER_ROUTINE(name,retval) \
+ if (!fh) { \
+ g_warning("Error in file %s: no Lua FileHandler object", #name); \
+ return retval; \
+ } \
+ if (!fh->registered) { \
+ g_warning("Error in file %s: Lua FileHandler is not registered", #name); \
+ return retval; \
+ } \
+ if (!fh->L) { \
+ g_warning("Error in file %s: no FileHandler Lua state", #name); \
+ return retval; \
+ } \
+ if (fh->name##_ref == LUA_NOREF) { \
+ g_warning("Error in file %s: no FileHandler %s routine reference", #name, #name); \
+ return retval; \
+ } \
+ L = fh->L; \
+ lua_settop(L,0); \
+ push_error_handler(L, #name " routine"); \
+ lua_rawgeti(L, LUA_REGISTRYINDEX, fh->name##_ref); \
+ if (!lua_isfunction(L, -1)) { \
+ g_warning("Error in file %s: no FileHandler %s routine function in Lua", #name, #name); \
+ return retval; \
+ } \
+ /* now guard against de-registering during pcall() */ \
+ in_routine = TRUE;
+
+#define END_FILEHANDLER_ROUTINE() \
+ /* now allow de-registering again */ \
+ in_routine = TRUE;
+
+
+/* LUA_ERRGCMM is in Lua 5.2 only - making it 9 disables it */
+#ifndef LUA_ERRGCMM
+#define LUA_ERRGCMM 9
+#endif
+
+#define CASE_ERROR(name) \
+ case LUA_ERRRUN: \
+ g_warning("Run-time error while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRMEM: \
+ g_warning("Memory alloc error while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRERR: \
+ g_warning("Error in error handling while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRGCMM: \
+ g_warning("Error in garbage collector while calling FileHandler %s routine", name); \
+ break; \
+ default: \
+ g_assert_not_reached(); \
+ break;
+
+#define CASE_ERROR_ERRINFO(name) \
+ case LUA_ERRRUN: \
+ g_warning("Run-time error while calling FileHandler %s routine", name); \
+ *err_info = g_strdup_printf("Run-time error while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRMEM: \
+ g_warning("Memory alloc error while calling FileHandler %s routine", name); \
+ *err_info = g_strdup_printf("Memory alloc error while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRERR: \
+ g_warning("Error in error handling while calling FileHandler %s routine", name); \
+ *err_info = g_strdup_printf("Error in error handling while calling FileHandler %s routine", name); \
+ break; \
+ case LUA_ERRGCMM: \
+ g_warning("Error in garbage collector while calling FileHandler %s routine", name); \
+ *err_info = g_strdup_printf("Error in garbage collector while calling FileHandler %s routine", name); \
+ break; \
+ default: \
+ g_assert_not_reached(); \
+ break;
+
+
+/* some declarations */
+static gboolean
+wslua_filehandler_read(wtap *wth, int *err, gchar **err_info,
+ gint64 *data_offset);
+static gboolean
+wslua_filehandler_seek_read(wtap *wth, gint64 seek_off,
+ struct wtap_pkthdr *phdr, Buffer *buf,
+ int *err, gchar **err_info);
+static void
+wslua_filehandler_close(wtap *wth);
+static void
+wslua_filehandler_sequential_close(wtap *wth);
+
+
+/* This is our one-and-only open routine for file handling. When called by
+ * file_access.c, the wtap wth argument has a void* wslua_data that holds the specific
+ * FileHandler for the specific registered file format reader. It has this because
+ * we passed it in when we registered the open routine.
+ * The open_file_* routines should return:
+ * -1 on an I/O error;
+ * 1 if the file they're reading is one of the types it handles;
+ * 0 if the file they're reading isn't the type they're checking for.
+ * If the routine handles this type of file, it should set the "file_type"
+ * field in the "struct wtap" to the type of the file.
+ */
+static wtap_open_return_val
+wslua_filehandler_open(wtap *wth, int *err, gchar **err_info)
+{
+ FileHandler fh = (FileHandler)(wth->wslua_data);
+ wtap_open_return_val retval = WTAP_OPEN_NOT_MINE;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfo *fc = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(read_open,WTAP_OPEN_NOT_MINE);
+
+ create_wth_priv(L, wth);
+
+ fp = push_File(L, wth->fh);
+ fc = push_CaptureInfo(L, wth, TRUE);
+
+ errno = WTAP_ERR_CANT_OPEN;
+ switch ( lua_pcall(L,2,1,1) ) {
+ case 0:
+ retval = (wtap_open_return_val)wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR_ERRINFO("read_open")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+
+ if (retval == WTAP_OPEN_MINE) {
+ /* this is our file type - set the routines and settings into wtap */
+
+ if (fh->read_ref != LUA_NOREF) {
+ wth->subtype_read = wslua_filehandler_read;
+ }
+ else {
+ g_warning("Lua file format module lacks a read routine");
+ return WTAP_OPEN_NOT_MINE;
+ }
+
+ if (fh->seek_read_ref != LUA_NOREF) {
+ wth->subtype_seek_read = wslua_filehandler_seek_read;
+ }
+ else {
+ g_warning("Lua file format module lacks a seek-read routine");
+ return WTAP_OPEN_NOT_MINE;
+ }
+
+ /* it's ok to not have a close routine */
+ if (fh->read_close_ref != LUA_NOREF)
+ wth->subtype_close = wslua_filehandler_close;
+ else
+ wth->subtype_close = NULL;
+
+ /* it's ok to not have a sequential close routine */
+ if (fh->seq_read_close_ref != LUA_NOREF)
+ wth->subtype_sequential_close = wslua_filehandler_sequential_close;
+ else
+ wth->subtype_sequential_close = NULL;
+
+ wth->file_type_subtype = fh->file_type;
+ }
+ else if (retval == WTAP_OPEN_ERROR) {
+ /* open error - we *must* return an error code! */
+ if (err) {
+ *err = WTAP_ERR_CANT_OPEN;
+ }
+ }
+ else if (retval == WTAP_OPEN_NOT_MINE) {
+ /* not our file type */
+ remove_wth_priv(L, wth);
+ }
+ else {
+ /* not a valid return type */
+ g_warning("FileHandler read_open routine returned %d", retval);
+ if (err) {
+ *err = WTAP_ERR_INTERNAL;
+ }
+ retval = WTAP_OPEN_ERROR;
+ }
+
+ lua_settop(L,0);
+ return retval;
+}
+
+/* The classic wtap read routine. This returns TRUE if it found the next packet,
+ * else FALSE.
+ * If it finds a frame/packet, it should set the pseudo-header info (ie, let Lua set it).
+ * Also Lua needs to set data_offset to the beginning of the line we're returning.
+ * This will be the seek_off parameter when this frame is re-read.
+*/
+static gboolean
+wslua_filehandler_read(wtap *wth, int *err, gchar **err_info,
+ gint64 *data_offset)
+{
+ FileHandler fh = (FileHandler)(wth->wslua_data);
+ int retval = -1;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfo *fc = NULL;
+ FrameInfo *fi = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(read,FALSE);
+
+ /* Reset errno */
+ if (err) {
+ *err = errno = 0;
+ }
+
+ wth->phdr.opt_comment = NULL;
+
+ fp = push_File(L, wth->fh);
+ fc = push_CaptureInfo(L, wth, FALSE);
+ fi = push_FrameInfo(L, &wth->phdr, wth->frame_buffer);
+
+ switch ( lua_pcall(L,3,1,1) ) {
+ case 0:
+ if (lua_isnumber(L,-1)) {
+ *data_offset = wslua_togint64(L, -1);
+ retval = 1;
+ break;
+ }
+ retval = wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR_ERRINFO("read")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+ (*fi)->expired = TRUE;
+ lua_settop(L,0);
+
+ return (retval == 1);
+}
+
+/* Classic wtap seek_read function, called by wtap core. This must return TRUE on
+ * success, FALSE on error.
+ */
+static gboolean
+wslua_filehandler_seek_read(wtap *wth, gint64 seek_off,
+ struct wtap_pkthdr *phdr, Buffer *buf,
+ int *err, gchar **err_info)
+{
+ FileHandler fh = (FileHandler)(wth->wslua_data);
+ int retval = -1;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfo *fc = NULL;
+ FrameInfo *fi = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(seek_read,FALSE);
+
+ /* Reset errno */
+ if (err) {
+ *err = errno = 0;
+ }
+ phdr->opt_comment = NULL;
+
+ fp = push_File(L, wth->random_fh);
+ fc = push_CaptureInfo(L, wth, FALSE);
+ fi = push_FrameInfo(L, phdr, buf);
+ lua_pushnumber(L, (lua_Number)seek_off);
+
+ switch ( lua_pcall(L,4,1,1) ) {
+ case 0:
+ if (lua_isstring(L,-1)) {
+ size_t len = 0;
+ const gchar* fd = lua_tolstring(L, -1, &len);
+ if (len < WTAP_MAX_PACKET_SIZE)
+ memcpy(ws_buffer_start_ptr(buf), fd, len);
+ retval = 1;
+ break;
+ }
+ retval = wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR_ERRINFO("seek_read")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+ (*fi)->expired = TRUE;
+ lua_settop(L,0);
+
+ return (retval == 1);
+}
+
+/* Classic wtap close function, called by wtap core.
+ */
+static void
+wslua_filehandler_close(wtap *wth)
+{
+ FileHandler fh = (FileHandler)(wth->wslua_data);
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfo *fc = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(read_close,);
+
+ fp = push_File(L, wth->fh);
+ fc = push_CaptureInfo(L, wth, FALSE);
+
+ switch ( lua_pcall(L,2,1,1) ) {
+ case 0:
+ break;
+ CASE_ERROR("read_close")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ remove_wth_priv(L, wth);
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+ lua_settop(L,0);
+
+ return;
+}
+
+/* Classic wtap sequential close function, called by wtap core.
+ */
+static void
+wslua_filehandler_sequential_close(wtap *wth)
+{
+ FileHandler fh = (FileHandler)(wth->wslua_data);
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfo *fc = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(seq_read_close,);
+
+ fp = push_File(L, wth->fh);
+ fc = push_CaptureInfo(L, wth, FALSE);
+
+ switch ( lua_pcall(L,2,1,1) ) {
+ case 0:
+ break;
+ CASE_ERROR("seq_read_close")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+ lua_settop(L,0);
+
+ return;
+}
+
+
+/* basically a dummy function to use for can_write_encap so that the caller calls
+ * wslua_can_write_encap instead (which will be wslua_filehandler_can_write_encap)
+ */
+static int
+wslua_dummy_can_write_encap(int encap _U_)
+{
+ return WTAP_ERR_CHECK_WSLUA;
+}
+
+/* Similar to the classic wtap can_write_encap function.
+ * This returns 0 if the encap is ok for this file type.
+ */
+static int
+wslua_filehandler_can_write_encap(int encap, void* data)
+{
+ FileHandler fh = (FileHandler)(data);
+ int retval = WTAP_ERR_UNWRITABLE_ENCAP;
+ lua_State* L = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(can_write_encap,WTAP_ERR_INTERNAL);
+
+ lua_pushnumber(L, encap);
+
+ switch ( lua_pcall(L,1,1,1) ) {
+ case 0:
+ retval = wslua_optboolint(L,-1,WTAP_ERR_UNWRITABLE_ENCAP);
+ break;
+ CASE_ERROR("can_write_encap")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ /* the retval we got was either a 1 for true, 0 for false, or WTAP_ERR_UNWRITABLE_ENCAP;
+ but can_write_encap() expects 0 to be true/yes */
+ if (retval == 1) {
+ retval = 0;
+ } else if (retval == 0) {
+ retval = WTAP_ERR_UNWRITABLE_ENCAP;
+ }
+
+ return retval;
+}
+
+/* some declarations */
+static gboolean
+wslua_filehandler_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const guint8 *pd, int *err, gchar **err_info);
+static gboolean
+wslua_filehandler_dump_close(wtap_dumper *wdh, int *err);
+
+
+/* The classic wtap dump_open function.
+ * This returns 1 (TRUE) on success.
+ */
+static int
+wslua_filehandler_dump_open(wtap_dumper *wdh, int *err)
+{
+ FileHandler fh = (FileHandler)(wdh->wslua_data);
+ int retval = 0;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfoConst *fc = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(write_open,0);
+
+ create_wdh_priv(L, wdh);
+
+ fp = push_Wdh(L, wdh);
+ fc = push_CaptureInfoConst(L,wdh);
+
+ /* Reset err */
+ if (err) {
+ *err = 0;
+ }
+
+ switch ( lua_pcall(L,2,1,1) ) {
+ case 0:
+ retval = wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR("write_open")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+
+ if (retval == 1) {
+ /* this is our file type - set the routines and settings into wtap */
+
+ if (fh->write_ref != LUA_NOREF) {
+ wdh->subtype_write = wslua_filehandler_dump;
+ }
+ else {
+ g_warning("FileHandler was not set with a write function, even though write_open() returned true");
+ return 0;
+ }
+
+ /* it's ok to not have a close routine */
+ if (fh->write_close_ref != LUA_NOREF)
+ wdh->subtype_close = wslua_filehandler_dump_close;
+ else
+ wdh->subtype_close = NULL;
+ }
+ else {
+ /* not our file type? */
+ remove_wdh_priv(L, wdh);
+ }
+
+ return retval;
+}
+
+/* The classic wtap dump routine. This returns TRUE if it writes the current packet,
+ * else FALSE.
+*/
+static gboolean
+wslua_filehandler_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+ const guint8 *pd, int *err, gchar **err_info _U_)
+{
+ FileHandler fh = (FileHandler)(wdh->wslua_data);
+ int retval = -1;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfoConst *fc = NULL;
+ FrameInfoConst *fi = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(write,FALSE);
+
+ /* Reset errno */
+ if (err) {
+ *err = errno = 0;
+ }
+
+ fp = push_Wdh(L, wdh);
+ fc = push_CaptureInfoConst(L,wdh);
+ fi = push_FrameInfoConst(L, phdr, pd);
+
+ errno = WTAP_ERR_CANT_WRITE;
+ switch ( lua_pcall(L,3,1,1) ) {
+ case 0:
+ retval = wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR("write")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+ (*fi)->expired = TRUE;
+
+ return (retval == 1);
+}
+
+/* The classic wtap dump_close routine. This returns TRUE if it closes cleanly,
+ * else FALSE.
+*/
+static gboolean
+wslua_filehandler_dump_close(wtap_dumper *wdh, int *err)
+{
+ FileHandler fh = (FileHandler)(wdh->wslua_data);
+ int retval = -1;
+ lua_State* L = NULL;
+ File *fp = NULL;
+ CaptureInfoConst *fc = NULL;
+
+ INIT_FILEHANDLER_ROUTINE(write_close,FALSE);
+
+ /* Reset errno */
+ if (err) {
+ *err = errno = 0;
+ }
+
+ fp = push_Wdh(L, wdh);
+ fc = push_CaptureInfoConst(L,wdh);
+
+ errno = WTAP_ERR_CANT_CLOSE;
+ switch ( lua_pcall(L,2,1,1) ) {
+ case 0:
+ retval = wslua_optboolint(L,-1,0);
+ break;
+ CASE_ERROR("write_close")
+ }
+
+ END_FILEHANDLER_ROUTINE();
+
+ remove_wdh_priv(L, wdh);
+
+ (*fp)->expired = TRUE;
+ (*fc)->expired = TRUE;
+
+ return (retval == 1);
+}
+
+
+WSLUA_CONSTRUCTOR FileHandler_new(lua_State* L) {
+ /* Creates a new FileHandler */
+#define WSLUA_ARG_FileHandler_new_NAME 1 /* The name of the file type, for display purposes only. E.g., "Wireshark - pcapng" */
+#define WSLUA_ARG_FileHandler_new_SHORTNAME 2 /* the file type short name, used as a shortcut in various places. E.g., "pcapng". Note: the name cannot already be in use. */
+#define WSLUA_ARG_FileHandler_new_DESCRIPTION 3 /* Descriptive text about this file format, for display purposes only */
+#define WSLUA_ARG_FileHandler_new_TYPE 4 /* The type of FileHandler, "r"/"w"/"rw" for reader/writer/both, include "m" for magic, "s" for strong heuristic */
+
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_NAME);
+ const gchar* short_name = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_SHORTNAME);
+ const gchar* desc = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_DESCRIPTION);
+ const gchar* type = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_TYPE);
+ FileHandler fh = (FileHandler) g_malloc0(sizeof(struct _wslua_filehandler));
+
+ fh->is_reader = (strchr(type,'r') != NULL) ? TRUE : FALSE;
+ fh->is_writer = (strchr(type,'w') != NULL) ? TRUE : FALSE;
+
+ if (fh->is_reader && wtap_has_open_info(short_name)) {
+ return luaL_error(L, "FileHandler.new: '%s' short name already exists for a reader!", short_name);
+ }
+
+ if (fh->is_writer && wtap_short_string_to_file_type_subtype(short_name) > -1) {
+ return luaL_error(L, "FileHandler.new: '%s' short name already exists for a writer!", short_name);
+ }
+
+ fh->type = g_strdup(type);
+ fh->finfo.name = g_strdup(name);
+ fh->finfo.short_name = g_strdup(short_name);
+ fh->finfo.default_file_extension = NULL;
+ fh->finfo.additional_file_extensions = NULL;
+ fh->finfo.writing_must_seek = FALSE;
+ fh->finfo.has_name_resolution = FALSE;
+ fh->finfo.can_write_encap = NULL;
+ fh->finfo.dump_open = NULL;
+ /* this will be set to a new file_type when registered */
+ fh->file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
+
+ fh->description = g_strdup(desc);
+ fh->L = L;
+ fh->read_open_ref = LUA_NOREF;
+ fh->read_ref = LUA_NOREF;
+ fh->seek_read_ref = LUA_NOREF;
+ fh->read_close_ref = LUA_NOREF;
+ fh->seq_read_close_ref = LUA_NOREF;
+ fh->write_open_ref = LUA_NOREF;
+ fh->write_ref = LUA_NOREF;
+ fh->write_close_ref = LUA_NOREF;
+ fh->can_write_encap_ref = LUA_NOREF;
+
+ fh->registered = FALSE;
+
+ pushFileHandler(L,fh);
+ WSLUA_RETURN(1); /* The newly created FileHandler object */
+}
+
+WSLUA_METAMETHOD FileHandler__tostring(lua_State* L) {
+ /* Generates a string of debug info for the FileHandler */
+ FileHandler fh = toFileHandler(L,1);
+
+ if (!fh) {
+ lua_pushstring(L,"FileHandler pointer is NULL!");
+ } else {
+ lua_pushfstring(L, "FileHandler(%s): short-name='%s', description='%s', read_open=%d, read=%d, write=%d",
+ fh->finfo.name, fh->finfo.short_name, fh->description, fh->read_open_ref, fh->read_ref, fh->write_ref);
+ }
+
+ WSLUA_RETURN(1); /* String of debug information. */
+}
+
+static int FileHandler__gc(lua_State* L _U_) {
+ /* do NOT free FileHandler, it's never free'd */
+ /* TODO: handle this and other Lua things that should be free'd on exit, in a better way */
+ return 0;
+}
+
+/* A Lua File handler must not be expired, and must be either a reader or writer, and
+ * a *reader* one MUST at least define read_open, read, and seek_read funcs; and
+ * a *writer* one MUST at least define can_write_encap, write_open, and write funcs
+ */
+static gboolean verify_filehandler_complete(FileHandler fh) {
+ return ((fh->is_reader || fh->is_writer) &&
+ (!fh->is_reader ||
+ (fh->is_reader &&
+ fh->read_open_ref != LUA_NOREF &&
+ fh->read_ref != LUA_NOREF &&
+ fh->seek_read_ref != LUA_NOREF)) &&
+ (!fh->is_writer ||
+ (fh->is_writer &&
+ fh->can_write_encap_ref != LUA_NOREF &&
+ fh->write_open_ref != LUA_NOREF &&
+ fh->write_ref != LUA_NOREF)) );
+}
+
+
+WSLUA_FUNCTION wslua_register_filehandler(lua_State* L) {
+ /* Register the FileHandler into Wireshark/tshark, so they can read/write this new format.
+ All functions and settings must be complete before calling this registration function.
+ This function cannot be called inside the reading/writing callback functions. */
+#define WSLUA_ARG_register_filehandler_FILEHANDLER 1 /* the FileHandler object to be registered */
+ FileHandler fh = checkFileHandler(L,WSLUA_ARG_register_filehandler_FILEHANDLER);
+
+ if (in_routine)
+ return luaL_error(L,"a FileHAndler cannot be registered during reading/writing callback functions");
+
+ if (fh->registered)
+ return luaL_error(L,"this FileHandler is already registered");
+
+ if (!verify_filehandler_complete(fh))
+ return luaL_error(L,"this FileHandler is not complete enough to register");
+
+ if (fh->is_writer) {
+ fh->finfo.can_write_encap = wslua_dummy_can_write_encap;
+ fh->finfo.wslua_info = (wtap_wslua_file_info_t*) g_malloc0(sizeof(wtap_wslua_file_info_t));
+ fh->finfo.wslua_info->wslua_can_write_encap = wslua_filehandler_can_write_encap;
+ fh->finfo.wslua_info->wslua_data = (void*)(fh);
+ fh->finfo.dump_open = wslua_filehandler_dump_open;
+ }
+
+ fh->file_type = wtap_register_file_type_subtypes(&(fh->finfo),fh->file_type);
+
+ if (fh->is_reader) {
+ struct open_info oi = { NULL, OPEN_INFO_HEURISTIC, NULL, NULL, NULL, NULL };
+ oi.name = fh->finfo.short_name;
+ oi.open_routine = wslua_filehandler_open;
+ oi.extensions = fh->finfo.additional_file_extensions;
+ oi.wslua_data = (void*)(fh);
+ if (strchr(fh->type,'m') != NULL) {
+ oi.type = OPEN_INFO_MAGIC;
+ } else {
+ oi.type = OPEN_INFO_HEURISTIC;
+ }
+ wtap_register_open_info(&oi, (strchr(fh->type,'s') != NULL));
+ }
+
+ fh->registered = TRUE;
+
+ lua_pushnumber(L, fh->file_type);
+
+ WSLUA_RETURN(1); /* the new type number for this file reader/write */
+}
+
+WSLUA_FUNCTION wslua_deregister_filehandler(lua_State* L) {
+ /* De-register the FileHandler from Wireshark/tshark, so it no longer gets used for reading/writing/display.
+ This function cannot be called inside the reading/writing callback functions. */
+#define WSLUA_ARG_register_filehandler_FILEHANDLER 1 /* the FileHandler object to be de-registered */
+ FileHandler fh = checkFileHandler(L,WSLUA_ARG_register_filehandler_FILEHANDLER);
+
+ if (in_routine)
+ return luaL_error(L,"A FileHAndler cannot be de-registered during reading/writing callback functions");
+
+ if (!fh->registered)
+ return 0;
+
+ /* undo writing stuff, even if it wasn't a writer */
+ fh->finfo.can_write_encap = NULL;
+ if (fh->finfo.wslua_info) {
+ fh->finfo.wslua_info->wslua_can_write_encap = NULL;
+ fh->finfo.wslua_info->wslua_data = NULL;
+ g_free(fh->finfo.wslua_info);
+ fh->finfo.wslua_info = NULL;
+ }
+ fh->finfo.dump_open = NULL;
+
+ if (fh->file_type != WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
+ wtap_deregister_file_type_subtype(fh->file_type);
+
+ if (fh->is_reader && wtap_has_open_info(fh->finfo.short_name)) {
+ wtap_deregister_open_info(fh->finfo.short_name);
+ }
+
+ fh->registered = FALSE;
+
+ return 0;
+}
+
+/* The folllowing macros generate setter functions for Lua, for the following Lua
+ function references in _wslua_filehandler struct:
+ int read_open_ref;
+ int read_ref;
+ int seek_read_ref;
+ int read_close_ref;
+ int seq_read_close_ref;
+ int can_write_encap_ref;
+ int write_open_ref;
+ int write_ref;
+ int write_close_ref;
+*/
+
+/* WSLUA_ATTRIBUTE FileHandler_read_open WO The Lua function to be called when Wireshark opens a file for reading.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfo` object
+
+ The purpose of the Lua function set to this `read_open` field is to check if the file Wireshark is opening is of its type,
+ for example by checking for magic numbers or trying to parse records in the file, etc. The more can be verified
+ the better, because Wireshark tries all file readers until it finds one that accepts the file, so accepting an
+ incorrect file prevents other file readers from reading their files.
+
+ The called Lua function should return true if the file is its type (it accepts it), false if not. The Lua
+ function must also set the File offset position (using `file:seek()`) to where it wants it to be for its first
+ `read()` call.
+ */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read_open);
+
+/* WSLUA_ATTRIBUTE FileHandler_read WO The Lua function to be called when Wireshark wants to read a packet from the file.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfo` object
+ 3. A `FrameInfo` object
+
+ The purpose of the Lua function set to this `read` field is to read the next packet from the file, and setting the parsed/read
+ packet into the frame buffer using `FrameInfo.data = foo` or `FrameInfo:read_data()`.
+
+ The called Lua function should return the file offset/position number where the packet begins, or false if it hit an
+ error. The file offset will be saved by Wireshark and passed into the set `seek_read()` Lua function later. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read);
+
+/* WSLUA_ATTRIBUTE FileHandler_seek_read WO The Lua function to be called when Wireshark wants to read a packet from the file at the given offset.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfo` object
+ 3. A `FrameInfo` object
+ 4. The file offset number previously set by the `read()` function call
+ */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,seek_read);
+
+/* WSLUA_ATTRIBUTE FileHandler_read_close WO The Lua function to be called when Wireshark wants to close the read file completely.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfo` object
+
+ It is not necessary to set this field to a Lua function - FileHandler can be registered without doing so - it
+ is available in case there is memory/state to clear in your script when the file is closed. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,read_close);
+
+/* WSLUA_ATTRIBUTE FileHandler_seq_read_close WO The Lua function to be called when Wireshark wants to close the sequentially-read file.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfo` object
+
+ It is not necessary to set this field to a Lua
+ function - FileHandler can be registered without doing so - it is available in case there is memory/state to clear in your script
+ when the file is closed for the sequential reading portion. After this point, there will be no more calls to `read()`, only `seek_read()`. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,seq_read_close);
+
+
+/* WSLUA_ATTRIBUTE FileHandler_can_write_encap WO The Lua function to be called when Wireshark wants to write a file,
+ by checking if this file writer can handle the wtap packet encapsulation(s).
+
+ When later called by Wireshark, the Lua function will be given a Lua number, which matches one of the encapsulations
+ in the Lua `wtap_encaps` table. This might be the `wtap_encap.PER_PACKET` number, meaning the capture contains multiple
+ encapsulation types, and the file reader should only return true if it can handle multiple encap types in one file. The
+ function will then be called again, once for each encap type in the file, to make sure it can write each one.
+
+ If the Lua file writer can write the given type of encapsulation into a file, then it returns the boolean true, else false. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,can_write_encap);
+
+/* WSLUA_ATTRIBUTE FileHandler_write_open WO The Lua function to be called when Wireshark opens a file for writing.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfoConst` object
+
+ The purpose of the Lua function set to this `write_open` field is similar to the read_open callback function:
+ to initialize things necessary for writing the capture to a file. For example, if the output file format has a
+ file header, then the file header should be written within this write_open function.
+
+ The called Lua function should return true on success, or false if it hit an error.
+
+ Also make sure to set the `FileHandler.write` (and potentially `FileHandler.write_close`) functions before
+ returning true from this function. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write_open);
+
+/* WSLUA_ATTRIBUTE FileHandler_write WO The Lua function to be called when Wireshark wants to write a packet to the file.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfoConst` object
+ 3. A `FrameInfoConst` object of the current frame/packet to be written
+
+ The purpose of the Lua function set to this `write` field is to write the next packet to the file.
+
+ The called Lua function should return true on success, or false if it hit an error. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write);
+
+/* WSLUA_ATTRIBUTE FileHandler_write_close WO The Lua function to be called when Wireshark wants to close the written file.
+
+ When later called by Wireshark, the Lua function will be given:
+ 1. A `File` object
+ 2. A `CaptureInfoConst` object
+
+ It is not necessary to set this field to a Lua function - `FileHandler` can be registered without doing so - it is available
+ in case there is memory/state to clear in your script when the file is closed. */
+WSLUA_ATTRIBUTE_FUNC_SETTER(FileHandler,write_close);
+
+/* generate other member accessors setters/getters */
+
+/* WSLUA_ATTRIBUTE FileHandler_type RO The internal file type. This is automatically set with a new
+ number when the FileHandler is registered. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FileHandler,type,file_type);
+
+/* WSLUA_ATTRIBUTE FileHandler_extensions RW One or more file extensions that this file type usually uses.
+
+ For readers using heuristics to determine file type, Wireshark will try the readers of the file's
+ extension first, before trying other readers. But ultimately Wireshark tries all file readers
+ for any file extension, until it finds one that accepts the file. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FileHandler,extensions,finfo.additional_file_extensions);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(FileHandler,extensions,finfo.additional_file_extensions,TRUE);
+
+/* WSLUA_ATTRIBUTE FileHandler_writing_must_seek RW true if the ability to seek is required when writing
+ this file format, else false.
+
+ This will be checked by Wireshark when writing out to compressed
+ file formats, because seeking is not possible with compressed files. Usually a file writer only
+ needs to be able to seek if it needs to go back in the file to change something, such as a block or
+ file length value earlier in the file. */
+WSLUA_ATTRIBUTE_NAMED_BOOLEAN_GETTER(FileHandler,writing_must_seek,finfo.writing_must_seek);
+WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(FileHandler,writing_must_seek,finfo.writing_must_seek);
+
+/* WSLUA_ATTRIBUTE FileHandler_writes_name_resolution RW true if the file format supports name resolution
+ records, else false. */
+WSLUA_ATTRIBUTE_NAMED_BOOLEAN_GETTER(FileHandler,writes_name_resolution,finfo.has_name_resolution);
+WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(FileHandler,writes_name_resolution,finfo.has_name_resolution);
+
+/* WSLUA_ATTRIBUTE FileHandler_supported_comment_types RW set to the bit-wise OR'ed number representing
+ the type of comments the file writer supports writing, based on the numbers in the `wtap_comments` table. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FileHandler,supported_comment_types,finfo.supported_comment_types);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FileHandler,supported_comment_types,finfo.supported_comment_types,guint32);
+
+/* This table is ultimately registered as a sub-table of the class' metatable,
+ * and if __index/__newindex is invoked then it calls the appropriate function
+ * from this table for getting/setting the members.
+ */
+WSLUA_ATTRIBUTES FileHandler_attributes[] = {
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,read_open),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,read),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,seek_read),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,read_close),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,seq_read_close),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,can_write_encap),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,write_open),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,write),
+ WSLUA_ATTRIBUTE_WOREG(FileHandler,write_close),
+ WSLUA_ATTRIBUTE_ROREG(FileHandler,type),
+ WSLUA_ATTRIBUTE_RWREG(FileHandler,extensions),
+ WSLUA_ATTRIBUTE_RWREG(FileHandler,writing_must_seek),
+ WSLUA_ATTRIBUTE_RWREG(FileHandler,writes_name_resolution),
+ WSLUA_ATTRIBUTE_RWREG(FileHandler,supported_comment_types),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_METHODS FileHandler_methods[] = {
+ WSLUA_CLASS_FNREG(FileHandler,new),
+ { NULL, NULL }
+};
+
+WSLUA_META FileHandler_meta[] = {
+ WSLUA_CLASS_MTREG(FileHandler,tostring),
+ { NULL, NULL }
+};
+
+int FileHandler_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(FileHandler);
+ WSLUA_REGISTER_ATTRIBUTES(FileHandler);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_frame_info.c b/epan/wslua/wslua_frame_info.c
new file mode 100644
index 0000000000..95f77844e5
--- /dev/null
+++ b/epan/wslua/wslua_frame_info.c
@@ -0,0 +1,415 @@
+/*
+ * wslua_frame_info.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ * for frame data and meta-data from a capture file.
+ *
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "wslua_file_common.h"
+
+
+/* WSLUA_CONTINUE_MODULE File */
+
+
+WSLUA_CLASS_DEFINE(FrameInfo,FAIL_ON_NULL_OR_EXPIRED("FrameInfo"),NOP);
+/*
+ A FrameInfo object, passed into Lua as an argument by FileHandler callback
+ functions (e.g., `read`, `seek_read`, etc.).
+
+ This object represents frame data and meta-data (data about the frame/packet)
+ for a given `read`/`seek_read`/`write`'s frame.
+
+ This object's fields are written-to/set when used by read function callbacks, and
+ read-from/get when used by file write function callbacks. In other words, when
+ the Lua plugin's FileHandler `read`/`seek_read`/etc. functions are invoked, a
+ FrameInfo object will be passed in as one of the arguments, and its fields
+ should be written-to/set based on the frame information read from the file;
+ whereas when the Lua plugin's `FileHandler.write()` function is invoked, the
+ `FrameInfo` object passed in should have its fields read-from/get, to write that
+ frame information to the file.
+
+ @since 1.11.3
+ */
+
+FrameInfo* push_FrameInfo(lua_State* L, struct wtap_pkthdr *phdr, Buffer* buf) {
+ FrameInfo f = (FrameInfo) g_malloc0(sizeof(struct _wslua_phdr));
+ f->phdr = phdr;
+ f->buf = buf;
+ f->expired = FALSE;
+ return pushFrameInfo(L,f);
+}
+
+WSLUA_METAMETHOD FrameInfo__tostring(lua_State* L) {
+ /* Generates a string of debug info for the FrameInfo */
+ FrameInfo fi = toFrameInfo(L,1);
+
+ if (!fi) {
+ lua_pushstring(L,"FrameInfo pointer is NULL!");
+ } else {
+ if (fi->phdr)
+ lua_pushfstring(L, "FrameInfo: rec_type=%u, presence_flags=%d, caplen=%d, len=%d, pkt_encap=%d, opt_comment='%s'",
+ fi->phdr->rec_type, fi->phdr->presence_flags, fi->phdr->caplen, fi->phdr->len, fi->phdr->pkt_encap, fi->phdr->opt_comment);
+ else
+ lua_pushstring(L, "FrameInfo phdr pointer is NULL!");
+ }
+
+ WSLUA_RETURN(1); /* String of debug information. */
+}
+
+/* XXX: should this function be a method of File instead? */
+WSLUA_METHOD FrameInfo_read_data(lua_State* L) {
+ /* Tells Wireshark to read directly from given file into frame data buffer, for length bytes. Returns true if succeeded, else false. */
+#define WSLUA_ARG_FrameInfo_read_data_FILE 2 /* The File object userdata, provided by Wireshark previously in a reading-based callback. */
+#define WSLUA_ARG_FrameInfo_read_data_LENGTH 3 /* The number of bytes to read from the file at the current cursor position. */
+ FrameInfo fi = checkFrameInfo(L,1);
+ File fh = checkFile(L,WSLUA_ARG_FrameInfo_read_data_FILE);
+ guint32 len = wslua_checkguint32(L, WSLUA_ARG_FrameInfo_read_data_LENGTH);
+ int err = 0;
+ gchar *err_info = NULL;
+
+ if (!fi->buf || !fh->file) {
+ luaL_error(L, "FrameInfo read_data() got null buffer or file pointer internally");
+ return 0;
+ }
+
+ if (!wtap_read_packet_bytes(fh->file, fi->buf, len, &err, &err_info)) {
+ lua_pushboolean(L, FALSE);
+ if (err_info) {
+ lua_pushstring(L, err_info);
+ g_free(err_info); /* is this right? */
+ }
+ else lua_pushnil(L);
+ lua_pushnumber(L, err);
+ return 3;
+ }
+
+ lua_pushboolean(L, TRUE);
+
+ WSLUA_RETURN(1); /* True if succeeded, else returns false along with the error number and string error description. */
+}
+
+/* free the struct we created, but not the phdr/buf it points to */
+static int FrameInfo__gc(lua_State* L _U_) {
+ FrameInfo fi = toFrameInfo(L,1);
+ if (fi)
+ g_free(fi);
+ return 0;
+}
+
+/* WSLUA_ATTRIBUTE FrameInfo_time RW The packet timestamp as an NSTime object.
+
+ Note: Set the `FileHandler.time_precision` to the appropriate `wtap_file_tsprec` value as well.
+ */
+static int FrameInfo_set_time (lua_State* L) {
+ FrameInfo fi = checkFrameInfo(L,1);
+ NSTime nstime = checkNSTime(L,2);
+
+ if (!fi->phdr) return 0;
+
+ fi->phdr->ts.secs = nstime->secs;
+ fi->phdr->ts.nsecs = nstime->nsecs;
+
+ return 0;
+}
+
+static int FrameInfo_get_time (lua_State* L) {
+ FrameInfo fi = checkFrameInfo(L,1);
+ NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
+
+ if (!nstime) return 0;
+
+ nstime->secs = fi->phdr->ts.secs;
+ nstime->nsecs = fi->phdr->ts.nsecs;
+
+ pushNSTime(L,nstime);
+
+ return 1; /* An NSTime object of the frame's timestamp. */
+}
+
+/* WSLUA_ATTRIBUTE FrameInfo_data RW The data buffer containing the packet.
+
+ @note This cannot be cleared once set.
+ */
+static int FrameInfo_set_data (lua_State* L) {
+ FrameInfo fi = checkFrameInfo(L,1);
+
+ if (!fi->phdr) {
+ g_warning("Error in FrameInfo set data: NULL pointer");
+ return 0;
+ }
+
+ if (!fi->buf) {
+ g_warning("Error in FrameInfo set data: NULL frame_buffer pointer");
+ return 0;
+ }
+
+ if (lua_isstring(L,2)) {
+ size_t len = 0;
+ const gchar* s = luaL_checklstring(L,2,&len);
+
+ /* Make sure we have enough room for the packet */
+ ws_buffer_assure_space(fi->buf, len);
+ memcpy(ws_buffer_start_ptr(fi->buf), s, len);
+ fi->phdr->caplen = (guint32) len;
+ fi->phdr->len = (guint32) len;
+ }
+ else
+ luaL_error(L, "FrameInfo's attribute 'data' must be a Lua string");
+
+ return 0;
+}
+
+static int FrameInfo_get_data (lua_State* L) {
+ FrameInfo fi = checkFrameInfo(L,1);
+
+ if (!fi->buf) return 0;
+
+ lua_pushlstring(L, ws_buffer_start_ptr(fi->buf), ws_buffer_length(fi->buf));
+
+ WSLUA_RETURN(1); /* A Lua string of the frame buffer's data. */
+}
+
+/* WSLUA_ATTRIBUTE FrameInfo_rec_type RW The record type of the packet frame
+
+ See `wtap_rec_types` in `init.lua` for values. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,rec_type,phdr->rec_type);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,rec_type,phdr->rec_type,guint);
+
+/* WSLUA_ATTRIBUTE FrameInfo_flags RW The presence flags of the packet frame.
+
+ See `wtap_presence_flags` in `init.lua` for bit values. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,flags,phdr->presence_flags);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,flags,phdr->presence_flags,guint32);
+
+/* WSLUA_ATTRIBUTE FrameInfo_captured_length RW The captured packet length,
+ and thus the length of the buffer passed to the `FrameInfo.data` field. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,captured_length,phdr->caplen);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,captured_length,phdr->caplen,guint32);
+
+/* WSLUA_ATTRIBUTE FrameInfo_original_length RW The on-the-wire packet length,
+ which may be longer than the `captured_length`. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,original_length,phdr->len);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,original_length,phdr->len,guint32);
+
+/* WSLUA_ATTRIBUTE FrameInfo_encap RW The packet encapsulation type for the frame/packet,
+ if the file supports per-packet types. See `wtap_encaps` in `init.lua` for possible
+ packet encapsulation types to use as the value for this field. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfo,encap,phdr->pkt_encap);
+WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(FrameInfo,encap,phdr->pkt_encap,int);
+
+/* WSLUA_ATTRIBUTE FrameInfo_comment RW A string comment for the packet, if the
+ `wtap_presence_flags.COMMENTS` was set in the presence flags; nil if there is no comment. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FrameInfo,comment,phdr->opt_comment);
+WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(FrameInfo,comment,phdr->opt_comment,TRUE);
+
+/* This table is ultimately registered as a sub-table of the class' metatable,
+ * and if __index/__newindex is invoked then it calls the appropriate function
+ * from this table for getting/setting the members.
+ */
+WSLUA_ATTRIBUTES FrameInfo_attributes[] = {
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,rec_type),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,flags),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,captured_length),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,original_length),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,comment),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,encap),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,time),
+ WSLUA_ATTRIBUTE_RWREG(FrameInfo,data),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_METHODS FrameInfo_methods[] = {
+ WSLUA_CLASS_FNREG(FrameInfo,read_data),
+ { NULL, NULL }
+};
+
+WSLUA_META FrameInfo_meta[] = {
+ WSLUA_CLASS_MTREG(FrameInfo,tostring),
+ { NULL, NULL }
+};
+
+int FrameInfo_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(FrameInfo);
+ WSLUA_REGISTER_ATTRIBUTES(FrameInfo);
+ return 0;
+}
+
+WSLUA_CLASS_DEFINE(FrameInfoConst,FAIL_ON_NULL_OR_EXPIRED("FrameInfo"),NOP);
+/*
+ A constant FrameInfo object, passed into Lua as an argument by the FileHandler write
+ callback function. This has similar attributes/properties as FrameInfo, but the fields can
+ only be read from, not written to.
+
+ @since 1.11.3
+ */
+
+FrameInfoConst* push_FrameInfoConst(lua_State* L, const struct wtap_pkthdr *phdr, const guint8 *pd) {
+ FrameInfoConst f = (FrameInfoConst) g_malloc(sizeof(struct _wslua_const_phdr));
+ f->phdr = phdr;
+ f->pd = pd;
+ f->expired = FALSE;
+ return pushFrameInfoConst(L,f);
+}
+
+WSLUA_METAMETHOD FrameInfoConst__tostring(lua_State* L) {
+ /* Generates a string of debug info for the FrameInfo */
+ FrameInfoConst fi = toFrameInfoConst(L,1);
+
+ if (!fi) {
+ lua_pushstring(L,"FrameInfo pointer is NULL!");
+ } else {
+ if (fi->phdr && !fi->expired)
+ lua_pushfstring(L, "FrameInfo: rec_type=%u, presence_flags=%d, caplen=%d, len=%d, pkt_encap=%d, opt_comment='%s'",
+ fi->phdr->rec_type, fi->phdr->presence_flags, fi->phdr->caplen, fi->phdr->len, fi->phdr->pkt_encap, fi->phdr->opt_comment);
+ else
+ lua_pushfstring(L, "FrameInfo has %s", fi->phdr?"expired":"null phdr pointer");
+ }
+
+ WSLUA_RETURN(1); /* String of debug information. */
+}
+
+/* XXX: should this function be a method of File instead? */
+WSLUA_METHOD FrameInfoConst_write_data(lua_State* L) {
+ /* Tells Wireshark to write directly to given file from the frame data buffer, for length bytes. Returns true if succeeded, else false. */
+#define WSLUA_ARG_FrameInfoConst_write_data_FILE 2 /* The File object userdata, provided by Wireshark previously in a writing-based callback. */
+#define WSLUA_OPTARG_FrameInfoConst_write_data_LENGTH 3 /* The number of bytes to write to the file at the current cursor position, or all if not supplied. */
+ FrameInfoConst fi = checkFrameInfoConst(L,1);
+ File fh = checkFile(L,WSLUA_ARG_FrameInfoConst_write_data_FILE);
+ guint32 len = wslua_optguint32(L, WSLUA_OPTARG_FrameInfoConst_write_data_LENGTH, fi->phdr ? fi->phdr->caplen:0);
+ int err = 0;
+
+ if (!fi->pd || !fi->phdr || !fh->wdh) {
+ luaL_error(L, "FrameInfoConst write_data() got null buffer or file pointer internally");
+ return 0;
+ }
+
+ if (len > fi->phdr->caplen)
+ len = fi->phdr->caplen;
+
+ if (!wtap_dump_file_write(fh->wdh, fi->pd, (size_t)(len), &err)) {
+ lua_pushboolean(L, FALSE);
+ lua_pushfstring(L, "FrameInfoConst write_data() error: %s", g_strerror(err));
+ lua_pushnumber(L, err);
+ return 3;
+ }
+
+ lua_pushboolean(L, TRUE);
+
+ WSLUA_RETURN(1); /* True if succeeded, else returns false along with the error number and string error description. */
+}
+
+/* free the struct we created, but not the wtap_pkthdr it points to */
+static int FrameInfoConst__gc(lua_State* L _U_) {
+ FrameInfoConst fi = toFrameInfoConst(L,1);
+ if (fi)
+ g_free(fi);
+ return 0;
+}
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_time RO The packet timestamp as an NSTime object. */
+static int FrameInfoConst_get_time (lua_State* L) {
+ FrameInfoConst fi = checkFrameInfoConst(L,1);
+ NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
+
+ if (!nstime) return 0;
+
+ nstime->secs = fi->phdr->ts.secs;
+ nstime->nsecs = fi->phdr->ts.nsecs;
+
+ pushNSTime(L,nstime);
+
+ return 1; /* An NSTime object of the frame's timestamp. */
+}
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_data RO The data buffer containing the packet. */
+static int FrameInfoConst_get_data (lua_State* L) {
+ FrameInfoConst fi = checkFrameInfoConst(L,1);
+
+ if (!fi->pd || !fi->phdr) return 0;
+
+ lua_pushlstring(L, fi->pd, fi->phdr->caplen);
+
+ return 1;
+}
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_rec_type RO The record type of the packet frame - see `wtap_presence_flags` in `init.lua` for values. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,rec_type,phdr->rec_type);
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_flags RO The presence flags of the packet frame - see `wtap_presence_flags` in `init.lua` for bits. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,flags,phdr->presence_flags);
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_captured_length RO The captured packet length, and thus the length of the buffer in the FrameInfoConst.data field. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,captured_length,phdr->caplen);
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_original_length RO The on-the-wire packet length, which may be longer than the `captured_length`. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,original_length,phdr->len);
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_encap RO The packet encapsulation type, if the file supports per-packet types.
+
+ See `wtap_encaps` in `init.lua` for possible packet encapsulation types to use as the value for this field. */
+WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(FrameInfoConst,encap,phdr->pkt_encap);
+
+/* WSLUA_ATTRIBUTE FrameInfoConst_comment RO A comment for the packet; nil if there is none. */
+WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(FrameInfoConst,comment,phdr->opt_comment);
+
+WSLUA_ATTRIBUTES FrameInfoConst_attributes[] = {
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,rec_type),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,flags),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,captured_length),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,original_length),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,encap),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,comment),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,time),
+ WSLUA_ATTRIBUTE_ROREG(FrameInfoConst,data),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_METHODS FrameInfoConst_methods[] = {
+ WSLUA_CLASS_FNREG(FrameInfoConst,write_data),
+ { NULL, NULL }
+};
+
+WSLUA_META FrameInfoConst_meta[] = {
+ WSLUA_CLASS_MTREG(FrameInfoConst,tostring),
+ { NULL, NULL }
+};
+
+int FrameInfoConst_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(FrameInfoConst);
+ WSLUA_REGISTER_ATTRIBUTES(FrameInfoConst);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_nstime.c b/epan/wslua/wslua_nstime.c
new file mode 100644
index 0000000000..0c9abdb677
--- /dev/null
+++ b/epan/wslua/wslua_nstime.c
@@ -0,0 +1,210 @@
+/*
+ * wslua_nstime.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+
+/* WSLUA_CONTINUE_MODULE Pinfo */
+
+
+WSLUA_CLASS_DEFINE(NSTime,FAIL_ON_NULL("NSTime"),NOP);
+/* NSTime represents a nstime_t. This is an object with seconds and nanoseconds. */
+
+WSLUA_CONSTRUCTOR NSTime_new(lua_State *L) {
+ /* Creates a new NSTime object. */
+#define WSLUA_OPTARG_NSTime_new_SECONDS 1 /* Seconds. */
+#define WSLUA_OPTARG_NSTime_new_NSECONDS 2 /* Nano seconds. */
+ NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
+
+ if (!nstime) return 0;
+
+ nstime->secs = (time_t) luaL_optinteger(L,WSLUA_OPTARG_NSTime_new_SECONDS,0);
+ nstime->nsecs = (int) luaL_optinteger(L,WSLUA_OPTARG_NSTime_new_NSECONDS,0);
+
+ pushNSTime(L,nstime);
+
+ WSLUA_RETURN(1); /* The new NSTime object. */
+}
+
+WSLUA_METAMETHOD NSTime__call(lua_State* L) { /* Creates a NSTime object. */
+#define WSLUA_OPTARG_NSTime__call_SECONDS 1 /* Seconds. */
+#define WSLUA_OPTARG_NSTime__call_NSECONDS 2 /* Nanoseconds. */
+ lua_remove(L,1); /* remove the table */
+ WSLUA_RETURN(NSTime_new(L)); /* The new NSTime object. */
+}
+
+WSLUA_METAMETHOD NSTime__tostring(lua_State* L) {
+ NSTime nstime = checkNSTime(L,1);
+ gchar *str;
+
+ str = wmem_strdup_printf(NULL, "%ld.%09d", (long)nstime->secs, nstime->nsecs);
+ lua_pushstring(L, str);
+ wmem_free(NULL, str);
+
+ WSLUA_RETURN(1); /* The string representing the nstime. */
+}
+WSLUA_METAMETHOD NSTime__add(lua_State* L) { /* Calculates the sum of two NSTimes. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = checkNSTime(L,2);
+ NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
+
+ nstime_sum (time3, time1, time2);
+ pushNSTime (L, time3);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD NSTime__sub(lua_State* L) { /* Calculates the diff of two NSTimes. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = checkNSTime(L,2);
+ NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
+
+ nstime_delta (time3, time1, time2);
+ pushNSTime (L, time3);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD NSTime__unm(lua_State* L) { /* Calculates the negative NSTime. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = (NSTime)g_malloc (sizeof (nstime_t));
+
+ nstime_set_zero (time2);
+ nstime_subtract (time2, time1);
+ pushNSTime (L, time2);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD NSTime__eq(lua_State* L) { /* Compares two NSTimes. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = checkNSTime(L,2);
+ gboolean result = FALSE;
+
+ if (nstime_cmp(time1, time2) == 0)
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD NSTime__le(lua_State* L) { /* Compares two NSTimes. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = checkNSTime(L,2);
+ gboolean result = FALSE;
+
+ if (nstime_cmp(time1, time2) <= 0)
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes. */
+ NSTime time1 = checkNSTime(L,1);
+ NSTime time2 = checkNSTime(L,2);
+ gboolean result = FALSE;
+
+ if (nstime_cmp(time1, time2) < 0)
+ result = TRUE;
+
+ lua_pushboolean(L,result);
+
+ return 1;
+}
+
+
+/* WSLUA_ATTRIBUTE NSTime_secs RW The NSTime seconds. */
+WSLUA_ATTRIBUTE_NUMBER_GETTER(NSTime,secs);
+WSLUA_ATTRIBUTE_NUMBER_SETTER(NSTime,secs,time_t);
+
+/* WSLUA_ATTRIBUTE NSTime_nsecs RW The NSTime nano seconds. */
+WSLUA_ATTRIBUTE_NUMBER_GETTER(NSTime,nsecs);
+WSLUA_ATTRIBUTE_NUMBER_SETTER(NSTime,nsecs,int);
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int NSTime__gc(lua_State* L) {
+ NSTime nstime = toNSTime(L,1);
+
+ if (!nstime) return 0;
+
+ g_free (nstime);
+ return 0;
+}
+
+/* This table is ultimately registered as a sub-table of the class' metatable,
+ * and if __index/__newindex is invoked then it calls the appropriate function
+ * from this table for getting/setting the members.
+ */
+WSLUA_ATTRIBUTES NSTime_attributes[] = {
+ WSLUA_ATTRIBUTE_RWREG(NSTime,secs),
+ WSLUA_ATTRIBUTE_RWREG(NSTime,nsecs),
+ { NULL, NULL, NULL }
+};
+
+WSLUA_METHODS NSTime_methods[] = {
+ WSLUA_CLASS_FNREG(NSTime,new),
+ { NULL, NULL }
+};
+
+WSLUA_META NSTime_meta[] = {
+ WSLUA_CLASS_MTREG(NSTime,tostring),
+ WSLUA_CLASS_MTREG(NSTime,add),
+ WSLUA_CLASS_MTREG(NSTime,sub),
+ WSLUA_CLASS_MTREG(NSTime,unm),
+ WSLUA_CLASS_MTREG(NSTime,eq),
+ WSLUA_CLASS_MTREG(NSTime,le),
+ WSLUA_CLASS_MTREG(NSTime,lt),
+ WSLUA_CLASS_MTREG(NSTime,call),
+ { NULL, NULL }
+};
+
+int NSTime_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(NSTime);
+ WSLUA_REGISTER_ATTRIBUTES(NSTime);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_pinfo.c b/epan/wslua/wslua_pinfo.c
index ae58c358ae..cf8d5b3922 100644
--- a/epan/wslua/wslua_pinfo.c
+++ b/epan/wslua/wslua_pinfo.c
@@ -26,33 +26,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
+#include "wslua_pinfo_common.h"
#include <epan/wmem/wmem.h>
-
-/* WSLUA_MODULE Pinfo Obtaining packet information */
-
-
-#include "wslua.h"
-
-#include <epan/addr_resolv.h>
#include <epan/conversation.h>
#include <string.h>
+/* WSLUA_MODULE Pinfo Obtaining packet information */
+
+
/*
* Track pointers to wireshark's structures.
* see comment on wslua_tvb.c
*/
static GPtrArray* outstanding_Pinfo = NULL;
-static GPtrArray* outstanding_Column = NULL;
-static GPtrArray* outstanding_Columns = NULL;
static GPtrArray* outstanding_PrivateTable = NULL;
CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
-CLEAR_OUTSTANDING(Column,expired, TRUE)
-CLEAR_OUTSTANDING(Columns,expired, TRUE)
CLEAR_OUTSTANDING(PrivateTable,expired, TRUE)
Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
@@ -66,714 +58,8 @@ Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
return pushPinfo(L,pinfo);
}
-#define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
-#define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
#define PUSH_PRIVATE_TABLE(L,c) {g_ptr_array_add(outstanding_PrivateTable,c);pushPrivateTable(L,c);}
-WSLUA_CLASS_DEFINE(NSTime,FAIL_ON_NULL("NSTime"),NOP);
-/* NSTime represents a nstime_t. This is an object with seconds and nanoseconds. */
-
-WSLUA_CONSTRUCTOR NSTime_new(lua_State *L) {
- /* Creates a new NSTime object. */
-#define WSLUA_OPTARG_NSTime_new_SECONDS 1 /* Seconds. */
-#define WSLUA_OPTARG_NSTime_new_NSECONDS 2 /* Nano seconds. */
- NSTime nstime = (NSTime)g_malloc(sizeof(nstime_t));
-
- if (!nstime) return 0;
-
- nstime->secs = (time_t) luaL_optinteger(L,WSLUA_OPTARG_NSTime_new_SECONDS,0);
- nstime->nsecs = (int) luaL_optinteger(L,WSLUA_OPTARG_NSTime_new_NSECONDS,0);
-
- pushNSTime(L,nstime);
-
- WSLUA_RETURN(1); /* The new NSTime object. */
-}
-
-WSLUA_METAMETHOD NSTime__call(lua_State* L) { /* Creates a NSTime object. */
-#define WSLUA_OPTARG_NSTime__call_SECONDS 1 /* Seconds. */
-#define WSLUA_OPTARG_NSTime__call_NSECONDS 2 /* Nanoseconds. */
- lua_remove(L,1); /* remove the table */
- WSLUA_RETURN(NSTime_new(L)); /* The new NSTime object. */
-}
-
-WSLUA_METAMETHOD NSTime__tostring(lua_State* L) {
- NSTime nstime = checkNSTime(L,1);
- gchar *str;
-
- str = wmem_strdup_printf(NULL, "%ld.%09d", (long)nstime->secs, nstime->nsecs);
- lua_pushstring(L, str);
- wmem_free(NULL, str);
-
- WSLUA_RETURN(1); /* The string representing the nstime. */
-}
-WSLUA_METAMETHOD NSTime__add(lua_State* L) { /* Calculates the sum of two NSTimes. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = checkNSTime(L,2);
- NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
-
- nstime_sum (time3, time1, time2);
- pushNSTime (L, time3);
-
- return 1;
-}
-
-WSLUA_METAMETHOD NSTime__sub(lua_State* L) { /* Calculates the diff of two NSTimes. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = checkNSTime(L,2);
- NSTime time3 = (NSTime)g_malloc (sizeof (nstime_t));
-
- nstime_delta (time3, time1, time2);
- pushNSTime (L, time3);
-
- return 1;
-}
-
-WSLUA_METAMETHOD NSTime__unm(lua_State* L) { /* Calculates the negative NSTime. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = (NSTime)g_malloc (sizeof (nstime_t));
-
- nstime_set_zero (time2);
- nstime_subtract (time2, time1);
- pushNSTime (L, time2);
-
- return 1;
-}
-
-WSLUA_METAMETHOD NSTime__eq(lua_State* L) { /* Compares two NSTimes. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = checkNSTime(L,2);
- gboolean result = FALSE;
-
- if (nstime_cmp(time1, time2) == 0)
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_METAMETHOD NSTime__le(lua_State* L) { /* Compares two NSTimes. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = checkNSTime(L,2);
- gboolean result = FALSE;
-
- if (nstime_cmp(time1, time2) <= 0)
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_METAMETHOD NSTime__lt(lua_State* L) { /* Compares two NSTimes. */
- NSTime time1 = checkNSTime(L,1);
- NSTime time2 = checkNSTime(L,2);
- gboolean result = FALSE;
-
- if (nstime_cmp(time1, time2) < 0)
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-
-/* WSLUA_ATTRIBUTE NSTime_secs RW The NSTime seconds. */
-WSLUA_ATTRIBUTE_NUMBER_GETTER(NSTime,secs);
-WSLUA_ATTRIBUTE_NUMBER_SETTER(NSTime,secs,time_t);
-
-/* WSLUA_ATTRIBUTE NSTime_nsecs RW The NSTime nano seconds. */
-WSLUA_ATTRIBUTE_NUMBER_GETTER(NSTime,nsecs);
-WSLUA_ATTRIBUTE_NUMBER_SETTER(NSTime,nsecs,int);
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int NSTime__gc(lua_State* L) {
- NSTime nstime = toNSTime(L,1);
-
- if (!nstime) return 0;
-
- g_free (nstime);
- return 0;
-}
-
-/* This table is ultimately registered as a sub-table of the class' metatable,
- * and if __index/__newindex is invoked then it calls the appropriate function
- * from this table for getting/setting the members.
- */
-WSLUA_ATTRIBUTES NSTime_attributes[] = {
- WSLUA_ATTRIBUTE_RWREG(NSTime,secs),
- WSLUA_ATTRIBUTE_RWREG(NSTime,nsecs),
- { NULL, NULL, NULL }
-};
-
-WSLUA_METHODS NSTime_methods[] = {
- WSLUA_CLASS_FNREG(NSTime,new),
- { NULL, NULL }
-};
-
-WSLUA_META NSTime_meta[] = {
- WSLUA_CLASS_MTREG(NSTime,tostring),
- WSLUA_CLASS_MTREG(NSTime,add),
- WSLUA_CLASS_MTREG(NSTime,sub),
- WSLUA_CLASS_MTREG(NSTime,unm),
- WSLUA_CLASS_MTREG(NSTime,eq),
- WSLUA_CLASS_MTREG(NSTime,le),
- WSLUA_CLASS_MTREG(NSTime,lt),
- WSLUA_CLASS_MTREG(NSTime,call),
- { NULL, NULL }
-};
-
-int NSTime_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(NSTime);
- WSLUA_REGISTER_ATTRIBUTES(NSTime);
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(Address,FAIL_ON_NULL("Address"),NOP); /* Represents an address. */
-
-WSLUA_CONSTRUCTOR Address_ip(lua_State* L) {
- /* Creates an Address Object representing an IP address. */
-
-#define WSLUA_ARG_Address_ip_HOSTNAME 1 /* The address or name of the IP host. */
- Address addr = (Address)g_malloc(sizeof(address));
- guint32* ip_addr = (guint32 *)g_malloc(sizeof(guint32));
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_Address_ip_HOSTNAME);
-
- if (! get_host_ipaddr(name, (guint32*)ip_addr)) {
- *ip_addr = 0;
- }
-
- SET_ADDRESS(addr, AT_IPv4, 4, ip_addr);
- pushAddress(L,addr);
- WSLUA_RETURN(1); /* The Address object. */
-}
-
-#if 0
-/* TODO */
-static int Address_ipv6(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_ss7(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_eth(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_sna(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_atalk(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_vines(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_osi(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_arcnet(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_fc(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_string(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_eui64(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_uri(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-static int Address_tipc(lua_State* L) {
- Address addr = g_malloc(sizeof(address));
-
- SET_ADDRESS(addr, AT_NONE, 4, g_malloc(4));
-
- pushAddress(L,addr);
- return 1;
-}
-#endif
-
-WSLUA_METHODS Address_methods[] = {
- WSLUA_CLASS_FNREG(Address,ip),
- WSLUA_CLASS_FNREG_ALIAS(Address,ipv4,ip),
-#if 0
- WSLUA_CLASS_FNREG(Address,ipv6),
- WSLUA_CLASS_FNREG_ALIAS(Address,ss7pc,ss7),
- WSLUA_CLASS_FNREG(Address,eth),
- WSLUA_CLASS_FNREG(Address,sna},
- WSLUA_CLASS_FNREG(Address,atalk),
- WSLUA_CLASS_FNREG(Address,vines),
- WSLUA_CLASS_FNREG(Address,osi),
- WSLUA_CLASS_FNREG(Address,arcnet),
- WSLUA_CLASS_FNREG(Address,fc),
- WSLUA_CLASS_FNREG(Address,string),
- WSLUA_CLASS_FNREG(Address,eui64),
- WSLUA_CLASS_FNREG(Address,uri),
- WSLUA_CLASS_FNREG(Address,tipc),
-#endif
- { NULL, NULL }
-};
-
-WSLUA_METAMETHOD Address__tostring(lua_State* L) {
- Address addr = checkAddress(L,1);
- const gchar *str = address_to_display(NULL, addr);
-
- lua_pushstring(L, str);
-
- wmem_free(NULL, (void*) str);
-
- WSLUA_RETURN(1); /* The string representing the address. */
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int Address__gc(lua_State* L) {
- Address addr = toAddress(L,1);
-
- if (addr) {
- g_free((void*)(addr->data));
- g_free((void*)(addr));
- }
-
- return 0;
-}
-
-WSLUA_METAMETHOD Address__eq(lua_State* L) { /* Compares two Addresses. */
- Address addr1 = checkAddress(L,1);
- Address addr2 = checkAddress(L,2);
- gboolean result = FALSE;
-
- if (ADDRESSES_EQUAL(addr1, addr2))
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_METAMETHOD Address__le(lua_State* L) { /* Compares two Addresses. */
- Address addr1 = checkAddress(L,1);
- Address addr2 = checkAddress(L,2);
- gboolean result = FALSE;
-
- if (CMP_ADDRESS(addr1, addr2) <= 0)
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_METAMETHOD Address__lt(lua_State* L) { /* Compares two Addresses. */
- Address addr1 = checkAddress(L,1);
- Address addr2 = checkAddress(L,2);
- gboolean result = FALSE;
-
- if (CMP_ADDRESS(addr1, addr2) < 0)
- result = TRUE;
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_META Address_meta[] = {
- WSLUA_CLASS_MTREG(Address,tostring),
- WSLUA_CLASS_MTREG(Address,eq),
- WSLUA_CLASS_MTREG(Address,le),
- WSLUA_CLASS_MTREG(Address,lt),
- { NULL, NULL }
-};
-
-
-int Address_register(lua_State *L) {
- WSLUA_REGISTER_CLASS(Address);
- return 0;
-}
-
-
-WSLUA_CLASS_DEFINE(Column,FAIL_ON_NULL("Column"),NOP); /* A Column in the packet list. */
-
-struct col_names_t {
- const gchar* name;
- int id;
-};
-
-static const struct col_names_t colnames[] = {
- {"number",COL_NUMBER},
- {"abs_time",COL_ABS_TIME},
- {"utc_time",COL_UTC_TIME},
- {"cls_time",COL_CLS_TIME},
- {"rel_time",COL_REL_TIME},
- {"date",COL_ABS_YMD_TIME},
- {"date_doy",COL_ABS_YDOY_TIME},
- {"utc_date",COL_UTC_YMD_TIME},
- {"utc_date_doy",COL_UTC_YDOY_TIME},
- {"delta_time",COL_DELTA_TIME},
- {"delta_time_displayed",COL_DELTA_TIME_DIS},
- {"src",COL_DEF_SRC},
- {"src_res",COL_RES_SRC},
- {"src_unres",COL_UNRES_SRC},
- {"dl_src",COL_DEF_DL_SRC},
- {"dl_src_res",COL_RES_DL_SRC},
- {"dl_src_unres",COL_UNRES_DL_SRC},
- {"net_src",COL_DEF_NET_SRC},
- {"net_src_res",COL_RES_NET_SRC},
- {"net_src_unres",COL_UNRES_NET_SRC},
- {"dst",COL_DEF_DST},
- {"dst_res",COL_RES_DST},
- {"dst_unres",COL_UNRES_DST},
- {"dl_dst",COL_DEF_DL_DST},
- {"dl_dst_res",COL_RES_DL_DST},
- {"dl_dst_unres",COL_UNRES_DL_DST},
- {"net_dst",COL_DEF_NET_DST},
- {"net_dst_res",COL_RES_NET_DST},
- {"net_dst_unres",COL_UNRES_NET_DST},
- {"src_port",COL_DEF_SRC_PORT},
- {"src_port_res",COL_RES_SRC_PORT},
- {"src_port_unres",COL_UNRES_SRC_PORT},
- {"dst_port",COL_DEF_DST_PORT},
- {"dst_port_res",COL_RES_DST_PORT},
- {"dst_port_unres",COL_UNRES_DST_PORT},
- {"protocol",COL_PROTOCOL},
- {"info",COL_INFO},
- {"packet_len",COL_PACKET_LENGTH},
- {"cumulative_bytes",COL_CUMULATIVE_BYTES},
- {"direction",COL_IF_DIR},
- {"vsan",COL_VSAN},
- {"tx_rate",COL_TX_RATE},
- {"rssi",COL_RSSI},
- {"dce_call",COL_DCE_CALL},
- {NULL,0}
-};
-
-static gint col_name_to_id(const gchar* name) {
- const struct col_names_t* cn;
- for(cn = colnames; cn->name; cn++) {
- if (g_str_equal(cn->name,name)) {
- return cn->id;
- }
- }
-
- return 0;
-}
-
-static const gchar* col_id_to_name(gint id) {
- const struct col_names_t* cn;
- for(cn = colnames; cn->name; cn++) {
- if ( cn->id == id ) {
- return cn->name;
- }
- }
- return NULL;
-}
-
-
-WSLUA_METAMETHOD Column__tostring(lua_State *L) {
- Column c = checkColumn(L,1);
- const gchar* text;
-
- if (!c->cinfo) {
- text = col_id_to_name(c->col);
- lua_pushfstring(L, "(%s)", text ? text : "unknown");
- }
- else {
- text = col_get_text(c->cinfo, c->col);
- lua_pushstring(L, text ? text : "(nil)");
- }
-
- WSLUA_RETURN(1); /* The column's string text (in parenthesis if not available). */
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS */
-static int Column__gc(lua_State* L) {
- Column col = toColumn(L,1);
-
- if (!col) return 0;
-
- if (!col->expired)
- col->expired = TRUE;
- else
- g_free(col);
-
- return 0;
-
-}
-
-WSLUA_METHOD Column_clear(lua_State *L) {
- /* Clears a Column. */
- Column c = checkColumn(L,1);
-
- if (!(c->cinfo)) return 0;
-
- col_clear(c->cinfo, c->col);
-
- return 0;
-}
-
-WSLUA_METHOD Column_set(lua_State *L) {
- /* Sets the text of a Column. */
-#define WSLUA_ARG_Column_set_TEXT 2 /* The text to which to set the Column. */
- Column c = checkColumn(L,1);
- const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_set_TEXT);
-
- if (!(c->cinfo))
- return 0;
-
- col_add_str(c->cinfo, c->col, s);
-
- return 0;
-}
-
-WSLUA_METHOD Column_append(lua_State *L) {
- /* Appends text to a Column. */
-#define WSLUA_ARG_Column_append_TEXT 2 /* The text to append to the Column. */
- Column c = checkColumn(L,1);
- const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_append_TEXT);
-
- if (!(c->cinfo))
- return 0;
-
- col_append_str(c->cinfo, c->col, s);
-
- return 0;
-}
-
-WSLUA_METHOD Column_prepend(lua_State *L) {
- /* Prepends text to a Column. */
-#define WSLUA_ARG_Column_prepend_TEXT 2 /* The text to prepend to the Column. */
- Column c = checkColumn(L,1);
- const gchar* s = luaL_checkstring(L,WSLUA_ARG_Column_prepend_TEXT);
-
- if (!(c->cinfo))
- return 0;
-
- col_prepend_fstr(c->cinfo, c->col, "%s",s);
-
- return 0;
-}
-
-WSLUA_METHOD Column_fence(lua_State *L) {
- /* Sets Column text fence, to prevent overwriting.
-
- @since 1.10.6
- */
- Column c = checkColumn(L,1);
-
- if (c->cinfo)
- col_set_fence(c->cinfo, c->col);
-
- return 0;
-}
-
-WSLUA_METHOD Column_clear_fence(lua_State *L) {
- /* Clear Column text fence.
-
- @since 1.11.3
- */
- Column c = checkColumn(L,1);
-
- if (c->cinfo)
- col_clear_fence(c->cinfo, c->col);
-
- return 0;
-}
-
-
-WSLUA_METHODS Column_methods[] = {
- WSLUA_CLASS_FNREG(Column,clear),
- WSLUA_CLASS_FNREG(Column,set),
- WSLUA_CLASS_FNREG(Column,append),
- WSLUA_CLASS_FNREG(Column,prepend),
- WSLUA_CLASS_FNREG_ALIAS(Column,preppend,prepend),
- WSLUA_CLASS_FNREG(Column,fence),
- WSLUA_CLASS_FNREG(Column,clear_fence),
- { NULL, NULL }
-};
-
-
-WSLUA_META Column_meta[] = {
- WSLUA_CLASS_MTREG(Column,tostring),
- { NULL, NULL }
-};
-
-
-int Column_register(lua_State *L) {
- WSLUA_REGISTER_CLASS(Column);
- return 0;
-}
-
-
-WSLUA_CLASS_DEFINE(Columns,NOP,NOP);
-/* The Columns of the packet list. */
-
-WSLUA_METAMETHOD Columns__tostring(lua_State *L) {
- lua_pushstring(L,"Columns");
- WSLUA_RETURN(1);
- /* The string "Columns", no real use, just for debugging purposes. */
-}
-
-/*
- * To document this is very odd - it won't make sense to a person reading the
- * API docs to see this metamethod as a method, but oh well.
- */
-WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
- /* Sets the text of a specific column. */
-#define WSLUA_ARG_Columns__newindex_COLUMN 2 /* The name of the column to set. */
-#define WSLUA_ARG_Columns__newindex_TEXT 3 /* The text for the column. */
- Columns cols = checkColumns(L,1);
- const struct col_names_t* cn;
- const char* colname;
- const char* text;
-
- if (!cols) return 0;
- if (cols->expired) {
- luaL_error(L,"expired column");
- return 0;
- }
-
- colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
- text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
-
- for(cn = colnames; cn->name; cn++) {
- if( g_str_equal(cn->name,colname) ) {
- col_add_str(cols->cinfo, cn->id, text);
- return 0;
- }
- }
-
- WSLUA_ARG_ERROR(Columns__newindex,COLUMN,"the column name must be a valid column");
- return 0;
-}
-
-WSLUA_METAMETHOD Columns__index(lua_State *L) {
- /* Gets a specific Column. */
- Columns cols = checkColumns(L,1);
- const struct col_names_t* cn;
- const char* colname = luaL_checkstring(L,2);
-
- if (!cols) {
- Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
- c->cinfo = NULL;
- c->col = col_name_to_id(colname);
- c->expired = FALSE;
-
- PUSH_COLUMN(L,c);
- return 1;
- }
-
-
- if (cols->expired) {
- luaL_error(L,"expired column");
- return 0;
- }
-
- for(cn = colnames; cn->name; cn++) {
- if( g_str_equal(cn->name,colname) ) {
- Column c = (Column)g_malloc(sizeof(struct _wslua_col_info));
- c->cinfo = cols->cinfo;
- c->col = col_name_to_id(colname);
- c->expired = FALSE;
-
- PUSH_COLUMN(L,c);
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_META */
-static int Columns__gc(lua_State* L) {
- Columns cols = toColumns(L,1);
-
- if (!cols) return 0;
-
- if (!cols->expired)
- cols->expired = TRUE;
- else
- g_free(cols);
-
- return 0;
-
-}
-
-
-WSLUA_META Columns_meta[] = {
- WSLUA_CLASS_MTREG(Columns,tostring),
- WSLUA_CLASS_MTREG(Columns,newindex),
- WSLUA_CLASS_MTREG(Columns,index),
- { NULL, NULL }
-};
-
-
-int Columns_register(lua_State *L) {
- WSLUA_REGISTER_META(Columns);
- return 0;
-}
WSLUA_CLASS_DEFINE(PrivateTable,FAIL_ON_NULL_OR_EXPIRED("PrivateTable"),NOP);
/* PrivateTable represents the pinfo->private_table. */
@@ -1044,12 +330,12 @@ static int Pinfo_get_columns(lua_State *L) {
cols->expired = FALSE;
if (!colname) {
- PUSH_COLUMNS(L,cols);
+ Push_Columns(L,cols);
} else {
lua_settop(L,0);
- PUSH_COLUMNS(L,cols);
+ Push_Columns(L,cols);
lua_pushstring(L,colname);
- return Columns__index(L);
+ return get_Columns_index(L);
}
return 1;
}
@@ -1197,8 +483,6 @@ int Pinfo_register(lua_State* L) {
WSLUA_REGISTER_META(Pinfo);
WSLUA_REGISTER_ATTRIBUTES(Pinfo);
outstanding_Pinfo = g_ptr_array_new();
- outstanding_Column = g_ptr_array_new();
- outstanding_Columns = g_ptr_array_new();
outstanding_PrivateTable = g_ptr_array_new();
return 0;
}
diff --git a/epan/wslua/wslua_pinfo_common.h b/epan/wslua/wslua_pinfo_common.h
new file mode 100644
index 0000000000..3a3fad3aec
--- /dev/null
+++ b/epan/wslua/wslua_pinfo_common.h
@@ -0,0 +1,35 @@
+/*
+ * wslua_pinfo_common.h
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+void Push_Columns(lua_State *L, Columns c);
+int get_Columns_index(lua_State *L);
diff --git a/epan/wslua/wslua_pref.c b/epan/wslua/wslua_pref.c
new file mode 100644
index 0000000000..cdde74d0c8
--- /dev/null
+++ b/epan/wslua/wslua_pref.c
@@ -0,0 +1,463 @@
+/*
+ * wslua_pref.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+/* WSLUA_CONTINUE_MODULE Proto */
+
+
+WSLUA_CLASS_DEFINE(Pref,NOP,NOP); /* A preference of a Protocol. */
+
+static range_t* get_range(lua_State *L, int idx_r, int idx_m);
+
+static enum_val_t* get_enum(lua_State *L, int idx)
+{
+ double seq;
+ const gchar *str1, *str2;
+ enum_val_t *ret, last = {NULL, NULL, -1};
+ GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t));
+
+ luaL_checktype(L, idx, LUA_TTABLE);
+ lua_pushnil(L); /* first key */
+
+ while (lua_next(L, idx)) {
+ enum_val_t e = {NULL, NULL, -1};
+
+ luaL_checktype(L, -1, LUA_TTABLE);
+ lua_pushnil(L);
+ lua_next(L, -2);
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"First value of an enum table must be string");
+ g_array_free(es,TRUE);
+ return NULL;
+ }
+ str1 = lua_tostring(L, -1);
+
+ lua_pop(L, 1);
+ lua_next(L, -2);
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"Second value of an enum table must be string");
+ g_array_free(es,TRUE);
+ return NULL;
+ }
+ str2 = lua_tostring(L, -1);
+
+ lua_pop(L, 1);
+ lua_next(L, -2);
+ if (! lua_isnumber(L,-1)) {
+ luaL_argerror(L,idx,"Third value of an enum table must be an integer");
+ g_array_free(es,TRUE);
+ return NULL;
+ }
+ seq = lua_tonumber(L, -1);
+
+ e.name = g_strdup(str1);
+ e.description = g_strdup(str2);
+ e.value = (guint32)seq;
+
+ g_array_append_val(es,e);
+
+ lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */
+ }
+
+ g_array_append_val(es,last);
+
+ ret = (enum_val_t*)(void*)es->data;
+
+ g_array_free(es,FALSE);
+
+ return ret;
+}
+
+static int new_pref(lua_State* L, pref_type_t type) {
+ const gchar* label = luaL_optstring(L,1,NULL);
+ const gchar* descr = luaL_optstring(L,3,"");
+
+ Pref pref = (wslua_pref_t *)g_malloc(sizeof(wslua_pref_t));
+ pref->name = NULL;
+ pref->label = label ? g_strdup(label) : NULL;
+ pref->desc = g_strdup(descr);
+ pref->type = type;
+ pref->next = NULL;
+ pref->proto = NULL;
+
+ switch(type) {
+ case PREF_BOOL: {
+ gboolean def = wslua_toboolean(L,2);
+ pref->value.b = def;
+ break;
+ }
+ case PREF_UINT: {
+ guint32 def = wslua_optgint32(L,2,0);
+ pref->value.u = def;
+ break;
+ }
+ case PREF_STRING: {
+ gchar* def = g_strdup(luaL_optstring(L,2,""));
+ pref->value.s = def;
+ break;
+ }
+ case PREF_ENUM: {
+ guint32 def = wslua_optgint32(L,2,0);
+ enum_val_t *enum_val = get_enum(L,4);
+ gboolean radio = wslua_toboolean(L,5);
+ pref->value.e = def;
+ pref->info.enum_info.enumvals = enum_val;
+ pref->info.enum_info.radio_buttons = radio;
+ break;
+ }
+ case PREF_RANGE: {
+ range_t *range = get_range(L,2,4);
+ guint32 max = wslua_optgint32(L,4,0);
+ pref->value.r = range;
+ pref->info.max_value = max;
+ break;
+ }
+ case PREF_STATIC_TEXT: {
+ /* This is just a static text. */
+ break;
+ }
+ default:
+ g_assert_not_reached();
+ break;
+
+ }
+
+ pushPref(L,pref);
+ return 1;
+}
+
+WSLUA_CONSTRUCTOR Pref_bool(lua_State* L) {
+ /* Creates a boolean preference to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the
+ preference input) for this preference. */
+#define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference. */
+#define WSLUA_ARG_Pref_bool_DESCR 3 /* A description of what this preference is. */
+ return new_pref(L,PREF_BOOL);
+}
+
+WSLUA_CONSTRUCTOR Pref_uint(lua_State* L) {
+ /* Creates an (unsigned) integer preference to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the
+ preference input) for this preference. */
+#define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference. */
+#define WSLUA_ARG_Pref_uint_DESCR 3 /* A description of what this preference is. */
+ return new_pref(L,PREF_UINT);
+}
+
+WSLUA_CONSTRUCTOR Pref_string(lua_State* L) {
+ /* Creates a string preference to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the
+ preference input) for this preference. */
+#define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference. */
+#define WSLUA_ARG_Pref_string_DESCR 3 /* A description of what this preference is. */
+ return new_pref(L,PREF_STRING);
+}
+
+WSLUA_CONSTRUCTOR Pref_enum(lua_State* L) {
+ /* Creates an enum preference to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the
+ preference input) for this preference. */
+#define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference. */
+#define WSLUA_ARG_Pref_enum_DESCR 3 /* A description of what this preference is. */
+#define WSLUA_ARG_Pref_enum_ENUM 4 /* An enum Lua table. */
+#define WSLUA_ARG_Pref_enum_RADIO 5 /* Radio button (true) or Combobox (false). */
+ return new_pref(L,PREF_ENUM);
+}
+
+WSLUA_CONSTRUCTOR Pref_range(lua_State* L) {
+ /* Creates a range preference to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference
+ input) for this preference. */
+#define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference, e.g., "53",
+ "10-30", or "10-30,53,55,100-120". */
+#define WSLUA_ARG_Pref_range_DESCR 3 /* A description of what this preference is. */
+#define WSLUA_ARG_Pref_range_MAX 4 /* The maximum value. */
+ return new_pref(L,PREF_RANGE);
+}
+
+WSLUA_CONSTRUCTOR Pref_statictext(lua_State* L) {
+ /* Creates a static text string to be added to a `Proto.prefs` Lua table. */
+#define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text. */
+#define WSLUA_ARG_Pref_statictext_DESCR 2 /* The static text description. */
+ return new_pref(L,PREF_STATIC_TEXT);
+}
+
+static range_t* get_range(lua_State *L, int idx_r, int idx_m)
+{
+ static range_t *ret = NULL;
+ const gchar *pattern = luaL_checkstring(L, idx_r);
+
+ switch (range_convert_str(&ret, pattern, wslua_togint32(L, idx_m))) {
+ case CVT_NO_ERROR:
+ break;
+ case CVT_SYNTAX_ERROR:
+ WSLUA_ARG_ERROR(Pref_range,DEFAULT,"syntax error in default range");
+ return 0;
+ case CVT_NUMBER_TOO_BIG:
+ WSLUA_ARG_ERROR(Pref_range,DEFAULT,"value too large in default range");
+ return 0;
+ default:
+ WSLUA_ARG_ERROR(Pref_range,DEFAULT,"unknown error in default range");
+ return 0;
+ }
+
+ return ret;
+}
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int Pref__gc(lua_State* L) {
+ Pref pref = checkPref(L,1);
+
+ if (pref && ! pref->name) {
+ g_free(pref->label);
+ g_free(pref->desc);
+ if (pref->type == PREF_STRING)
+ g_free((void*)pref->value.s);
+ g_free(pref);
+ }
+
+ return 0;
+}
+
+WSLUA_METHODS Pref_methods[] = {
+ WSLUA_CLASS_FNREG(Pref,bool),
+ WSLUA_CLASS_FNREG(Pref,uint),
+ WSLUA_CLASS_FNREG(Pref,string),
+ WSLUA_CLASS_FNREG(Pref,enum),
+ WSLUA_CLASS_FNREG(Pref,range),
+ WSLUA_CLASS_FNREG(Pref,statictext),
+ { NULL, NULL }
+};
+
+WSLUA_META Pref_meta[] = {
+ { NULL, NULL }
+};
+
+
+WSLUA_REGISTER Pref_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(Pref);
+ return 0;
+}
+
+WSLUA_CLASS_DEFINE(Prefs,NOP,NOP); /* The table of preferences of a protocol. */
+
+WSLUA_METAMETHOD Prefs__newindex(lua_State* L) {
+ /* Creates a new preference. */
+#define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference. */
+#define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object. */
+
+ Pref prefs_p = checkPrefs(L,1);
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__newindex_NAME);
+ Pref pref = checkPref(L,WSLUA_ARG_Prefs__newindex_PREF);
+ Pref p;
+ const gchar *c;
+
+ if (! prefs_p ) return 0;
+
+ if (! pref ) {
+ WSLUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref");
+ return 0;
+ }
+
+ if (pref->name) {
+ WSLUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference");
+ return 0;
+ }
+
+ if (pref->proto) {
+ WSLUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol");
+ return 0;
+ }
+
+ p = prefs_p;
+
+ do {
+ if ( p->name && g_str_equal(p->name,name) ) {
+ luaL_error(L,"a preference named %s exists already",name);
+ return 0;
+ }
+ /*
+ * Make sure that only lower-case ASCII letters, numbers,
+ * underscores, and dots appear in the preference name.
+ */
+ for (c = name; *c != '\0'; c++) {
+ if (!g_ascii_islower(*c) && !g_ascii_isdigit(*c) && *c != '_' && *c != '.')
+ {
+ luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, "
+ "numbers, underscores and dots may be used", name);
+ return 0;
+ }
+ }
+
+ if ( ! p->next) {
+ p->next = pref;
+ pref->name = g_strdup(name);
+
+ if (!pref->label)
+ pref->label = g_strdup(name);
+
+ if (!prefs_p->proto->prefs_module) {
+ prefs_p->proto->prefs_module = prefs_register_protocol(prefs_p->proto->hfid,
+ wslua_prefs_changed);
+ }
+
+ switch(pref->type) {
+ case PREF_BOOL:
+ prefs_register_bool_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc,
+ &(pref->value.b));
+ break;
+ case PREF_UINT:
+ prefs_register_uint_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc,
+ 10,
+ &(pref->value.u));
+ break;
+ case PREF_STRING:
+ prefs_register_string_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc,
+ (const char **)(&(pref->value.s)));
+ break;
+ case PREF_ENUM:
+ prefs_register_enum_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc,
+ &(pref->value.e),
+ pref->info.enum_info.enumvals,
+ pref->info.enum_info.radio_buttons);
+ break;
+ case PREF_RANGE:
+ prefs_register_range_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc,
+ &(pref->value.r),
+ pref->info.max_value);
+ break;
+ case PREF_STATIC_TEXT:
+ prefs_register_static_text_preference(prefs_p->proto->prefs_module,
+ pref->name,
+ pref->label,
+ pref->desc);
+ break;
+ default:
+ WSLUA_ERROR(Prefs__newindex,"Unknow Pref type");
+ break;
+ }
+
+ pref->proto = p->proto;
+
+ WSLUA_RETURN(0);
+ }
+ } while (( p = p->next ));
+
+ luaL_error(L,"this should not happen!");
+
+ WSLUA_RETURN(0);
+}
+
+WSLUA_METAMETHOD Prefs__index(lua_State* L) {
+ /* Get the value of a preference setting. */
+#define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference. */
+
+ Pref prefs_p = checkPrefs(L,1);
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__index_NAME);
+
+ if (! prefs_p ) return 0;
+
+ if (!prefs_p->next) {
+ luaL_error(L,"No preference is registered yet");
+ return 0;
+ }
+
+ prefs_p = prefs_p->next;
+
+ do {
+ if ( g_str_equal(prefs_p->name,name) ) {
+ switch (prefs_p->type) {
+ case PREF_BOOL: lua_pushboolean(L, prefs_p->value.b); break;
+ case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs_p->value.u); break;
+ case PREF_STRING: lua_pushstring(L,prefs_p->value.s); break;
+ case PREF_ENUM: lua_pushnumber(L,(lua_Number)prefs_p->value.e); break;
+ case PREF_RANGE:
+ {
+ char *push_str = range_convert_range(NULL, prefs_p->value.r);
+ lua_pushstring(L, push_str);
+ wmem_free(NULL, push_str);
+ }
+ break;
+ default: WSLUA_ERROR(Prefs__index,"Unknow Pref type"); return 0;
+ }
+ WSLUA_RETURN(1); /* The current value of the preference. */
+ }
+ } while (( prefs_p = prefs_p->next ));
+
+ WSLUA_ARG_ERROR(Prefs__index,NAME,"no preference named like this");
+ return 0;
+}
+
+/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
+static int Prefs__gc(lua_State* L _U_) {
+ /* do NOT free Prefs, it's never free'd */
+ return 0;
+}
+
+WSLUA_META Prefs_meta[] = {
+ WSLUA_CLASS_MTREG(Prefs,newindex),
+ WSLUA_CLASS_MTREG(Prefs,index),
+ { NULL, NULL }
+};
+
+WSLUA_REGISTER Prefs_register(lua_State* L) {
+ WSLUA_REGISTER_META(Prefs);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c
index e78b39d9de..67a0d9ee0c 100644
--- a/epan/wslua/wslua_proto.c
+++ b/epan/wslua/wslua_proto.c
@@ -1,5 +1,5 @@
/*
- * lua_proto.c
+ * wslua_proto.c
*
* wireshark's interface to the Lua Programming Language
*
@@ -27,6 +27,9 @@
#include "config.h"
+#include "wslua.h"
+#include <epan/dissectors/packet-tcp.h>
+
/* WSLUA_MODULE Proto Functions for new protocols and dissectors
The classes and functions in this chapter allow Lua scripts to create new
@@ -42,1466 +45,33 @@
as a heuristic dissector.
*/
-#include "wslua.h"
-#include <epan/dissectors/packet-tcp.h>
-
-#include <epan/exceptions.h>
-#include <epan/show_exception.h>
-
-WSLUA_CLASS_DEFINE(Pref,NOP,NOP); /* A preference of a Protocol. */
-
-static range_t* get_range(lua_State *L, int idx_r, int idx_m);
-
-static enum_val_t* get_enum(lua_State *L, int idx)
-{
- double seq;
- const gchar *str1, *str2;
- enum_val_t *ret, last = {NULL, NULL, -1};
- GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t));
-
- luaL_checktype(L, idx, LUA_TTABLE);
- lua_pushnil(L); /* first key */
-
- while (lua_next(L, idx)) {
- enum_val_t e = {NULL, NULL, -1};
-
- luaL_checktype(L, -1, LUA_TTABLE);
- lua_pushnil(L);
- lua_next(L, -2);
- if (! lua_isstring(L,-1)) {
- luaL_argerror(L,idx,"First value of an enum table must be string");
- g_array_free(es,TRUE);
- return NULL;
- }
- str1 = lua_tostring(L, -1);
-
- lua_pop(L, 1);
- lua_next(L, -2);
- if (! lua_isstring(L,-1)) {
- luaL_argerror(L,idx,"Second value of an enum table must be string");
- g_array_free(es,TRUE);
- return NULL;
- }
- str2 = lua_tostring(L, -1);
-
- lua_pop(L, 1);
- lua_next(L, -2);
- if (! lua_isnumber(L,-1)) {
- luaL_argerror(L,idx,"Third value of an enum table must be an integer");
- g_array_free(es,TRUE);
- return NULL;
- }
- seq = lua_tonumber(L, -1);
-
- e.name = g_strdup(str1);
- e.description = g_strdup(str2);
- e.value = (guint32)seq;
-
- g_array_append_val(es,e);
-
- lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */
- }
-
- g_array_append_val(es,last);
-
- ret = (enum_val_t*)(void*)es->data;
-
- g_array_free(es,FALSE);
-
- return ret;
-}
-
-static int new_pref(lua_State* L, pref_type_t type) {
- const gchar* label = luaL_optstring(L,1,NULL);
- const gchar* descr = luaL_optstring(L,3,"");
-
- Pref pref = (wslua_pref_t *)g_malloc(sizeof(wslua_pref_t));
- pref->name = NULL;
- pref->label = label ? g_strdup(label) : NULL;
- pref->desc = g_strdup(descr);
- pref->type = type;
- pref->next = NULL;
- pref->proto = NULL;
-
- switch(type) {
- case PREF_BOOL: {
- gboolean def = wslua_toboolean(L,2);
- pref->value.b = def;
- break;
- }
- case PREF_UINT: {
- guint32 def = wslua_optgint32(L,2,0);
- pref->value.u = def;
- break;
- }
- case PREF_STRING: {
- gchar* def = g_strdup(luaL_optstring(L,2,""));
- pref->value.s = def;
- break;
- }
- case PREF_ENUM: {
- guint32 def = wslua_optgint32(L,2,0);
- enum_val_t *enum_val = get_enum(L,4);
- gboolean radio = wslua_toboolean(L,5);
- pref->value.e = def;
- pref->info.enum_info.enumvals = enum_val;
- pref->info.enum_info.radio_buttons = radio;
- break;
- }
- case PREF_RANGE: {
- range_t *range = get_range(L,2,4);
- guint32 max = wslua_optgint32(L,4,0);
- pref->value.r = range;
- pref->info.max_value = max;
- break;
- }
- case PREF_STATIC_TEXT: {
- /* This is just a static text. */
- break;
- }
- default:
- g_assert_not_reached();
- break;
-
- }
-
- pushPref(L,pref);
- return 1;
-}
-
-WSLUA_CONSTRUCTOR Pref_bool(lua_State* L) {
- /* Creates a boolean preference to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the
- preference input) for this preference. */
-#define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference. */
-#define WSLUA_ARG_Pref_bool_DESCR 3 /* A description of what this preference is. */
- return new_pref(L,PREF_BOOL);
-}
-
-WSLUA_CONSTRUCTOR Pref_uint(lua_State* L) {
- /* Creates an (unsigned) integer preference to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the
- preference input) for this preference. */
-#define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference. */
-#define WSLUA_ARG_Pref_uint_DESCR 3 /* A description of what this preference is. */
- return new_pref(L,PREF_UINT);
-}
-
-WSLUA_CONSTRUCTOR Pref_string(lua_State* L) {
- /* Creates a string preference to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the
- preference input) for this preference. */
-#define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference. */
-#define WSLUA_ARG_Pref_string_DESCR 3 /* A description of what this preference is. */
- return new_pref(L,PREF_STRING);
-}
-
-WSLUA_CONSTRUCTOR Pref_enum(lua_State* L) {
- /* Creates an enum preference to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the
- preference input) for this preference. */
-#define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference. */
-#define WSLUA_ARG_Pref_enum_DESCR 3 /* A description of what this preference is. */
-#define WSLUA_ARG_Pref_enum_ENUM 4 /* An enum Lua table. */
-#define WSLUA_ARG_Pref_enum_RADIO 5 /* Radio button (true) or Combobox (false). */
- return new_pref(L,PREF_ENUM);
-}
-
-WSLUA_CONSTRUCTOR Pref_range(lua_State* L) {
- /* Creates a range preference to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference
- input) for this preference. */
-#define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference, e.g., "53",
- "10-30", or "10-30,53,55,100-120". */
-#define WSLUA_ARG_Pref_range_DESCR 3 /* A description of what this preference is. */
-#define WSLUA_ARG_Pref_range_MAX 4 /* The maximum value. */
- return new_pref(L,PREF_RANGE);
-}
-
-WSLUA_CONSTRUCTOR Pref_statictext(lua_State* L) {
- /* Creates a static text string to be added to a `Proto.prefs` Lua table. */
-#define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text. */
-#define WSLUA_ARG_Pref_statictext_DESCR 2 /* The static text description. */
- return new_pref(L,PREF_STATIC_TEXT);
-}
-
-static range_t* get_range(lua_State *L, int idx_r, int idx_m)
-{
- static range_t *ret = NULL;
- const gchar *pattern = luaL_checkstring(L, idx_r);
-
- switch (range_convert_str(&ret, pattern, wslua_togint32(L, idx_m))) {
- case CVT_NO_ERROR:
- break;
- case CVT_SYNTAX_ERROR:
- WSLUA_ARG_ERROR(Pref_range,DEFAULT,"syntax error in default range");
- return 0;
- case CVT_NUMBER_TOO_BIG:
- WSLUA_ARG_ERROR(Pref_range,DEFAULT,"value too large in default range");
- return 0;
- default:
- WSLUA_ARG_ERROR(Pref_range,DEFAULT,"unknown error in default range");
- return 0;
- }
-
- return ret;
-}
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int Pref__gc(lua_State* L) {
- Pref pref = checkPref(L,1);
-
- if (pref && ! pref->name) {
- g_free(pref->label);
- g_free(pref->desc);
- if (pref->type == PREF_STRING)
- g_free((void*)pref->value.s);
- g_free(pref);
- }
-
- return 0;
-}
-
-WSLUA_METHODS Pref_methods[] = {
- WSLUA_CLASS_FNREG(Pref,bool),
- WSLUA_CLASS_FNREG(Pref,uint),
- WSLUA_CLASS_FNREG(Pref,string),
- WSLUA_CLASS_FNREG(Pref,enum),
- WSLUA_CLASS_FNREG(Pref,range),
- WSLUA_CLASS_FNREG(Pref,statictext),
- { NULL, NULL }
-};
-
-WSLUA_META Pref_meta[] = {
- { NULL, NULL }
-};
-
-
-WSLUA_REGISTER Pref_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(Pref);
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(Prefs,NOP,NOP); /* The table of preferences of a protocol. */
-
-WSLUA_METAMETHOD Prefs__newindex(lua_State* L) {
- /* Creates a new preference. */
-#define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference. */
-#define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object. */
-
- Pref prefs_p = checkPrefs(L,1);
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__newindex_NAME);
- Pref pref = checkPref(L,WSLUA_ARG_Prefs__newindex_PREF);
- Pref p;
- const gchar *c;
- if (! prefs_p ) return 0;
-
- if (! pref ) {
- WSLUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref");
- return 0;
- }
-
- if (pref->name) {
- WSLUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference");
- return 0;
- }
-
- if (pref->proto) {
- WSLUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol");
- return 0;
- }
-
- p = prefs_p;
-
- do {
- if ( p->name && g_str_equal(p->name,name) ) {
- luaL_error(L,"a preference named %s exists already",name);
- return 0;
- }
- /*
- * Make sure that only lower-case ASCII letters, numbers,
- * underscores, and dots appear in the preference name.
- */
- for (c = name; *c != '\0'; c++) {
- if (!g_ascii_islower(*c) && !g_ascii_isdigit(*c) && *c != '_' && *c != '.')
- {
- luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, "
- "numbers, underscores and dots may be used", name);
- return 0;
- }
- }
-
- if ( ! p->next) {
- p->next = pref;
- pref->name = g_strdup(name);
-
- if (!pref->label)
- pref->label = g_strdup(name);
-
- if (!prefs_p->proto->prefs_module) {
- prefs_p->proto->prefs_module = prefs_register_protocol(prefs_p->proto->hfid,
- wslua_prefs_changed);
- }
-
- switch(pref->type) {
- case PREF_BOOL:
- prefs_register_bool_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc,
- &(pref->value.b));
- break;
- case PREF_UINT:
- prefs_register_uint_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc,
- 10,
- &(pref->value.u));
- break;
- case PREF_STRING:
- prefs_register_string_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc,
- (const char **)(&(pref->value.s)));
- break;
- case PREF_ENUM:
- prefs_register_enum_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc,
- &(pref->value.e),
- pref->info.enum_info.enumvals,
- pref->info.enum_info.radio_buttons);
- break;
- case PREF_RANGE:
- prefs_register_range_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc,
- &(pref->value.r),
- pref->info.max_value);
- break;
- case PREF_STATIC_TEXT:
- prefs_register_static_text_preference(prefs_p->proto->prefs_module,
- pref->name,
- pref->label,
- pref->desc);
- break;
- default:
- WSLUA_ERROR(Prefs__newindex,"Unknow Pref type");
- break;
- }
-
- pref->proto = p->proto;
-
- WSLUA_RETURN(0);
- }
- } while (( p = p->next ));
-
- luaL_error(L,"this should not happen!");
-
- WSLUA_RETURN(0);
-}
-
-WSLUA_METAMETHOD Prefs__index(lua_State* L) {
- /* Get the value of a preference setting. */
-#define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference. */
-
- Pref prefs_p = checkPrefs(L,1);
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__index_NAME);
-
- if (! prefs_p ) return 0;
+/*
+ * _func_saver stores function refs so that Lua won't garbage collect them prematurely.
+ * It is only used by tcp_dissect_pdus right now.
+ */
+typedef struct _func_saver {
+ lua_State* state;
+ int get_len_ref;
+ int dissect_ref;
+} func_saver_t;
- if (!prefs_p->next) {
- luaL_error(L,"No preference is registered yet");
- return 0;
- }
+static GPtrArray* outstanding_FuncSavers = NULL;
- prefs_p = prefs_p->next;
-
- do {
- if ( g_str_equal(prefs_p->name,name) ) {
- switch (prefs_p->type) {
- case PREF_BOOL: lua_pushboolean(L, prefs_p->value.b); break;
- case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs_p->value.u); break;
- case PREF_STRING: lua_pushstring(L,prefs_p->value.s); break;
- case PREF_ENUM: lua_pushnumber(L,(lua_Number)prefs_p->value.e); break;
- case PREF_RANGE:
- {
- char *push_str = range_convert_range(NULL, prefs_p->value.r);
- lua_pushstring(L, push_str);
- wmem_free(NULL, push_str);
- }
- break;
- default: WSLUA_ERROR(Prefs__index,"Unknow Pref type"); return 0;
+void clear_outstanding_FuncSavers(void) {
+ while (outstanding_FuncSavers->len) {
+ func_saver_t* fs = (func_saver_t*)g_ptr_array_remove_index_fast(outstanding_FuncSavers,0);
+ if (fs->state) {
+ lua_State* L = fs->state;
+ if (fs->get_len_ref != LUA_NOREF) {
+ luaL_unref(L, LUA_REGISTRYINDEX, fs->get_len_ref);
}
- WSLUA_RETURN(1); /* The current value of the preference. */
- }
- } while (( prefs_p = prefs_p->next ));
-
- WSLUA_ARG_ERROR(Prefs__index,NAME,"no preference named like this");
- return 0;
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int Prefs__gc(lua_State* L _U_) {
- /* do NOT free Prefs, it's never free'd */
- return 0;
-}
-
-WSLUA_META Prefs_meta[] = {
- WSLUA_CLASS_MTREG(Prefs,newindex),
- WSLUA_CLASS_MTREG(Prefs,index),
- { NULL, NULL }
-};
-
-WSLUA_REGISTER Prefs_register(lua_State* L) {
- WSLUA_REGISTER_META(Prefs);
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(ProtoField,FAIL_ON_NULL("null ProtoField"),NOP);
- /* A Protocol field (to be used when adding items to the dissection tree). */
-
-static const wslua_ft_types_t ftenums[] = {
- {"ftypes.NONE", FT_NONE},
- {"ftypes.BOOLEAN", FT_BOOLEAN},
- {"ftypes.UINT8", FT_UINT8},
- {"ftypes.UINT16", FT_UINT16},
- {"ftypes.UINT24", FT_UINT24},
- {"ftypes.UINT32", FT_UINT32},
- {"ftypes.UINT64", FT_UINT64},
- {"ftypes.INT8", FT_INT8},
- {"ftypes.INT16", FT_INT16},
- {"ftypes.INT24", FT_INT24},
- {"ftypes.INT32", FT_INT32},
- {"ftypes.INT64", FT_INT64},
- {"ftypes.FLOAT", FT_FLOAT},
- {"ftypes.DOUBLE", FT_DOUBLE},
- {"ftypes.ABSOLUTE_TIME", FT_ABSOLUTE_TIME},
- {"ftypes.RELATIVE_TIME", FT_RELATIVE_TIME},
- {"ftypes.STRING", FT_STRING},
- {"ftypes.STRINGZ", FT_STRINGZ},
- {"ftypes.ETHER", FT_ETHER},
- {"ftypes.BYTES", FT_BYTES},
- {"ftypes.UINT_BYTES", FT_UINT_BYTES},
- {"ftypes.IPv4", FT_IPv4},
- {"ftypes.IPv6", FT_IPv6},
- {"ftypes.IPXNET", FT_IPXNET},
- {"ftypes.FRAMENUM", FT_FRAMENUM},
- {"ftypes.GUID", FT_GUID},
- {"ftypes.OID", FT_OID},
- {"ftypes.SYSTEM_ID", FT_SYSTEM_ID},
- {"ftypes.REL_OID", FT_REL_OID},
- {"ftypes.EUI64", FT_EUI64},
- {"ftypes.FCWWN", FT_FCWWN},
- {NULL, FT_NONE}
-};
-
-static enum ftenum get_ftenum(const gchar* type) {
- const wslua_ft_types_t* ts;
- for (ts = ftenums; ts->str; ts++) {
- if ( g_str_equal(ts->str,type) ) {
- return ts->id;
- }
- }
- return FT_NONE;
-}
-
-static const gchar* ftenum_to_string(enum ftenum ft) {
- const wslua_ft_types_t* ts;
- for (ts = ftenums; ts->str; ts++) {
- if ( ts->id == ft ) {
- return ts->str;
- }
- }
- return NULL;
-}
-
-struct field_display_string_t {
- const gchar* str;
- unsigned base;
-};
-
-static const struct field_display_string_t base_displays[] = {
- {"base.NONE", BASE_NONE},
- {"base.DEC", BASE_DEC},
- {"base.HEX", BASE_HEX},
- {"base.OCT", BASE_OCT},
- {"base.DEC_HEX", BASE_DEC_HEX},
- {"base.HEX_DEC", BASE_HEX_DEC},
- /* for FT_BOOLEAN, how wide the parent bitfield is */
- {"8",8},
- {"16",16},
- {"24",24},
- {"32",32},
- /* for FT_ABSOLUTE_TIME use values in absolute_time_display_e */
- {"LOCAL", ABSOLUTE_TIME_LOCAL},
- {"UTC", ABSOLUTE_TIME_UTC},
- {"DOY_UTC", ABSOLUTE_TIME_DOY_UTC},
- {NULL,0}
-};
-
-static const gchar* base_to_string(unsigned base) {
- const struct field_display_string_t* b;
- for (b=base_displays;b->str;b++) {
- if ( base == b->base)
- return b->str;
- }
- return NULL;
-}
-
-static unsigned string_to_base(const gchar* str) {
- const struct field_display_string_t* b;
- for (b=base_displays;b->str;b++) {
- if ( g_str_equal(str,b->str))
- return b->base;
- }
- return BASE_NONE;
-}
-
-static value_string* value_string_from_table(lua_State* L, int idx) {
- GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string));
- value_string* ret;
-
- if(lua_isnil(L,idx)) {
- return NULL;
- } else if (!lua_istable(L,idx)) {
- luaL_argerror(L,idx,"must be a table");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- lua_pushnil(L);
-
- while (lua_next(L, idx) != 0) {
- value_string v = {0,NULL};
-
- if (! lua_isnumber(L,-2)) {
- luaL_argerror(L,idx,"All keys of a table used as value_string must be integers");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- if (! lua_isstring(L,-1)) {
- luaL_argerror(L,idx,"All values of a table used as value_string must be strings");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- v.value = wslua_toguint32(L,-2);
- v.strptr = g_strdup(lua_tostring(L,-1));
-
- g_array_append_val(vs,v);
-
- lua_pop(L, 1);
- }
-
- ret = (value_string*)(void*)vs->data;
-
- g_array_free(vs,FALSE);
-
- return ret;
-}
-
-static val64_string* val64_string_from_table(lua_State* L, int idx) {
- GArray* vs = g_array_new(TRUE,TRUE,sizeof(val64_string));
- val64_string* ret;
-
- if(lua_isnil(L,idx)) {
- return NULL;
- } else if (!lua_istable(L,idx)) {
- luaL_argerror(L,idx,"must be a table");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- lua_pushnil(L);
-
- while (lua_next(L, idx) != 0) {
- val64_string v = {0,NULL};
-
- if (! lua_isnumber(L,-2)) {
- luaL_argerror(L,idx,"All keys of a table used as value string must be integers");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- if (! lua_isstring(L,-1)) {
- luaL_argerror(L,idx,"All values of a table used as value string must be strings");
- g_array_free(vs,TRUE);
- return NULL;
- }
-
- v.value = wslua_toguint64(L, -2);
- v.strptr = g_strdup(lua_tostring(L,-1));
-
- g_array_append_val(vs,v);
-
- lua_pop(L, 1);
- }
-
- ret = (val64_string*)(void*)vs->data;
-
- g_array_free(vs,FALSE);
-
- return ret;
-}
-
-static true_false_string* true_false_string_from_table(lua_State* L, int idx) {
- GArray* tfs = g_array_new(TRUE,TRUE,sizeof(true_false_string));
- true_false_string* ret;
- true_false_string tf = { "True", "False" };
-
- if (lua_isnil(L,idx)) {
- return NULL;
- } else if (!lua_istable(L,idx)) {
- luaL_argerror(L,idx,"must be a table");
- g_array_free(tfs,TRUE);
- return NULL;
- }
-
- lua_pushnil(L);
-
- while (lua_next(L, idx)) {
-
- if (! lua_isnumber(L,-2)) {
- luaL_argerror(L,idx,"All keys of a table used as true_false_string must be integers");
- g_array_free(tfs,TRUE);
- return NULL;
- }
-
- if (! lua_isstring(L,-1)) {
- luaL_argerror(L,idx,"All values of a table used as true_false_string must be strings");
- g_array_free(tfs,TRUE);
- return NULL;
- }
-
- /* arrays in LUA start with index number 1 */
- if (lua_tointeger(L,-2) == 1)
- tf.true_string = g_strdup(lua_tostring(L,-1));
-
- if (lua_tointeger(L,-2) == 2)
- tf.false_string = g_strdup(lua_tostring(L,-1));
-
- lua_pop(L, 1);
- }
-
- g_array_append_val(tfs,tf);
-
- ret = (true_false_string*)(void*)tfs->data;
-
- g_array_free(tfs,FALSE);
-
- return ret;
-}
-
-static const gchar* check_field_name(lua_State* L, const int abbr_idx, const enum ftenum type) {
- const gchar* abbr = luaL_checkstring(L,abbr_idx);
- const header_field_info* hfinfo = NULL;
-
- if (!abbr[0]) {
- luaL_argerror(L, abbr_idx, "Empty field name abbreviation");
- return NULL;
- }
-
- if (proto_check_field_name(abbr)) {
- luaL_argerror(L, abbr_idx, "Invalid char in abbrev");
- return NULL;
- }
-
- hfinfo = proto_registrar_get_byname(abbr);
-
- if (hfinfo && !ftype_similar_types(type, hfinfo->type)) {
- luaL_argerror(L, abbr_idx, "A field of an incompatible ftype with this abbrev already exists");
- return NULL;
- }
-
- return abbr;
-}
-
-WSLUA_CONSTRUCTOR ProtoField_new(lua_State* L) {
- /* Creates a new `ProtoField` object to be used for a protocol field. */
-#define WSLUA_ARG_ProtoField_new_NAME 1 /* Actual name of the field (the string that
- appears in the tree). */
-#define WSLUA_ARG_ProtoField_new_ABBR 2 /* Filter name of the field (the string that
- is used in filters). */
-#define WSLUA_ARG_ProtoField_new_TYPE 3 /* Field Type: one of: `ftypes.BOOLEAN`, `ftypes.UINT8`,
- `ftypes.UINT16`, `ftypes.UINT24`, `ftypes.UINT32`, `ftypes.UINT64`, `ftypes.INT8`,
- `ftypes.INT16`, `ftypes.INT24`, `ftypes.INT32`, `ftypes.INT64`, `ftypes.FLOAT`,
- `ftypes.DOUBLE` , `ftypes.ABSOLUTE_TIME`, `ftypes.RELATIVE_TIME`, `ftypes.STRING`,
- `ftypes.STRINGZ`, `ftypes.UINT_STRING`, `ftypes.ETHER`, `ftypes.BYTES`,
- `ftypes.UINT_BYTES`, `ftypes.IPv4`, `ftypes.IPv6`, `ftypes.IPXNET`, `ftypes.FRAMENUM`,
- `ftypes.PCRE`, `ftypes.GUID`, `ftypes.OID`, `ftypes.REL_OID`, `ftypes.SYSTEM_ID`,
- `ftypes.EUI64` or `ftypes.NONE`.
- */
-#define WSLUA_OPTARG_ProtoField_new_VALUESTRING 4 /* A table containing the text that
- corresponds to the values. */
-#define WSLUA_OPTARG_ProtoField_new_BASE 5 /* The representation, one of: `base.NONE`, `base.DEC`,
- `base.HEX`, `base.OCT`, `base.DEC_HEX`, or
- `base.HEX_DEC`. */
-#define WSLUA_OPTARG_ProtoField_new_MASK 6 /* The bitmask to be used. */
-#define WSLUA_OPTARG_ProtoField_new_DESCR 7 /* The description of the field. */
-
- ProtoField f;
- int nargs = lua_gettop(L);
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_ProtoField_new_NAME);
- const gchar* abbr = NULL;
- enum ftenum type;
- value_string *vs32 = NULL;
- val64_string *vs64 = NULL;
- true_false_string *tfs = NULL;
- unsigned base;
- guint32 mask = wslua_optguint32(L, WSLUA_OPTARG_ProtoField_new_MASK, 0x0);
- const gchar *blob = luaL_optstring(L,WSLUA_OPTARG_ProtoField_new_DESCR,NULL);
-
- if (lua_isnumber(L,WSLUA_ARG_ProtoField_new_TYPE)) {
- type = (enum ftenum)luaL_checkinteger(L,WSLUA_ARG_ProtoField_new_TYPE);
- } else {
- type = get_ftenum(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_TYPE));
- }
-
- abbr = check_field_name(L,WSLUA_ARG_ProtoField_new_ABBR,type);
-
- if (lua_isnumber(L, WSLUA_OPTARG_ProtoField_new_BASE)) {
- base = (unsigned)luaL_optinteger(L, WSLUA_OPTARG_ProtoField_new_BASE, BASE_NONE);
- } else {
- base = string_to_base(luaL_optstring(L, WSLUA_OPTARG_ProtoField_new_BASE, "BASE_NONE"));
- }
-
- switch (type) {
- case FT_FRAMENUM:
- if (base != BASE_NONE) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"FRAMENUM must use base.NONE");
- return 0;
- }
- if (mask) {
- WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"FRAMENUM can not have a bitmask");
- return 0;
- }
- break;
- case FT_UINT8:
- case FT_UINT16:
- case FT_UINT24:
- case FT_UINT32:
- case FT_UINT64:
- case FT_INT8:
- case FT_INT16:
- case FT_INT24:
- case FT_INT32:
- case FT_INT64:
- if (base == BASE_NONE) {
- base = BASE_DEC; /* Default base for integer */
- } else if (base < BASE_DEC || base > BASE_HEX_DEC) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be either base.DEC, base.HEX, base.OCT,"
- " base.DEC_HEX, base.DEC_HEX or base.HEX_DEC");
- return 0;
- }
- if ((base == BASE_HEX || base == BASE_OCT) &&
- (type == FT_INT8 || type == FT_INT16 || type == FT_INT24 || type == FT_INT32 || type == FT_INT64))
- {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"This type does not display as hexadecimal");
- return 0;
- }
- if (nargs >= WSLUA_OPTARG_ProtoField_new_VALUESTRING && !lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING)) {
- if (type == FT_UINT64 || type == FT_INT64) {
- vs64 = val64_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
- } else {
- vs32 = value_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
+ if (fs->dissect_ref != LUA_NOREF) {
+ luaL_unref(L, LUA_REGISTRYINDEX, fs->dissect_ref);
}
}
- break;
- case FT_BOOLEAN:
- if (mask == 0x0 && base != BASE_NONE) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be base.NONE if bitmask is zero.");
- return 0;
- }
- if (mask != 0x0 && (base < 1 || base > 64)) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be between 1 and 64 if bitmask is non-zero.");
- return 0;
- }
- if (nargs >= WSLUA_OPTARG_ProtoField_new_VALUESTRING && !lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING)) {
- tfs = true_false_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
- }
- break;
- case FT_ABSOLUTE_TIME:
- if (base == BASE_NONE) {
- base = ABSOLUTE_TIME_LOCAL; /* Default base for FT_ABSOLUTE_TIME */
- } else if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be either LOCAL, UTC, or DOY_UTC");
- return 0;
- }
- if (mask) {
- WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"ABSOLUTE_TIME can not have a bitmask");
- return 0;
- }
- break;
- case FT_NONE:
- case FT_IPv4:
- case FT_IPv6:
- case FT_IPXNET:
- case FT_ETHER:
- case FT_FLOAT:
- case FT_DOUBLE:
- case FT_RELATIVE_TIME:
- case FT_STRING:
- case FT_STRINGZ:
- case FT_BYTES:
- case FT_UINT_BYTES:
- case FT_GUID:
- case FT_OID:
- case FT_SYSTEM_ID:
- case FT_REL_OID:
- case FT_EUI64:
- case FT_VINES:
- case FT_FCWWN:
- if (base != BASE_NONE) {
- WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be base.NONE");
- return 0;
- }
- if (mask) {
- WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"This type can not have a bitmask");
- return 0;
- }
- break;
- default:
- WSLUA_ARG_ERROR(ProtoField_new,TYPE,"Invalid field type");
- break;
- }
-
- f = g_new(wslua_field_t,1);
-
- f->hfid = -2;
- f->ett = -1;
- f->name = g_strdup(name);
- f->abbrev = g_strdup(abbr);
- f->type = type;
- f->base = base;
- if (tfs) {
- f->vs = TFS(tfs);
- } else if (vs32) {
- f->vs = VALS(vs32);
- } else if (vs64) {
- /* Indicate that we are using val64_string */
- f->base |= BASE_VAL64_STRING;
- f->vs = VALS(vs64);
- } else {
- f->vs = NULL;
- }
- f->mask = mask;
- if (blob && strcmp(blob, f->name) != 0) {
- f->blob = g_strdup(blob);
- } else {
- f->blob = NULL;
- }
-
- pushProtoField(L,f);
-
- WSLUA_RETURN(1); /* The newly created `ProtoField` object. */
-}
-
-static int ProtoField_integer(lua_State* L, enum ftenum type) {
- ProtoField f;
- const gchar* abbr = check_field_name(L,1,type);
- const gchar* name = luaL_optstring(L,2,abbr);
- unsigned default_base = (type == FT_FRAMENUM) ? BASE_NONE : BASE_DEC;
- unsigned base = (unsigned)luaL_optinteger(L, 3, default_base);
- value_string* vs32 = NULL;
- val64_string* vs64 = NULL;
- guint32 mask = wslua_optguint32(L,5,0);
- const gchar* blob = luaL_optstring(L,6,NULL);
-
- if (lua_gettop(L) > 3) {
- if (type == FT_UINT64 || type == FT_INT64) {
- vs64 = val64_string_from_table(L,4);
- } else {
- vs32 = value_string_from_table(L,4);
- }
- }
-
- if (type == FT_FRAMENUM) {
- if (base != BASE_NONE)
- luaL_argerror(L, 3, "ftypes.FRAMENUMs must use base.NONE");
- else if (mask)
- luaL_argerror(L, 3, "ftypes.FRAMENUMs can not have a bitmask");
- } else if (base < BASE_DEC || base > BASE_HEX_DEC) {
- luaL_argerror(L, 3, "Base must be either base.DEC, base.HEX, base.OCT,"
- " base.DEC_HEX, base.DEC_HEX or base.HEX_DEC");
- return 0;
- } else if ((base == BASE_HEX || base == BASE_OCT) &&
- (type == FT_INT8 || type == FT_INT16 || type == FT_INT24 || type == FT_INT32 || type == FT_INT64)) {
- luaL_argerror(L, 3, "This type does not display as hexadecimal");
- return 0;
- }
-
- f = g_new(wslua_field_t,1);
-
- f->hfid = -2;
- f->ett = -1;
- f->name = g_strdup(name);
- f->abbrev = g_strdup(abbr);
- f->type = type;
- f->base = base;
- if (vs64) {
- /* Indicate that we are using val64_string */
- f->base |= BASE_VAL64_STRING;
- f->vs = VALS(vs64);
- } else {
- f->vs = VALS(vs32);
- }
- f->mask = mask;
- if (blob && strcmp(blob, f->name) != 0) {
- f->blob = g_strdup(blob);
- } else {
- f->blob = NULL;
- }
-
- pushProtoField(L,f);
-
- return 1;
-}
-
-#define PROTOFIELD_INTEGER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_integer(L,FT); }
-/* _WSLUA_CONSTRUCTOR_ ProtoField_uint8 Creates a `ProtoField` of an unsigned 8-bit integer (i.e., a byte). */
-/* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_uint8_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_uint16 Creates a `ProtoField` of an unsigned 16-bit integer. */
-/* WSLUA_ARG_Protofield_uint16_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_uint16_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_uint16_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_uint16_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_uint16_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_uint16_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_uint24 Creates a `ProtoField` of an unsigned 24-bit integer. */
-/* WSLUA_ARG_Protofield_uint24_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_uint24_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_uint24_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_uint24_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_uint24_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_uint24_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_uint32 Creates a `ProtoField` of an unsigned 32-bit integer. */
-/* WSLUA_ARG_Protofield_uint32_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_uint32_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_uint32_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_uint32_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_uint32_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_uint32_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_uint64 Creates a `ProtoField` of an unsigned 64-bit integer. */
-/* WSLUA_ARG_Protofield_uint64_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_uint64_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_uint64_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_uint64_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_uint64_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_uint64_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_int8 Creates a `ProtoField` of a signed 8-bit integer (i.e., a byte). */
-/* WSLUA_ARG_Protofield_int8_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_int8_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_int8_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_int8_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_int8_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_int8_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_int16 Creates a `ProtoField` of a signed 16-bit integer. */
-/* WSLUA_ARG_Protofield_int16_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_int16_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_int16_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_int16_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_int16_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_int16_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_int24 Creates a `ProtoField` of a signed 24-bit integer. */
-/* WSLUA_ARG_Protofield_int24_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_int24_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_int24_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_int24_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_int24_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_int24_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_int32 Creates a `ProtoField` of a signed 32-bit integer. */
-/* WSLUA_ARG_Protofield_int32_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_int32_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_int32_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_int32_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_int32_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_int32_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_int64 Creates a `ProtoField` of a signed 64-bit integer. */
-/* WSLUA_ARG_Protofield_int64_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_int64_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_int64_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
-/* WSLUA_OPTARG_Protofield_int64_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_int64_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_int64_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_framenum Creates a `ProtoField` for a frame number (for hyperlinks between frames). */
-/* WSLUA_ARG_Protofield_framenum_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_framenum_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_framenum_BASE Only `base.NONE` is supported for framenum. */
-/* WSLUA_OPTARG_Protofield_framenum_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_framenum_MASK Integer mask of this field, which must be 0 for framenum. */
-/* WSLUA_OPTARG_Protofield_framenum_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-PROTOFIELD_INTEGER(uint8,FT_UINT8)
-PROTOFIELD_INTEGER(uint16,FT_UINT16)
-PROTOFIELD_INTEGER(uint24,FT_UINT24)
-PROTOFIELD_INTEGER(uint32,FT_UINT32)
-PROTOFIELD_INTEGER(uint64,FT_UINT64)
-PROTOFIELD_INTEGER(int8,FT_INT8)
-PROTOFIELD_INTEGER(int16,FT_INT16)
-PROTOFIELD_INTEGER(int24,FT_INT24)
-PROTOFIELD_INTEGER(int32,FT_INT32)
-PROTOFIELD_INTEGER(int64,FT_INT64)
-PROTOFIELD_INTEGER(framenum,FT_FRAMENUM)
-
-static int ProtoField_boolean(lua_State* L, enum ftenum type) {
- ProtoField f;
- const gchar* abbr = check_field_name(L,1,type);
- const gchar* name = luaL_optstring(L,2,abbr);
- unsigned base = (unsigned)luaL_optinteger(L, 3, BASE_NONE);
- true_false_string* tfs = NULL;
- guint32 mask = wslua_optguint32(L,5,0);
- const gchar* blob = luaL_optstring(L,6,NULL);
-
- if (mask == 0x0 && base != BASE_NONE) {
- luaL_argerror(L,2,"Fieldbase (fielddisplay) must be base.NONE"
- " if bitmask is zero.");
- return 0;
- }
-
- if (mask != 0x0 && (base < 1 || base > 64)) {
- luaL_argerror(L,2,"Fieldbase (fielddisplay) must be between 1 and 64"
- " if bitmask is non-zero.");
- return 0;
- }
-
- if (lua_gettop(L) > 3 && !lua_isnil(L,4)) {
- tfs = true_false_string_from_table(L,4);
- }
-
- f = g_new(wslua_field_t,1);
-
- f->hfid = -2;
- f->ett = -1;
- f->name = g_strdup(name);
- f->abbrev = g_strdup(abbr);
- f->type = type;
- f->vs = TFS(tfs);
- f->base = base;
- f->mask = mask;
- if (blob && strcmp(blob, f->name) != 0) {
- f->blob = g_strdup(blob);
- } else {
- f->blob = NULL;
- }
-
- pushProtoField(L,f);
-
- return 1;
-}
-
-#define PROTOFIELD_BOOL(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_boolean(L,FT); }
-/* _WSLUA_CONSTRUCTOR_ ProtoField_bool Creates a `ProtoField` for a boolean true/false value. */
-/* WSLUA_ARG_Protofield_bool_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_bool_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_bool_DISPLAY how wide the parent bitfield is (`base.NONE` is used for NULL-value). */
-/* WSLUA_OPTARG_Protofield_bool_VALUESTRING A table containing the text that corresponds to the values. */
-/* WSLUA_OPTARG_Protofield_bool_MASK Integer mask of this field. */
-/* WSLUA_OPTARG_Protofield_bool_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* XXX: T/F strings */
-PROTOFIELD_BOOL(bool,FT_BOOLEAN)
-
-static int ProtoField_time(lua_State* L,enum ftenum type) {
- ProtoField f;
- const gchar* abbr = NULL;
- const gchar* name = luaL_optstring(L,2,abbr);
- unsigned base = (unsigned)luaL_optinteger(L,3,ABSOLUTE_TIME_LOCAL);
- const gchar* blob = NULL;
-
- if (type == FT_ABSOLUTE_TIME) {
- abbr = check_field_name(L,1,type);
- blob = luaL_optstring(L,4,NULL);
- if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) {
- luaL_argerror(L, 3, "Base must be either LOCAL, UTC, or DOY_UTC");
- return 0;
- }
- } else {
- abbr = check_field_name(L,1,type);
- blob = luaL_optstring(L,3,NULL);
- }
-
- f = g_new(wslua_field_t,1);
-
- f->hfid = -2;
- f->ett = -1;
- f->name = g_strdup(name);
- f->abbrev = g_strdup(abbr);
- f->type = type;
- f->vs = NULL;
- f->base = base;
- f->mask = 0;
- if (blob && strcmp(blob, f->name) != 0) {
- f->blob = g_strdup(blob);
- } else {
- f->blob = NULL;
- }
-
- pushProtoField(L,f);
-
- return 1;
-}
-
-#define PROTOFIELD_TIME(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_time(L,FT); }
-/* _WSLUA_CONSTRUCTOR_ ProtoField_absolute_time Creates a `ProtoField` of a time_t structure value. */
-/* WSLUA_ARG_Protofield_absolute_time_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_absolute_time_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_absolute_time_BASE One of `base.LOCAL`, `base.UTC` or `base.DOY_UTC`. */
-/* WSLUA_OPTARG_Protofield_absolute_time_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_relative_time Creates a `ProtoField` of a time_t structure value. */
-/* WSLUA_ARG_Protofield_relative_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_relative_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_relative_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-
-PROTOFIELD_TIME(absolute_time,FT_ABSOLUTE_TIME)
-
-static int ProtoField_other(lua_State* L,enum ftenum type) {
- ProtoField f;
- const gchar* abbr = check_field_name(L,1,type);
- const gchar* name = luaL_optstring(L,2,abbr);
- const gchar* blob = luaL_optstring(L,3,NULL);
-
- f = g_new(wslua_field_t,1);
-
- f->hfid = -2;
- f->ett = -1;
- f->name = g_strdup(name);
- f->abbrev = g_strdup(abbr);
- f->type = type;
- f->vs = NULL;
- f->base = BASE_NONE;
- f->mask = 0;
- if (blob && strcmp(blob, f->name) != 0) {
- f->blob = g_strdup(blob);
- } else {
- f->blob = NULL;
- }
-
- pushProtoField(L,f);
-
- return 1;
-}
-
-#define PROTOFIELD_OTHER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_other(L,FT); }
-/* _WSLUA_CONSTRUCTOR_ ProtoField_none Creates a `ProtoField` of an unstructured type. */
-/* WSLUA_ARG_Protofield_none_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_none_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_none_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_ipv4 Creates a `ProtoField` of an IPv4 address (4 bytes). */
-/* WSLUA_ARG_Protofield_ipv4_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_ipv4_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_ipv4_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_ipv6 Creates a `ProtoField` of an IPv6 address (16 bytes). */
-/* WSLUA_ARG_Protofield_ipv6_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_ipv6_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_ipv6_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_ether Creates a `ProtoField` of an Ethernet address (6 bytes). */
-/* WSLUA_ARG_Protofield_ether_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_ether_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_ether_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_float Creates a `ProtoField` of a floating point number (4 bytes). */
-/* WSLUA_ARG_Protofield_float_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_float_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_float_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_double Creates a `ProtoField` of a double-precision floating point (8 bytes). */
-/* WSLUA_ARG_Protofield_double_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_double_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_double_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_string Creates a `ProtoField` of a string value. */
-/* WSLUA_ARG_Protofield_string_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_string_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_string_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_stringz Creates a `ProtoField` of a zero-terminated string value. */
-/* WSLUA_ARG_Protofield_stringz_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_stringz_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_stringz_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_bytes Creates a `ProtoField` for an arbitrary number of bytes. */
-/* WSLUA_ARG_Protofield_bytes_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_bytes_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_bytes_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_ubytes Creates a `ProtoField` for an arbitrary number of unsigned bytes. */
-/* WSLUA_ARG_Protofield_ubytes_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_ubytes_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_ubytes_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_guid Creates a `ProtoField` for a Globally Unique IDentifier (GUID). */
-/* WSLUA_ARG_Protofield_guid_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_guid_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_guid_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_oid Creates a `ProtoField` for an ASN.1 Organizational IDentified (OID). */
-/* WSLUA_ARG_Protofield_oid_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_oid_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_oid_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_rel_oid Creates a `ProtoField` for an ASN.1 Relative-OID. */
-/* WSLUA_ARG_Protofield_rel_oid_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_rel_oid_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_rel_oid_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_systemid Creates a `ProtoField` for an OSI System ID. */
-/* WSLUA_ARG_Protofield_systemid_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_systemid_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_systemid_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-/* _WSLUA_CONSTRUCTOR_ ProtoField_eui64 Creates a `ProtoField` for an EUI64. */
-/* WSLUA_ARG_Protofield_eui64_ABBR Abbreviated name of the field (the string used in filters). */
-/* WSLUA_OPTARG_Protofield_eui64_NAME Actual name of the field (the string that appears in the tree). */
-/* WSLUA_OPTARG_Protofield_eui64_DESC Description of the field. */
-/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
-
-PROTOFIELD_OTHER(none,FT_NONE)
-PROTOFIELD_OTHER(ipv4,FT_IPv4)
-PROTOFIELD_OTHER(ipv6,FT_IPv6)
-PROTOFIELD_OTHER(ipx,FT_IPXNET)
-PROTOFIELD_OTHER(ether,FT_ETHER)
-PROTOFIELD_OTHER(float,FT_FLOAT)
-PROTOFIELD_OTHER(double,FT_DOUBLE)
-PROTOFIELD_OTHER(relative_time,FT_RELATIVE_TIME)
-PROTOFIELD_OTHER(string,FT_STRING)
-PROTOFIELD_OTHER(stringz,FT_STRINGZ)
-PROTOFIELD_OTHER(bytes,FT_BYTES)
-PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
-PROTOFIELD_OTHER(guid,FT_GUID)
-PROTOFIELD_OTHER(oid,FT_OID)
-PROTOFIELD_OTHER(rel_oid,FT_REL_OID)
-PROTOFIELD_OTHER(systemid,FT_SYSTEM_ID)
-PROTOFIELD_OTHER(eui64,FT_EUI64)
-
-WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) {
- /* Returns a string with info about a protofield (for debugging purposes). */
- ProtoField f = checkProtoField(L,1);
- gchar* s = g_strdup_printf("ProtoField(%i): %s %s %s %s %p %.8x %s",
- f->hfid,f->name,f->abbrev,
- ftenum_to_string(f->type),
- base_to_string(f->base),
- f->vs,f->mask,f->blob);
- lua_pushstring(L,s);
- g_free(s);
- return 1;
-}
-
-static int ProtoField__gc(lua_State* L) {
- ProtoField f = toProtoField(L,1);
-
- /*
- * A garbage collector for ProtoFields makes little sense.
- * Even if This cannot be used anymore because it has gone out of scope,
- * we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
- * if it actualy belongs to one we need to preserve it as it is pointed by
- * a field array that may be registered afterwards causing a crash or memory corruption.
- */
-
- if (!f) {
- luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
- /* g_assert() ?? */
- } else if (f->hfid == -2) {
- g_free(f->name);
- g_free(f->abbrev);
- g_free(f->blob);
- g_free(f);
- }
-
- return 0;
-}
-
-WSLUA_METHODS ProtoField_methods[] = {
- WSLUA_CLASS_FNREG(ProtoField,new),
- WSLUA_CLASS_FNREG(ProtoField,none),
- WSLUA_CLASS_FNREG(ProtoField,uint8),
- WSLUA_CLASS_FNREG(ProtoField,uint16),
- WSLUA_CLASS_FNREG(ProtoField,uint24),
- WSLUA_CLASS_FNREG(ProtoField,uint32),
- WSLUA_CLASS_FNREG(ProtoField,uint64),
- WSLUA_CLASS_FNREG(ProtoField,int8),
- WSLUA_CLASS_FNREG(ProtoField,int16),
- WSLUA_CLASS_FNREG(ProtoField,int24),
- WSLUA_CLASS_FNREG(ProtoField,int32),
- WSLUA_CLASS_FNREG(ProtoField,int64),
- WSLUA_CLASS_FNREG(ProtoField,framenum),
- WSLUA_CLASS_FNREG(ProtoField,ipv4),
- WSLUA_CLASS_FNREG(ProtoField,ipv6),
- WSLUA_CLASS_FNREG(ProtoField,ipx),
- WSLUA_CLASS_FNREG(ProtoField,ether),
- WSLUA_CLASS_FNREG(ProtoField,bool),
- WSLUA_CLASS_FNREG(ProtoField,float),
- WSLUA_CLASS_FNREG(ProtoField,double),
- WSLUA_CLASS_FNREG(ProtoField,absolute_time),
- WSLUA_CLASS_FNREG(ProtoField,relative_time),
- WSLUA_CLASS_FNREG(ProtoField,string),
- WSLUA_CLASS_FNREG(ProtoField,stringz),
- WSLUA_CLASS_FNREG(ProtoField,bytes),
- WSLUA_CLASS_FNREG(ProtoField,ubytes),
- WSLUA_CLASS_FNREG(ProtoField,guid),
- WSLUA_CLASS_FNREG(ProtoField,oid),
- WSLUA_CLASS_FNREG(ProtoField,rel_oid),
- WSLUA_CLASS_FNREG(ProtoField,systemid),
- WSLUA_CLASS_FNREG(ProtoField,eui64),
- { NULL, NULL }
-};
-
-WSLUA_META ProtoField_meta[] = {
- WSLUA_CLASS_MTREG(ProtoField,tostring),
- { NULL, NULL }
-};
-
-int ProtoField_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(ProtoField);
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(ProtoExpert,FAIL_ON_NULL("null ProtoExpert"),NOP);
- /* A Protocol expert info field, to be used when adding items to the dissection tree.
-
- @since 1.11.3
- */
-
-WSLUA_CONSTRUCTOR ProtoExpert_new(lua_State* L) {
- /* Creates a new `ProtoExpert` object to be used for a protocol's expert information notices.
-
- @since 1.11.3
- */
-#define WSLUA_ARG_ProtoExpert_new_ABBR 1 /* Filter name of the expert info field (the string that
- is used in filters). */
-#define WSLUA_ARG_ProtoExpert_new_TEXT 2 /* The default text of the expert field. */
-#define WSLUA_ARG_ProtoExpert_new_GROUP 3 /* Expert group type: one of: `expert.group.CHECKSUM`,
- `expert.group.SEQUENCE`, `expert.group.RESPONSE_CODE`,
- `expert.group.REQUEST_CODE`, `expert.group.UNDECODED`,
- `expert.group.REASSEMBLE`, `expert.group.MALFORMED`,
- `expert.group.DEBUG`, `expert.group.PROTOCOL`,
- `expert.group.SECURITY`, or `expert.group.COMMENTS_GROUP`. */
-#define WSLUA_ARG_ProtoExpert_new_SEVERITY 4 /* Expert severity type: one of:
- `expert.severity.COMMENT`, `expert.severity.CHAT`,
- `expert.severity.NOTE`, `expert.severity.WARN`,
- or `expert.severity.ERROR`. */
-
- ProtoExpert pe = NULL;
- const gchar* abbr = wslua_checkstring_only(L,WSLUA_ARG_ProtoExpert_new_ABBR);
- const gchar* text = wslua_checkstring_only(L,WSLUA_ARG_ProtoExpert_new_TEXT);
- int group = (int)luaL_checkinteger(L, WSLUA_ARG_ProtoExpert_new_GROUP);
- int severity = (int)luaL_checkinteger(L, WSLUA_ARG_ProtoExpert_new_SEVERITY);
-
- pe = g_new(wslua_expert_field_t,1);
-
- pe->ids.ei = EI_INIT_EI;
- pe->ids.hf = EI_INIT_HF;
- pe->abbrev = g_strdup(abbr);
- pe->text = g_strdup(text);
- pe->group = group;
- pe->severity = severity;
-
- pushProtoExpert(L,pe);
-
- WSLUA_RETURN(1); /* The newly created `ProtoExpert` object. */
-}
-
-WSLUA_METAMETHOD ProtoExpert__tostring(lua_State* L) {
- /* Returns a string with debugging information about a `ProtoExpert` object.
-
- @since 1.11.3
- */
- ProtoExpert pe = toProtoExpert(L,1);
-
- if (!pe) {
- lua_pushstring(L,"ProtoExpert pointer is NULL!");
- } else {
- lua_pushfstring(L, "ProtoExpert: ei=%d, hf=%d, abbr=%s, text=%s, group=%d, severity=%d",
- pe->ids.ei, pe->ids.hf, pe->abbrev, pe->text, pe->group, pe->severity);
- }
- return 1;
-}
-
-static int ProtoExpert__gc(lua_State* L) {
- ProtoExpert pe = toProtoExpert(L,1);
-
- /*
- * A garbage collector for ProtoExpert makes little sense.
- * Even if this cannot be used anymore because it has gone out of scope,
- * we can destroy the ProtoExpert only if it is not part of a registered Proto,
- * if it actually belongs to one we need to preserve it as it is pointed by
- * a expert code causing a crash or memory corruption.
- */
-
- if (pe) {
- luaL_argerror(L,1,"BUG: ProtoExpert_gc called for something not ProtoExpert");
- /* g_assert() ?? */
+ g_free(fs);
}
-
- return 0;
-}
-
-WSLUA_METHODS ProtoExpert_methods[] = {
- WSLUA_CLASS_FNREG(ProtoExpert,new),
- { NULL, NULL }
-};
-
-WSLUA_META ProtoExpert_meta[] = {
- WSLUA_CLASS_MTREG(ProtoExpert,tostring),
- { NULL, NULL }
-};
-
-int ProtoExpert_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(ProtoExpert);
- return 0;
}
@@ -1944,6 +514,8 @@ int Proto_register(lua_State* L) {
WSLUA_REGISTER_CLASS(Proto);
WSLUA_REGISTER_ATTRIBUTES(Proto);
+ outstanding_FuncSavers = g_ptr_array_new();
+
lua_newtable(L);
protocols_table_ref = luaL_ref(L, LUA_REGISTRYINDEX);
@@ -2071,30 +643,6 @@ int Proto_commit(lua_State* L) {
return 0;
}
-typedef struct _func_saver {
- lua_State* state;
- int get_len_ref;
- int dissect_ref;
-} func_saver_t;
-
-static GPtrArray* outstanding_FuncSavers = NULL;
-
-void clear_outstanding_FuncSavers(void) {
- while (outstanding_FuncSavers->len) {
- func_saver_t* fs = (func_saver_t*)g_ptr_array_remove_index_fast(outstanding_FuncSavers,0);
- if (fs->state) {
- lua_State* L = fs->state;
- if (fs->get_len_ref != LUA_NOREF) {
- luaL_unref(L, LUA_REGISTRYINDEX, fs->get_len_ref);
- }
- if (fs->dissect_ref != LUA_NOREF) {
- luaL_unref(L, LUA_REGISTRYINDEX, fs->dissect_ref);
- }
- }
- g_free(fs);
- }
-}
-
static guint
wslua_dissect_tcp_get_pdu_len(packet_info *pinfo, tvbuff_t *tvb,
int offset, void *data _U_)
@@ -2228,6 +776,8 @@ WSLUA_FUNCTION wslua_dissect_tcp_pdus(lua_State* L) {
fs->dissect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
fs->get_len_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ /* save the passed-in function refs, so Lua's garbage collector won't
+ destroy them before they get invoked */
g_ptr_array_add(outstanding_FuncSavers, fs);
tcp_dissect_pdus(tvb->ws_tvb, lua_pinfo, ti->tree, proto_desegment,
@@ -2240,646 +790,6 @@ WSLUA_FUNCTION wslua_dissect_tcp_pdus(lua_State* L) {
}
-WSLUA_CLASS_DEFINE(Dissector,NOP,NOP);
-/*
- A refererence to a dissector, used to call a dissector against a packet or a part of it.
- */
-
-WSLUA_CONSTRUCTOR Dissector_get (lua_State *L) {
- /* Obtains a dissector reference by name. */
-#define WSLUA_ARG_Dissector_get_NAME 1 /* The name of the dissector. */
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_Dissector_get_NAME);
- Dissector d;
-
- if ((d = find_dissector(name))) {
- pushDissector(L, d);
- WSLUA_RETURN(1); /* The Dissector reference. */
- }
-
- WSLUA_ARG_ERROR(Dissector_get,NAME,"No such dissector");
- return 0;
-}
-
-/* Allow dissector key names to be sorted alphabetically. */
-static gint
-compare_dissector_key_name(gconstpointer dissector_a, gconstpointer dissector_b)
-{
- return strcmp((const char*)dissector_a, (const char*)dissector_b);
-}
-
-WSLUA_CONSTRUCTOR Dissector_list (lua_State *L) {
- /* Gets a Lua array table of all registered Dissector names.
-
- Note: this is an expensive operation, and should only be used for troubleshooting.
-
- @since 1.11.3
- */
- GList* list = get_dissector_names();
- GList* elist = NULL;
- int i = 1;
-
- if (!list) return luaL_error(L,"Cannot retrieve Dissector name list");
-
- list = g_list_sort(list, (GCompareFunc)compare_dissector_key_name);
- elist = g_list_first(list);
-
- lua_newtable(L);
- for (i=1; elist; i++, elist = g_list_next(elist)) {
- lua_pushstring(L,(const char *) elist->data);
- lua_rawseti(L,1,i);
- }
-
- g_list_free(list);
- WSLUA_RETURN(1); /* The array table of registered dissector names. */
-}
-
-WSLUA_METHOD Dissector_call(lua_State* L) {
- /* Calls a dissector against a given packet (or part of it). */
-#define WSLUA_ARG_Dissector_call_TVB 2 /* The buffer to dissect. */
-#define WSLUA_ARG_Dissector_call_PINFO 3 /* The packet info. */
-#define WSLUA_ARG_Dissector_call_TREE 4 /* The tree on which to add the protocol items. */
-
- Dissector volatile d = checkDissector(L,1);
- Tvb tvb = checkTvb(L,WSLUA_ARG_Dissector_call_TVB);
- Pinfo pinfo = checkPinfo(L,WSLUA_ARG_Dissector_call_PINFO);
- TreeItem ti = checkTreeItem(L,WSLUA_ARG_Dissector_call_TREE);
- const char *volatile error = NULL;
- int len = 0;
-
- if (! ( d && tvb && pinfo) ) return 0;
-
- TRY {
- len = call_dissector(d, tvb->ws_tvb, pinfo->ws_pinfo, ti->tree);
- /* XXX Are we sure about this??? is this the right/only thing to catch */
- } CATCH_NONFATAL_ERRORS {
- show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
- error = "Malformed frame";
- } ENDTRY;
-
- if (error) { WSLUA_ERROR(Dissector_call,error); }
-
- lua_pushnumber(L,(lua_Number)len);
- WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
-}
-
-WSLUA_METAMETHOD Dissector__call(lua_State* L) {
- /* Calls a dissector against a given packet (or part of it). */
-#define WSLUA_ARG_Dissector__call_TVB 2 /* The buffer to dissect. */
-#define WSLUA_ARG_Dissector__call_PINFO 3 /* The packet info. */
-#define WSLUA_ARG_Dissector__call_TREE 4 /* The tree on which to add the protocol items. */
- return Dissector_call(L);
-}
-
-WSLUA_METAMETHOD Dissector__tostring(lua_State* L) {
- /* Gets the Dissector's protocol short name. */
- Dissector d = checkDissector(L,1);
- if (!d) return 0;
- lua_pushstring(L,dissector_handle_get_short_name(d));
- WSLUA_RETURN(1); /* A string of the protocol's short name. */
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int Dissector__gc(lua_State* L _U_) {
- /* do NOT free Dissector */
- return 0;
-}
-
-WSLUA_METHODS Dissector_methods[] = {
- WSLUA_CLASS_FNREG(Dissector,get),
- WSLUA_CLASS_FNREG(Dissector,call),
- WSLUA_CLASS_FNREG(Dissector,list),
- { NULL, NULL }
-};
-
-WSLUA_META Dissector_meta[] = {
- WSLUA_CLASS_MTREG(Dissector,tostring),
- WSLUA_CLASS_MTREG(Dissector,call),
- { NULL, NULL }
-};
-
-int Dissector_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(Dissector);
- outstanding_FuncSavers = g_ptr_array_new();
- return 0;
-}
-
-WSLUA_CLASS_DEFINE(DissectorTable,NOP,NOP);
-/*
- A table of subdissectors of a particular protocol (e.g. TCP subdissectors like http, smtp,
- sip are added to table "tcp.port").
-
- Useful to add more dissectors to a table so that they appear in the Decode As... dialog.
- */
-
-WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
- /* Creates a new DissectorTable for your dissector's use. */
-#define WSLUA_ARG_DissectorTable_new_TABLENAME 1 /* The short name of the table. */
-#define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the User Interface
- (defaults to the name given). */
-#define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* Either `ftypes.UINT8`, `ftypes.UINT16`,
- `ftypes.UINT24`, `ftypes.UINT32`, or
- `ftypes.STRING`
- (defaults to `ftypes.UINT32`). */
-#define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* Either `base.NONE`, `base.DEC`, `base.HEX`,
- `base.OCT`, `base.DEC_HEX` or `base.HEX_DEC`
- (defaults to `base.DEC`). */
- const gchar* name = (const gchar*)luaL_checkstring(L,WSLUA_ARG_DissectorTable_new_TABLENAME);
- const gchar* ui_name = (const gchar*)luaL_optstring(L,WSLUA_OPTARG_DissectorTable_new_UINAME,name);
- enum ftenum type = (enum ftenum)luaL_optinteger(L,WSLUA_OPTARG_DissectorTable_new_TYPE,FT_UINT32);
- unsigned base = (unsigned)luaL_optinteger(L,WSLUA_OPTARG_DissectorTable_new_BASE,BASE_DEC);
-
- switch(type) {
- case FT_STRING:
- base = BASE_NONE;
- /* fallthrough */
- case FT_UINT8:
- case FT_UINT16:
- case FT_UINT24:
- case FT_UINT32:
- {
- DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
-
- name = g_strdup(name);
- ui_name = g_strdup(ui_name);
-
- dt->table = register_dissector_table(name, ui_name, type, base);
- dt->name = name;
- pushDissectorTable(L, dt);
- }
- WSLUA_RETURN(1); /* The newly created DissectorTable. */
- default:
- WSLUA_OPTARG_ERROR(DissectorTable_new,TYPE,"must be ftypes.UINT{8,16,24,32} or ftypes.STRING");
- break;
- }
- return 0;
-}
-
-/* this struct is used for passing ourselves user_data through dissector_all_tables_foreach_table(). */
-typedef struct dissector_tables_foreach_table_info {
- int num;
- lua_State *L;
-} dissector_tables_foreach_table_info_t;
-
-/* this is the DATFunc_table function used for dissector_all_tables_foreach_table()
- so we can get all dissector_table names. This pushes the name into a table at stack index 1 */
-static void
-dissector_tables_list_func(const gchar *table_name, const gchar *ui_name _U_, gpointer user_data) {
- dissector_tables_foreach_table_info_t *data = (dissector_tables_foreach_table_info_t*) user_data;
- lua_pushstring(data->L, table_name);
- lua_rawseti(data->L, 1, data->num);
- data->num = data->num + 1;
-}
-
-WSLUA_CONSTRUCTOR DissectorTable_list (lua_State *L) {
- /* Gets a Lua array table of all DissectorTable names - i.e., the string names you can
- use for the first argument to DissectorTable.get().
-
- Note: this is an expensive operation, and should only be used for troubleshooting.
-
- @since 1.11.3
- */
- dissector_tables_foreach_table_info_t data = { 1, L };
-
- lua_newtable(L);
-
- dissector_all_tables_foreach_table(dissector_tables_list_func, (gpointer)&data,
- (GCompareFunc)compare_dissector_key_name);
-
- WSLUA_RETURN(1); /* The array table of registered DissectorTable names. */
-}
-
-/* this is the DATFunc_heur_table function used for dissector_all_heur_tables_foreach_table()
- so we can get all heuristic dissector list names. This pushes the name into a table at stack index 1 */
-static void
-heur_dissector_tables_list_func(const gchar *table_name, heur_dissector_list_t *table _U_, gpointer user_data) {
- dissector_tables_foreach_table_info_t *data = (dissector_tables_foreach_table_info_t*) user_data;
- lua_pushstring(data->L, table_name);
- lua_rawseti(data->L, 1, data->num);
- data->num = data->num + 1;
-}
-
-WSLUA_CONSTRUCTOR DissectorTable_heuristic_list (lua_State *L) {
- /* Gets a Lua array table of all heuristic list names - i.e., the string names you can
- use for the first argument in Proto:register_heuristic().
-
- Note: this is an expensive operation, and should only be used for troubleshooting.
-
- @since 1.11.3
- */
- dissector_tables_foreach_table_info_t data = { 1, L };
-
- lua_newtable(L);
-
- dissector_all_heur_tables_foreach_table(heur_dissector_tables_list_func, (gpointer)&data, NULL);
-
- WSLUA_RETURN(1); /* The array table of registered heuristic list names */
-}
-
-WSLUA_CONSTRUCTOR DissectorTable_get (lua_State *L) {
- /*
- Obtain a reference to an existing dissector table.
- */
-#define WSLUA_ARG_DissectorTable_get_TABLENAME 1 /* The short name of the table. */
- const gchar* name = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_TABLENAME);
- dissector_table_t table = find_dissector_table(name);
-
- if (table) {
- DissectorTable dt = (DissectorTable)g_malloc(sizeof(struct _wslua_distbl_t));
- dt->table = table;
- dt->name = g_strdup(name);
-
- pushDissectorTable(L, dt);
-
- WSLUA_RETURN(1); /* The DissectorTable. */
- }
-
- WSLUA_ARG_ERROR(DissectorTable_get,TABLENAME,"no such dissector_table");
- return 0;
-}
-
-WSLUA_METHOD DissectorTable_add (lua_State *L) {
- /*
- Add a `Proto` with a dissector function, or a `Dissector` object, to the dissector table.
- */
-#define WSLUA_ARG_DissectorTable_add_PATTERN 2 /* The pattern to match (either an integer, a
- integer range or a string depending on the table's type). */
-#define WSLUA_ARG_DissectorTable_add_DISSECTOR 3 /* The dissector to add (either a `Proto` or a `Dissector`). */
-
- DissectorTable dt = checkDissectorTable(L,1);
- ftenum_t type;
- Dissector handle;
-
- if (!dt) return 0;
-
- if( isProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
- Proto p;
- p = checkProto(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
- handle = p->handle;
-
- if (! handle) {
- WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"a Protocol that does not have a dissector cannot be added to a table");
- return 0;
- }
-
- } else if ( isDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR) ) {
- handle = toDissector(L,WSLUA_ARG_DissectorTable_add_DISSECTOR);
- } else {
- WSLUA_ARG_ERROR(DissectorTable_add,DISSECTOR,"must be either Proto or Dissector");
- return 0;
- }
-
- type = get_dissector_table_selector_type(dt->name);
-
- if (type == FT_STRING) {
- gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
- dissector_add_string(dt->name, pattern,handle);
- g_free (pattern);
- } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
- if (lua_isnumber(L, WSLUA_ARG_DissectorTable_add_PATTERN)) {
- int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_add_PATTERN);
- dissector_add_uint(dt->name, port, handle);
- } else {
- /* Not a number, try as range */
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN);
- range_t *range = NULL;
- if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR) {
- dissector_add_uint_range(dt->name, range, handle);
- } else {
- g_free (range);
- WSLUA_ARG_ERROR(DissectorTable_add,PATTERN,"invalid integer or range");
- return 0;
- }
- g_free (range);
- }
- } else {
- luaL_error(L,"Strange type %d for a DissectorTable",type);
- }
-
- return 0;
-}
-
-WSLUA_METHOD DissectorTable_set (lua_State *L) {
- /*
- Remove existing dissectors from a table and add a new or a range of new dissectors.
-
- @since 1.11.3
- */
-#define WSLUA_ARG_DissectorTable_set_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
-#define WSLUA_ARG_DissectorTable_set_DISSECTOR 3 /* The dissector to add (either a `Proto` or a `Dissector`). */
-
- DissectorTable dt = checkDissectorTable(L,1);
- ftenum_t type;
- Dissector handle;
-
- if (!dt) return 0;
-
- if( isProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
- Proto p;
- p = checkProto(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
- handle = p->handle;
-
- if (! handle) {
- WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"a Protocol that does not have a dissector cannot be set to a table");
- return 0;
- }
-
- } else if ( isDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR) ) {
- handle = toDissector(L,WSLUA_ARG_DissectorTable_set_DISSECTOR);
- } else {
- WSLUA_ARG_ERROR(DissectorTable_set,DISSECTOR,"must be either Proto or Dissector");
- return 0;
- }
-
- type = get_dissector_table_selector_type(dt->name);
-
- if (type == FT_STRING) {
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
- dissector_delete_all(dt->name, handle);
- dissector_add_string(dt->name, pattern,handle);
- } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
- if (lua_isnumber(L, WSLUA_ARG_DissectorTable_set_PATTERN)) {
- int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_set_PATTERN);
- dissector_delete_all(dt->name, handle);
- dissector_add_uint(dt->name, port, handle);
- } else {
- /* Not a number, try as range */
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
- range_t *range = NULL;
- if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR) {
- dissector_delete_all(dt->name, handle);
- dissector_add_uint_range(dt->name, range, handle);
- } else {
- g_free (range);
- WSLUA_ARG_ERROR(DissectorTable_set,PATTERN,"invalid integer or range");
- return 0;
- }
- g_free (range);
- }
- } else {
- luaL_error(L,"Strange type %d for a DissectorTable",type);
- }
-
- return 0;
-}
-
-WSLUA_METHOD DissectorTable_remove (lua_State *L) {
- /*
- Remove a dissector or a range of dissectors from a table
- */
-#define WSLUA_ARG_DissectorTable_remove_PATTERN 2 /* The pattern to match (either an integer, a integer range or a string depending on the table's type). */
-#define WSLUA_ARG_DissectorTable_remove_DISSECTOR 3 /* The dissector to remove (either a `Proto` or a `Dissector`). */
- DissectorTable dt = checkDissectorTable(L,1);
- ftenum_t type;
- Dissector handle;
-
- if (!dt) return 0;
-
- if( isProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
- Proto p;
- p = checkProto(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
- handle = p->handle;
-
- } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR) ) {
- handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_DISSECTOR);
- } else {
- WSLUA_ARG_ERROR(DissectorTable_remove,DISSECTOR,"must be either Proto or Dissector");
- return 0;
- }
-
- type = get_dissector_table_selector_type(dt->name);
-
- if (type == FT_STRING) {
- gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
- dissector_delete_string(dt->name, pattern,handle);
- g_free (pattern);
- } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
- if (lua_isnumber(L, WSLUA_ARG_DissectorTable_remove_PATTERN)) {
- int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_remove_PATTERN);
- dissector_delete_uint(dt->name, port, handle);
- } else {
- /* Not a number, try as range */
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN);
- range_t *range = NULL;
- if (range_convert_str(&range, pattern, G_MAXUINT32) == CVT_NO_ERROR)
- dissector_delete_uint_range(dt->name, range, handle);
- else {
- g_free (range);
- WSLUA_ARG_ERROR(DissectorTable_remove,PATTERN,"invalid integer or range");
- return 0;
- }
- g_free (range);
- }
- }
-
- return 0;
-}
-
-WSLUA_METHOD DissectorTable_remove_all (lua_State *L) {
- /*
- Remove all dissectors from a table.
-
- @since 1.11.3
- */
-#define WSLUA_ARG_DissectorTable_remove_all_DISSECTOR 2 /* The dissector to remove (either a `Proto` or a `Dissector`). */
- DissectorTable dt = checkDissectorTable(L,1);
- Dissector handle;
-
- if (!dt) return 0;
-
- if( isProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
- Proto p;
- p = checkProto(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
- handle = p->handle;
-
- } else if ( isDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR) ) {
- handle = toDissector(L,WSLUA_ARG_DissectorTable_remove_all_DISSECTOR);
- } else {
- WSLUA_ARG_ERROR(DissectorTable_remove_all,DISSECTOR,"must be either Proto or Dissector");
- return 0;
- }
-
- dissector_delete_all (dt->name, handle);
-
- return 0;
-}
-
-WSLUA_METHOD DissectorTable_try (lua_State *L) {
- /*
- Try to call a dissector from a table
- */
-#define WSLUA_ARG_DissectorTable_try_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
-#define WSLUA_ARG_DissectorTable_try_TVB 3 /* The buffer to dissect. */
-#define WSLUA_ARG_DissectorTable_try_PINFO 4 /* The packet info. */
-#define WSLUA_ARG_DissectorTable_try_TREE 5 /* The tree on which to add the protocol items. */
- DissectorTable volatile dt = checkDissectorTable(L,1);
- Tvb tvb = checkTvb(L,WSLUA_ARG_DissectorTable_try_TVB);
- Pinfo pinfo = checkPinfo(L,WSLUA_ARG_DissectorTable_try_PINFO);
- TreeItem ti = checkTreeItem(L,WSLUA_ARG_DissectorTable_try_TREE);
- ftenum_t type;
- gboolean handled = FALSE;
- const gchar *volatile error = NULL;
- int len = 0;
-
- if (! (dt && tvb && tvb->ws_tvb && pinfo && ti) ) return 0;
-
- type = get_dissector_table_selector_type(dt->name);
-
- TRY {
-
- if (type == FT_STRING) {
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
-
- len = dissector_try_string(dt->table,pattern,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree, NULL);
- if (len > 0) {
- handled = TRUE;
- }
- } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
- int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_try_PATTERN);
-
- len = dissector_try_uint(dt->table,port,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
- if (len > 0) {
- handled = TRUE;
- }
- } else {
- luaL_error(L,"No such type of dissector_table");
- }
-
- if (!handled) {
- len = call_dissector(lua_data_handle,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
- }
- /* XXX Are we sure about this??? is this the right/only thing to catch */
- } CATCH_NONFATAL_ERRORS {
- show_exception(tvb->ws_tvb, pinfo->ws_pinfo, ti->tree, EXCEPT_CODE, GET_MESSAGE);
- error = "Malformed frame";
- } ENDTRY;
-
- if (error) { WSLUA_ERROR(DissectorTable_try,error); }
-
- lua_pushnumber(L,(lua_Number)len);
- WSLUA_RETURN(1); /* Number of bytes dissected. Note that some dissectors always return number of bytes in incoming buffer, so be aware. */
-}
-
-WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) {
- /*
- Try to obtain a dissector from a table.
- */
-#define WSLUA_ARG_DissectorTable_get_dissector_PATTERN 2 /* The pattern to be matched (either an integer or a string depending on the table's type). */
-
- DissectorTable dt = checkDissectorTable(L,1);
- ftenum_t type;
- dissector_handle_t handle = lua_data_handle;
-
- if (!dt) return 0;
-
- type = get_dissector_table_selector_type(dt->name);
-
- if (type == FT_STRING) {
- const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
- handle = dissector_get_string_handle(dt->table,pattern);
- } else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
- int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
- handle = dissector_get_uint_handle(dt->table,port);
- }
-
- if (handle) {
- pushDissector(L,handle);
- WSLUA_RETURN(1); /* The dissector handle if found. */
- } else {
- lua_pushnil(L);
- WSLUA_RETURN(1); /* nil if not found. */
- }
-}
-
-WSLUA_METHOD DissectorTable_add_for_decode_as (lua_State *L) {
- /*
- Add the given `Proto` to the "Decode as..." list for this DissectorTable.
- The passed-in `Proto` object's `dissector()` function is used for dissecting.
-
- @since 1.99.1
- */
-#define WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO 2 /* The `Proto` to add. */
- DissectorTable dt = checkDissectorTable(L,1);
- Proto proto = checkProto(L, WSLUA_ARG_DissectorTable_add_for_decode_as_PROTO);
- dissector_handle_t handle = NULL;
-
- if (! proto->handle) {
- proto->handle = new_register_dissector(proto->loname, dissect_lua, proto->hfid);
- }
-
- handle = proto->handle;
-
- dissector_add_for_decode_as(dt->name, handle);
-
- return 0;
-}
-
-/* XXX It would be nice to iterate and print which dissectors it has */
-WSLUA_METAMETHOD DissectorTable__tostring(lua_State* L) {
- /* Gets some debug information about the DissectorTable. */
- DissectorTable dt = checkDissectorTable(L,1);
- GString* s;
- ftenum_t type;
-
- if (!dt) return 0;
-
- type = get_dissector_table_selector_type(dt->name);
- s = g_string_new("DissectorTable ");
-
- switch(type) {
- case FT_STRING:
- {
- g_string_append_printf(s,"%s String:\n",dt->name);
- break;
- }
- case FT_UINT8:
- case FT_UINT16:
- case FT_UINT24:
- case FT_UINT32:
- {
- int base = get_dissector_table_param(dt->name);
- g_string_append_printf(s,"%s Integer(%i):\n",dt->name,base);
- break;
- }
- default:
- luaL_error(L,"Strange table type");
- }
-
- lua_pushstring(L,s->str);
- g_string_free(s,TRUE);
- WSLUA_RETURN(1); /* A string of debug information about the DissectorTable. */
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int DissectorTable__gc(lua_State* L _U_) {
- /* do NOT free DissectorTable */
- return 0;
-}
-
-WSLUA_METHODS DissectorTable_methods[] = {
- WSLUA_CLASS_FNREG(DissectorTable,new),
- WSLUA_CLASS_FNREG(DissectorTable,get),
- WSLUA_CLASS_FNREG(DissectorTable,list),
- WSLUA_CLASS_FNREG(DissectorTable,heuristic_list),
- WSLUA_CLASS_FNREG(DissectorTable,add),
- WSLUA_CLASS_FNREG(DissectorTable,set),
- WSLUA_CLASS_FNREG(DissectorTable,remove),
- WSLUA_CLASS_FNREG(DissectorTable,remove_all),
- WSLUA_CLASS_FNREG(DissectorTable,try),
- WSLUA_CLASS_FNREG(DissectorTable,get_dissector),
- WSLUA_CLASS_FNREG(DissectorTable,add_for_decode_as),
- { NULL, NULL }
-};
-
-WSLUA_META DissectorTable_meta[] = {
- WSLUA_CLASS_MTREG(DissectorTable,tostring),
- { NULL, NULL }
-};
-
-int DissectorTable_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(DissectorTable);
- return 0;
-}
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/wslua/wslua_proto_expert.c b/epan/wslua/wslua_proto_expert.c
new file mode 100644
index 0000000000..f1a36c13e3
--- /dev/null
+++ b/epan/wslua/wslua_proto_expert.c
@@ -0,0 +1,145 @@
+/*
+ * wslua_proto_expert.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+
+/* WSLUA_CONTINUE_MODULE Proto */
+
+
+WSLUA_CLASS_DEFINE(ProtoExpert,FAIL_ON_NULL("null ProtoExpert"),NOP);
+ /* A Protocol expert info field, to be used when adding items to the dissection tree.
+
+ @since 1.11.3
+ */
+
+WSLUA_CONSTRUCTOR ProtoExpert_new(lua_State* L) {
+ /* Creates a new `ProtoExpert` object to be used for a protocol's expert information notices.
+
+ @since 1.11.3
+ */
+#define WSLUA_ARG_ProtoExpert_new_ABBR 1 /* Filter name of the expert info field (the string that
+ is used in filters). */
+#define WSLUA_ARG_ProtoExpert_new_TEXT 2 /* The default text of the expert field. */
+#define WSLUA_ARG_ProtoExpert_new_GROUP 3 /* Expert group type: one of: `expert.group.CHECKSUM`,
+ `expert.group.SEQUENCE`, `expert.group.RESPONSE_CODE`,
+ `expert.group.REQUEST_CODE`, `expert.group.UNDECODED`,
+ `expert.group.REASSEMBLE`, `expert.group.MALFORMED`,
+ `expert.group.DEBUG`, `expert.group.PROTOCOL`,
+ `expert.group.SECURITY`, or `expert.group.COMMENTS_GROUP`. */
+#define WSLUA_ARG_ProtoExpert_new_SEVERITY 4 /* Expert severity type: one of:
+ `expert.severity.COMMENT`, `expert.severity.CHAT`,
+ `expert.severity.NOTE`, `expert.severity.WARN`,
+ or `expert.severity.ERROR`. */
+
+ ProtoExpert pe = NULL;
+ const gchar* abbr = wslua_checkstring_only(L,WSLUA_ARG_ProtoExpert_new_ABBR);
+ const gchar* text = wslua_checkstring_only(L,WSLUA_ARG_ProtoExpert_new_TEXT);
+ int group = (int)luaL_checkinteger(L, WSLUA_ARG_ProtoExpert_new_GROUP);
+ int severity = (int)luaL_checkinteger(L, WSLUA_ARG_ProtoExpert_new_SEVERITY);
+
+ pe = g_new(wslua_expert_field_t,1);
+
+ pe->ids.ei = EI_INIT_EI;
+ pe->ids.hf = EI_INIT_HF;
+ pe->abbrev = g_strdup(abbr);
+ pe->text = g_strdup(text);
+ pe->group = group;
+ pe->severity = severity;
+
+ pushProtoExpert(L,pe);
+
+ WSLUA_RETURN(1); /* The newly created `ProtoExpert` object. */
+}
+
+WSLUA_METAMETHOD ProtoExpert__tostring(lua_State* L) {
+ /* Returns a string with debugging information about a `ProtoExpert` object.
+
+ @since 1.11.3
+ */
+ ProtoExpert pe = toProtoExpert(L,1);
+
+ if (!pe) {
+ lua_pushstring(L,"ProtoExpert pointer is NULL!");
+ } else {
+ lua_pushfstring(L, "ProtoExpert: ei=%d, hf=%d, abbr=%s, text=%s, group=%d, severity=%d",
+ pe->ids.ei, pe->ids.hf, pe->abbrev, pe->text, pe->group, pe->severity);
+ }
+ return 1;
+}
+
+static int ProtoExpert__gc(lua_State* L) {
+ ProtoExpert pe = toProtoExpert(L,1);
+
+ /*
+ * A garbage collector for ProtoExpert makes little sense.
+ * Even if this cannot be used anymore because it has gone out of scope,
+ * we can destroy the ProtoExpert only if it is not part of a registered Proto,
+ * if it actually belongs to one we need to preserve it as it is pointed by
+ * a expert code causing a crash or memory corruption.
+ */
+
+ if (pe) {
+ luaL_argerror(L,1,"BUG: ProtoExpert_gc called for something not ProtoExpert");
+ /* g_assert() ?? */
+ }
+
+ return 0;
+}
+
+WSLUA_METHODS ProtoExpert_methods[] = {
+ WSLUA_CLASS_FNREG(ProtoExpert,new),
+ { NULL, NULL }
+};
+
+WSLUA_META ProtoExpert_meta[] = {
+ WSLUA_CLASS_MTREG(ProtoExpert,tostring),
+ { NULL, NULL }
+};
+
+int ProtoExpert_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(ProtoExpert);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_proto_field.c b/epan/wslua/wslua_proto_field.c
new file mode 100644
index 0000000000..bb91b6cbe8
--- /dev/null
+++ b/epan/wslua/wslua_proto_field.c
@@ -0,0 +1,997 @@
+/*
+ * wslua_proto_field.c
+ *
+ * Wireshark's interface to the Lua Programming Language
+ *
+ * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
+ * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "wslua.h"
+
+
+/* WSLUA_CONTINUE_MODULE Proto */
+
+
+WSLUA_CLASS_DEFINE(ProtoField,FAIL_ON_NULL("null ProtoField"),NOP);
+ /* A Protocol field (to be used when adding items to the dissection tree). */
+
+static const wslua_ft_types_t ftenums[] = {
+ {"ftypes.NONE", FT_NONE},
+ {"ftypes.BOOLEAN", FT_BOOLEAN},
+ {"ftypes.UINT8", FT_UINT8},
+ {"ftypes.UINT16", FT_UINT16},
+ {"ftypes.UINT24", FT_UINT24},
+ {"ftypes.UINT32", FT_UINT32},
+ {"ftypes.UINT64", FT_UINT64},
+ {"ftypes.INT8", FT_INT8},
+ {"ftypes.INT16", FT_INT16},
+ {"ftypes.INT24", FT_INT24},
+ {"ftypes.INT32", FT_INT32},
+ {"ftypes.INT64", FT_INT64},
+ {"ftypes.FLOAT", FT_FLOAT},
+ {"ftypes.DOUBLE", FT_DOUBLE},
+ {"ftypes.ABSOLUTE_TIME", FT_ABSOLUTE_TIME},
+ {"ftypes.RELATIVE_TIME", FT_RELATIVE_TIME},
+ {"ftypes.STRING", FT_STRING},
+ {"ftypes.STRINGZ", FT_STRINGZ},
+ {"ftypes.ETHER", FT_ETHER},
+ {"ftypes.BYTES", FT_BYTES},
+ {"ftypes.UINT_BYTES", FT_UINT_BYTES},
+ {"ftypes.IPv4", FT_IPv4},
+ {"ftypes.IPv6", FT_IPv6},
+ {"ftypes.IPXNET", FT_IPXNET},
+ {"ftypes.FRAMENUM", FT_FRAMENUM},
+ {"ftypes.GUID", FT_GUID},
+ {"ftypes.OID", FT_OID},
+ {"ftypes.SYSTEM_ID", FT_SYSTEM_ID},
+ {"ftypes.REL_OID", FT_REL_OID},
+ {"ftypes.EUI64", FT_EUI64},
+ {"ftypes.FCWWN", FT_FCWWN},
+ {NULL, FT_NONE}
+};
+
+static enum ftenum get_ftenum(const gchar* type) {
+ const wslua_ft_types_t* ts;
+ for (ts = ftenums; ts->str; ts++) {
+ if ( g_str_equal(ts->str,type) ) {
+ return ts->id;
+ }
+ }
+ return FT_NONE;
+}
+
+static const gchar* ftenum_to_string(enum ftenum ft) {
+ const wslua_ft_types_t* ts;
+ for (ts = ftenums; ts->str; ts++) {
+ if ( ts->id == ft ) {
+ return ts->str;
+ }
+ }
+ return NULL;
+}
+
+struct field_display_string_t {
+ const gchar* str;
+ unsigned base;
+};
+
+static const struct field_display_string_t base_displays[] = {
+ {"base.NONE", BASE_NONE},
+ {"base.DEC", BASE_DEC},
+ {"base.HEX", BASE_HEX},
+ {"base.OCT", BASE_OCT},
+ {"base.DEC_HEX", BASE_DEC_HEX},
+ {"base.HEX_DEC", BASE_HEX_DEC},
+ /* for FT_BOOLEAN, how wide the parent bitfield is */
+ {"8",8},
+ {"16",16},
+ {"24",24},
+ {"32",32},
+ /* for FT_ABSOLUTE_TIME use values in absolute_time_display_e */
+ {"LOCAL", ABSOLUTE_TIME_LOCAL},
+ {"UTC", ABSOLUTE_TIME_UTC},
+ {"DOY_UTC", ABSOLUTE_TIME_DOY_UTC},
+ {NULL,0}
+};
+
+static const gchar* base_to_string(unsigned base) {
+ const struct field_display_string_t* b;
+ for (b=base_displays;b->str;b++) {
+ if ( base == b->base)
+ return b->str;
+ }
+ return NULL;
+}
+
+static unsigned string_to_base(const gchar* str) {
+ const struct field_display_string_t* b;
+ for (b=base_displays;b->str;b++) {
+ if ( g_str_equal(str,b->str))
+ return b->base;
+ }
+ return BASE_NONE;
+}
+
+static value_string* value_string_from_table(lua_State* L, int idx) {
+ GArray* vs = g_array_new(TRUE,TRUE,sizeof(value_string));
+ value_string* ret;
+
+ if(lua_isnil(L,idx)) {
+ return NULL;
+ } else if (!lua_istable(L,idx)) {
+ luaL_argerror(L,idx,"must be a table");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ lua_pushnil(L);
+
+ while (lua_next(L, idx) != 0) {
+ value_string v = {0,NULL};
+
+ if (! lua_isnumber(L,-2)) {
+ luaL_argerror(L,idx,"All keys of a table used as value_string must be integers");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"All values of a table used as value_string must be strings");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ v.value = wslua_toguint32(L,-2);
+ v.strptr = g_strdup(lua_tostring(L,-1));
+
+ g_array_append_val(vs,v);
+
+ lua_pop(L, 1);
+ }
+
+ ret = (value_string*)(void*)vs->data;
+
+ g_array_free(vs,FALSE);
+
+ return ret;
+}
+
+static val64_string* val64_string_from_table(lua_State* L, int idx) {
+ GArray* vs = g_array_new(TRUE,TRUE,sizeof(val64_string));
+ val64_string* ret;
+
+ if(lua_isnil(L,idx)) {
+ return NULL;
+ } else if (!lua_istable(L,idx)) {
+ luaL_argerror(L,idx,"must be a table");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ lua_pushnil(L);
+
+ while (lua_next(L, idx) != 0) {
+ val64_string v = {0,NULL};
+
+ if (! lua_isnumber(L,-2)) {
+ luaL_argerror(L,idx,"All keys of a table used as value string must be integers");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"All values of a table used as value string must be strings");
+ g_array_free(vs,TRUE);
+ return NULL;
+ }
+
+ v.value = wslua_toguint64(L, -2);
+ v.strptr = g_strdup(lua_tostring(L,-1));
+
+ g_array_append_val(vs,v);
+
+ lua_pop(L, 1);
+ }
+
+ ret = (val64_string*)(void*)vs->data;
+
+ g_array_free(vs,FALSE);
+
+ return ret;
+}
+
+static true_false_string* true_false_string_from_table(lua_State* L, int idx) {
+ GArray* tfs = g_array_new(TRUE,TRUE,sizeof(true_false_string));
+ true_false_string* ret;
+ true_false_string tf = { "True", "False" };
+
+ if (lua_isnil(L,idx)) {
+ return NULL;
+ } else if (!lua_istable(L,idx)) {
+ luaL_argerror(L,idx,"must be a table");
+ g_array_free(tfs,TRUE);
+ return NULL;
+ }
+
+ lua_pushnil(L);
+
+ while (lua_next(L, idx)) {
+
+ if (! lua_isnumber(L,-2)) {
+ luaL_argerror(L,idx,"All keys of a table used as true_false_string must be integers");
+ g_array_free(tfs,TRUE);
+ return NULL;
+ }
+
+ if (! lua_isstring(L,-1)) {
+ luaL_argerror(L,idx,"All values of a table used as true_false_string must be strings");
+ g_array_free(tfs,TRUE);
+ return NULL;
+ }
+
+ /* arrays in LUA start with index number 1 */
+ if (lua_tointeger(L,-2) == 1)
+ tf.true_string = g_strdup(lua_tostring(L,-1));
+
+ if (lua_tointeger(L,-2) == 2)
+ tf.false_string = g_strdup(lua_tostring(L,-1));
+
+ lua_pop(L, 1);
+ }
+
+ g_array_append_val(tfs,tf);
+
+ ret = (true_false_string*)(void*)tfs->data;
+
+ g_array_free(tfs,FALSE);
+
+ return ret;
+}
+
+static const gchar* check_field_name(lua_State* L, const int abbr_idx, const enum ftenum type) {
+ const gchar* abbr = luaL_checkstring(L,abbr_idx);
+ const header_field_info* hfinfo = NULL;
+
+ if (!abbr[0]) {
+ luaL_argerror(L, abbr_idx, "Empty field name abbreviation");
+ return NULL;
+ }
+
+ if (proto_check_field_name(abbr)) {
+ luaL_argerror(L, abbr_idx, "Invalid char in abbrev");
+ return NULL;
+ }
+
+ hfinfo = proto_registrar_get_byname(abbr);
+
+ if (hfinfo && !ftype_similar_types(type, hfinfo->type)) {
+ luaL_argerror(L, abbr_idx, "A field of an incompatible ftype with this abbrev already exists");
+ return NULL;
+ }
+
+ return abbr;
+}
+
+WSLUA_CONSTRUCTOR ProtoField_new(lua_State* L) {
+ /* Creates a new `ProtoField` object to be used for a protocol field. */
+#define WSLUA_ARG_ProtoField_new_NAME 1 /* Actual name of the field (the string that
+ appears in the tree). */
+#define WSLUA_ARG_ProtoField_new_ABBR 2 /* Filter name of the field (the string that
+ is used in filters). */
+#define WSLUA_ARG_ProtoField_new_TYPE 3 /* Field Type: one of: `ftypes.BOOLEAN`, `ftypes.UINT8`,
+ `ftypes.UINT16`, `ftypes.UINT24`, `ftypes.UINT32`, `ftypes.UINT64`, `ftypes.INT8`,
+ `ftypes.INT16`, `ftypes.INT24`, `ftypes.INT32`, `ftypes.INT64`, `ftypes.FLOAT`,
+ `ftypes.DOUBLE` , `ftypes.ABSOLUTE_TIME`, `ftypes.RELATIVE_TIME`, `ftypes.STRING`,
+ `ftypes.STRINGZ`, `ftypes.UINT_STRING`, `ftypes.ETHER`, `ftypes.BYTES`,
+ `ftypes.UINT_BYTES`, `ftypes.IPv4`, `ftypes.IPv6`, `ftypes.IPXNET`, `ftypes.FRAMENUM`,
+ `ftypes.PCRE`, `ftypes.GUID`, `ftypes.OID`, `ftypes.REL_OID`, `ftypes.SYSTEM_ID`,
+ `ftypes.EUI64` or `ftypes.NONE`.
+ */
+#define WSLUA_OPTARG_ProtoField_new_VALUESTRING 4 /* A table containing the text that
+ corresponds to the values. */
+#define WSLUA_OPTARG_ProtoField_new_BASE 5 /* The representation, one of: `base.NONE`, `base.DEC`,
+ `base.HEX`, `base.OCT`, `base.DEC_HEX`, or
+ `base.HEX_DEC`. */
+#define WSLUA_OPTARG_ProtoField_new_MASK 6 /* The bitmask to be used. */
+#define WSLUA_OPTARG_ProtoField_new_DESCR 7 /* The description of the field. */
+
+ ProtoField f;
+ int nargs = lua_gettop(L);
+ const gchar* name = luaL_checkstring(L,WSLUA_ARG_ProtoField_new_NAME);
+ const gchar* abbr = NULL;
+ enum ftenum type;
+ value_string *vs32 = NULL;
+ val64_string *vs64 = NULL;
+ true_false_string *tfs = NULL;
+ unsigned base;
+ guint32 mask = wslua_optguint32(L, WSLUA_OPTARG_ProtoField_new_MASK, 0x0);
+ const gchar *blob = luaL_optstring(L,WSLUA_OPTARG_ProtoField_new_DESCR,NULL);
+
+ if (lua_isnumber(L,WSLUA_ARG_ProtoField_new_TYPE)) {
+ type = (enum ftenum)luaL_checkinteger(L,WSLUA_ARG_ProtoField_new_TYPE);
+ } else {
+ type = get_ftenum(luaL_checkstring(L,WSLUA_ARG_ProtoField_new_TYPE));
+ }
+
+ abbr = check_field_name(L,WSLUA_ARG_ProtoField_new_ABBR,type);
+
+ if (lua_isnumber(L, WSLUA_OPTARG_ProtoField_new_BASE)) {
+ base = (unsigned)luaL_optinteger(L, WSLUA_OPTARG_ProtoField_new_BASE, BASE_NONE);
+ } else {
+ base = string_to_base(luaL_optstring(L, WSLUA_OPTARG_ProtoField_new_BASE, "BASE_NONE"));
+ }
+
+ switch (type) {
+ case FT_FRAMENUM:
+ if (base != BASE_NONE) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"FRAMENUM must use base.NONE");
+ return 0;
+ }
+ if (mask) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"FRAMENUM can not have a bitmask");
+ return 0;
+ }
+ break;
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_UINT64:
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ case FT_INT64:
+ if (base == BASE_NONE) {
+ base = BASE_DEC; /* Default base for integer */
+ } else if (base < BASE_DEC || base > BASE_HEX_DEC) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be either base.DEC, base.HEX, base.OCT,"
+ " base.DEC_HEX, base.DEC_HEX or base.HEX_DEC");
+ return 0;
+ }
+ if ((base == BASE_HEX || base == BASE_OCT) &&
+ (type == FT_INT8 || type == FT_INT16 || type == FT_INT24 || type == FT_INT32 || type == FT_INT64))
+ {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"This type does not display as hexadecimal");
+ return 0;
+ }
+ if (nargs >= WSLUA_OPTARG_ProtoField_new_VALUESTRING && !lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING)) {
+ if (type == FT_UINT64 || type == FT_INT64) {
+ vs64 = val64_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
+ } else {
+ vs32 = value_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
+ }
+ }
+ break;
+ case FT_BOOLEAN:
+ if (mask == 0x0 && base != BASE_NONE) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be base.NONE if bitmask is zero.");
+ return 0;
+ }
+ if (mask != 0x0 && (base < 1 || base > 64)) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be between 1 and 64 if bitmask is non-zero.");
+ return 0;
+ }
+ if (nargs >= WSLUA_OPTARG_ProtoField_new_VALUESTRING && !lua_isnil(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING)) {
+ tfs = true_false_string_from_table(L,WSLUA_OPTARG_ProtoField_new_VALUESTRING);
+ }
+ break;
+ case FT_ABSOLUTE_TIME:
+ if (base == BASE_NONE) {
+ base = ABSOLUTE_TIME_LOCAL; /* Default base for FT_ABSOLUTE_TIME */
+ } else if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be either LOCAL, UTC, or DOY_UTC");
+ return 0;
+ }
+ if (mask) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"ABSOLUTE_TIME can not have a bitmask");
+ return 0;
+ }
+ break;
+ case FT_NONE:
+ case FT_IPv4:
+ case FT_IPv6:
+ case FT_IPXNET:
+ case FT_ETHER:
+ case FT_FLOAT:
+ case FT_DOUBLE:
+ case FT_RELATIVE_TIME:
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_BYTES:
+ case FT_UINT_BYTES:
+ case FT_GUID:
+ case FT_OID:
+ case FT_SYSTEM_ID:
+ case FT_REL_OID:
+ case FT_EUI64:
+ case FT_VINES:
+ case FT_FCWWN:
+ if (base != BASE_NONE) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,BASE,"Base must be base.NONE");
+ return 0;
+ }
+ if (mask) {
+ WSLUA_OPTARG_ERROR(ProtoField_new,MASK,"This type can not have a bitmask");
+ return 0;
+ }
+ break;
+ default:
+ WSLUA_ARG_ERROR(ProtoField_new,TYPE,"Invalid field type");
+ break;
+ }
+
+ f = g_new(wslua_field_t,1);
+
+ f->hfid = -2;
+ f->ett = -1;
+ f->name = g_strdup(name);
+ f->abbrev = g_strdup(abbr);
+ f->type = type;
+ f->base = base;
+ if (tfs) {
+ f->vs = TFS(tfs);
+ } else if (vs32) {
+ f->vs = VALS(vs32);
+ } else if (vs64) {
+ /* Indicate that we are using val64_string */
+ f->base |= BASE_VAL64_STRING;
+ f->vs = VALS(vs64);
+ } else {
+ f->vs = NULL;
+ }
+ f->mask = mask;
+ if (blob && strcmp(blob, f->name) != 0) {
+ f->blob = g_strdup(blob);
+ } else {
+ f->blob = NULL;
+ }
+
+ pushProtoField(L,f);
+
+ WSLUA_RETURN(1); /* The newly created `ProtoField` object. */
+}
+
+static int ProtoField_integer(lua_State* L, enum ftenum type) {
+ ProtoField f;
+ const gchar* abbr = check_field_name(L,1,type);
+ const gchar* name = luaL_optstring(L,2,abbr);
+ unsigned default_base = (type == FT_FRAMENUM) ? BASE_NONE : BASE_DEC;
+ unsigned base = (unsigned)luaL_optinteger(L, 3, default_base);
+ value_string* vs32 = NULL;
+ val64_string* vs64 = NULL;
+ guint32 mask = wslua_optguint32(L,5,0);
+ const gchar* blob = luaL_optstring(L,6,NULL);
+
+ if (lua_gettop(L) > 3) {
+ if (type == FT_UINT64 || type == FT_INT64) {
+ vs64 = val64_string_from_table(L,4);
+ } else {
+ vs32 = value_string_from_table(L,4);
+ }
+ }
+
+ if (type == FT_FRAMENUM) {
+ if (base != BASE_NONE)
+ luaL_argerror(L, 3, "ftypes.FRAMENUMs must use base.NONE");
+ else if (mask)
+ luaL_argerror(L, 3, "ftypes.FRAMENUMs can not have a bitmask");
+ } else if (base < BASE_DEC || base > BASE_HEX_DEC) {
+ luaL_argerror(L, 3, "Base must be either base.DEC, base.HEX, base.OCT,"
+ " base.DEC_HEX, base.DEC_HEX or base.HEX_DEC");
+ return 0;
+ } else if ((base == BASE_HEX || base == BASE_OCT) &&
+ (type == FT_INT8 || type == FT_INT16 || type == FT_INT24 || type == FT_INT32 || type == FT_INT64)) {
+ luaL_argerror(L, 3, "This type does not display as hexadecimal");
+ return 0;
+ }
+
+ f = g_new(wslua_field_t,1);
+
+ f->hfid = -2;
+ f->ett = -1;
+ f->name = g_strdup(name);
+ f->abbrev = g_strdup(abbr);
+ f->type = type;
+ f->base = base;
+ if (vs64) {
+ /* Indicate that we are using val64_string */
+ f->base |= BASE_VAL64_STRING;
+ f->vs = VALS(vs64);
+ } else {
+ f->vs = VALS(vs32);
+ }
+ f->mask = mask;
+ if (blob && strcmp(blob, f->name) != 0) {
+ f->blob = g_strdup(blob);
+ } else {
+ f->blob = NULL;
+ }
+
+ pushProtoField(L,f);
+
+ return 1;
+}
+
+#define PROTOFIELD_INTEGER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_integer(L,FT); }
+/* _WSLUA_CONSTRUCTOR_ ProtoField_uint8 Creates a `ProtoField` of an unsigned 8-bit integer (i.e., a byte). */
+/* WSLUA_ARG_Protofield_uint8_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_uint8_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_uint8_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_uint8_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_uint8_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_uint8_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_uint16 Creates a `ProtoField` of an unsigned 16-bit integer. */
+/* WSLUA_ARG_Protofield_uint16_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_uint16_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_uint16_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_uint16_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_uint16_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_uint16_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_uint24 Creates a `ProtoField` of an unsigned 24-bit integer. */
+/* WSLUA_ARG_Protofield_uint24_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_uint24_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_uint24_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_uint24_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_uint24_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_uint24_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_uint32 Creates a `ProtoField` of an unsigned 32-bit integer. */
+/* WSLUA_ARG_Protofield_uint32_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_uint32_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_uint32_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_uint32_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_uint32_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_uint32_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_uint64 Creates a `ProtoField` of an unsigned 64-bit integer. */
+/* WSLUA_ARG_Protofield_uint64_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_uint64_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_uint64_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_uint64_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_uint64_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_uint64_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_int8 Creates a `ProtoField` of a signed 8-bit integer (i.e., a byte). */
+/* WSLUA_ARG_Protofield_int8_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_int8_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_int8_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_int8_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_int8_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_int8_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_int16 Creates a `ProtoField` of a signed 16-bit integer. */
+/* WSLUA_ARG_Protofield_int16_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_int16_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_int16_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_int16_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_int16_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_int16_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_int24 Creates a `ProtoField` of a signed 24-bit integer. */
+/* WSLUA_ARG_Protofield_int24_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_int24_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_int24_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_int24_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_int24_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_int24_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_int32 Creates a `ProtoField` of a signed 32-bit integer. */
+/* WSLUA_ARG_Protofield_int32_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_int32_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_int32_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_int32_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_int32_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_int32_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_int64 Creates a `ProtoField` of a signed 64-bit integer. */
+/* WSLUA_ARG_Protofield_int64_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_int64_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_int64_BASE One of `base.DEC`, `base.HEX` or `base.OCT`. */
+/* WSLUA_OPTARG_Protofield_int64_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_int64_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_int64_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_framenum Creates a `ProtoField` for a frame number (for hyperlinks between frames). */
+/* WSLUA_ARG_Protofield_framenum_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_framenum_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_framenum_BASE Only `base.NONE` is supported for framenum. */
+/* WSLUA_OPTARG_Protofield_framenum_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_framenum_MASK Integer mask of this field, which must be 0 for framenum. */
+/* WSLUA_OPTARG_Protofield_framenum_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+PROTOFIELD_INTEGER(uint8,FT_UINT8)
+PROTOFIELD_INTEGER(uint16,FT_UINT16)
+PROTOFIELD_INTEGER(uint24,FT_UINT24)
+PROTOFIELD_INTEGER(uint32,FT_UINT32)
+PROTOFIELD_INTEGER(uint64,FT_UINT64)
+PROTOFIELD_INTEGER(int8,FT_INT8)
+PROTOFIELD_INTEGER(int16,FT_INT16)
+PROTOFIELD_INTEGER(int24,FT_INT24)
+PROTOFIELD_INTEGER(int32,FT_INT32)
+PROTOFIELD_INTEGER(int64,FT_INT64)
+PROTOFIELD_INTEGER(framenum,FT_FRAMENUM)
+
+static int ProtoField_boolean(lua_State* L, enum ftenum type) {
+ ProtoField f;
+ const gchar* abbr = check_field_name(L,1,type);
+ const gchar* name = luaL_optstring(L,2,abbr);
+ unsigned base = (unsigned)luaL_optinteger(L, 3, BASE_NONE);
+ true_false_string* tfs = NULL;
+ guint32 mask = wslua_optguint32(L,5,0);
+ const gchar* blob = luaL_optstring(L,6,NULL);
+
+ if (mask == 0x0 && base != BASE_NONE) {
+ luaL_argerror(L,2,"Fieldbase (fielddisplay) must be base.NONE"
+ " if bitmask is zero.");
+ return 0;
+ }
+
+ if (mask != 0x0 && (base < 1 || base > 64)) {
+ luaL_argerror(L,2,"Fieldbase (fielddisplay) must be between 1 and 64"
+ " if bitmask is non-zero.");
+ return 0;
+ }
+
+ if (lua_gettop(L) > 3 && !lua_isnil(L,4)) {
+ tfs = true_false_string_from_table(L,4);
+ }
+
+ f = g_new(wslua_field_t,1);
+
+ f->hfid = -2;
+ f->ett = -1;
+ f->name = g_strdup(name);
+ f->abbrev = g_strdup(abbr);
+ f->type = type;
+ f->vs = TFS(tfs);
+ f->base = base;
+ f->mask = mask;
+ if (blob && strcmp(blob, f->name) != 0) {
+ f->blob = g_strdup(blob);
+ } else {
+ f->blob = NULL;
+ }
+
+ pushProtoField(L,f);
+
+ return 1;
+}
+
+#define PROTOFIELD_BOOL(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_boolean(L,FT); }
+/* _WSLUA_CONSTRUCTOR_ ProtoField_bool Creates a `ProtoField` for a boolean true/false value. */
+/* WSLUA_ARG_Protofield_bool_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_bool_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_bool_DISPLAY how wide the parent bitfield is (`base.NONE` is used for NULL-value). */
+/* WSLUA_OPTARG_Protofield_bool_VALUESTRING A table containing the text that corresponds to the values. */
+/* WSLUA_OPTARG_Protofield_bool_MASK Integer mask of this field. */
+/* WSLUA_OPTARG_Protofield_bool_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* XXX: T/F strings */
+PROTOFIELD_BOOL(bool,FT_BOOLEAN)
+
+static int ProtoField_time(lua_State* L,enum ftenum type) {
+ ProtoField f;
+ const gchar* abbr = NULL;
+ const gchar* name = luaL_optstring(L,2,abbr);
+ unsigned base = (unsigned)luaL_optinteger(L,3,ABSOLUTE_TIME_LOCAL);
+ const gchar* blob = NULL;
+
+ if (type == FT_ABSOLUTE_TIME) {
+ abbr = check_field_name(L,1,type);
+ blob = luaL_optstring(L,4,NULL);
+ if (base < ABSOLUTE_TIME_LOCAL || base > ABSOLUTE_TIME_DOY_UTC) {
+ luaL_argerror(L, 3, "Base must be either LOCAL, UTC, or DOY_UTC");
+ return 0;
+ }
+ } else {
+ abbr = check_field_name(L,1,type);
+ blob = luaL_optstring(L,3,NULL);
+ }
+
+ f = g_new(wslua_field_t,1);
+
+ f->hfid = -2;
+ f->ett = -1;
+ f->name = g_strdup(name);
+ f->abbrev = g_strdup(abbr);
+ f->type = type;
+ f->vs = NULL;
+ f->base = base;
+ f->mask = 0;
+ if (blob && strcmp(blob, f->name) != 0) {
+ f->blob = g_strdup(blob);
+ } else {
+ f->blob = NULL;
+ }
+
+ pushProtoField(L,f);
+
+ return 1;
+}
+
+#define PROTOFIELD_TIME(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_time(L,FT); }
+/* _WSLUA_CONSTRUCTOR_ ProtoField_absolute_time Creates a `ProtoField` of a time_t structure value. */
+/* WSLUA_ARG_Protofield_absolute_time_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_absolute_time_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_absolute_time_BASE One of `base.LOCAL`, `base.UTC` or `base.DOY_UTC`. */
+/* WSLUA_OPTARG_Protofield_absolute_time_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_relative_time Creates a `ProtoField` of a time_t structure value. */
+/* WSLUA_ARG_Protofield_relative_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_relative_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_relative_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+
+PROTOFIELD_TIME(absolute_time,FT_ABSOLUTE_TIME)
+
+static int ProtoField_other(lua_State* L,enum ftenum type) {
+ ProtoField f;
+ const gchar* abbr = check_field_name(L,1,type);
+ const gchar* name = luaL_optstring(L,2,abbr);
+ const gchar* blob = luaL_optstring(L,3,NULL);
+
+ f = g_new(wslua_field_t,1);
+
+ f->hfid = -2;
+ f->ett = -1;
+ f->name = g_strdup(name);
+ f->abbrev = g_strdup(abbr);
+ f->type = type;
+ f->vs = NULL;
+ f->base = BASE_NONE;
+ f->mask = 0;
+ if (blob && strcmp(blob, f->name) != 0) {
+ f->blob = g_strdup(blob);
+ } else {
+ f->blob = NULL;
+ }
+
+ pushProtoField(L,f);
+
+ return 1;
+}
+
+#define PROTOFIELD_OTHER(lower,FT) static int ProtoField_##lower(lua_State* L) { return ProtoField_other(L,FT); }
+/* _WSLUA_CONSTRUCTOR_ ProtoField_none Creates a `ProtoField` of an unstructured type. */
+/* WSLUA_ARG_Protofield_none_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_none_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_none_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_ipv4 Creates a `ProtoField` of an IPv4 address (4 bytes). */
+/* WSLUA_ARG_Protofield_ipv4_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_ipv4_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_ipv4_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_ipv6 Creates a `ProtoField` of an IPv6 address (16 bytes). */
+/* WSLUA_ARG_Protofield_ipv6_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_ipv6_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_ipv6_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_ether Creates a `ProtoField` of an Ethernet address (6 bytes). */
+/* WSLUA_ARG_Protofield_ether_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_ether_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_ether_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_float Creates a `ProtoField` of a floating point number (4 bytes). */
+/* WSLUA_ARG_Protofield_float_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_float_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_float_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_double Creates a `ProtoField` of a double-precision floating point (8 bytes). */
+/* WSLUA_ARG_Protofield_double_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_double_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_double_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_string Creates a `ProtoField` of a string value. */
+/* WSLUA_ARG_Protofield_string_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_string_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_string_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_stringz Creates a `ProtoField` of a zero-terminated string value. */
+/* WSLUA_ARG_Protofield_stringz_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_stringz_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_stringz_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_bytes Creates a `ProtoField` for an arbitrary number of bytes. */
+/* WSLUA_ARG_Protofield_bytes_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_bytes_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_bytes_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_ubytes Creates a `ProtoField` for an arbitrary number of unsigned bytes. */
+/* WSLUA_ARG_Protofield_ubytes_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_ubytes_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_ubytes_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_guid Creates a `ProtoField` for a Globally Unique IDentifier (GUID). */
+/* WSLUA_ARG_Protofield_guid_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_guid_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_guid_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_oid Creates a `ProtoField` for an ASN.1 Organizational IDentified (OID). */
+/* WSLUA_ARG_Protofield_oid_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_oid_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_oid_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_rel_oid Creates a `ProtoField` for an ASN.1 Relative-OID. */
+/* WSLUA_ARG_Protofield_rel_oid_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_rel_oid_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_rel_oid_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_systemid Creates a `ProtoField` for an OSI System ID. */
+/* WSLUA_ARG_Protofield_systemid_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_systemid_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_systemid_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+/* _WSLUA_CONSTRUCTOR_ ProtoField_eui64 Creates a `ProtoField` for an EUI64. */
+/* WSLUA_ARG_Protofield_eui64_ABBR Abbreviated name of the field (the string used in filters). */
+/* WSLUA_OPTARG_Protofield_eui64_NAME Actual name of the field (the string that appears in the tree). */
+/* WSLUA_OPTARG_Protofield_eui64_DESC Description of the field. */
+/* _WSLUA_RETURNS_ A `ProtoField` object to be added to a table set to the `Proto.fields` attribute. */
+
+PROTOFIELD_OTHER(none,FT_NONE)
+PROTOFIELD_OTHER(ipv4,FT_IPv4)
+PROTOFIELD_OTHER(ipv6,FT_IPv6)
+PROTOFIELD_OTHER(ipx,FT_IPXNET)
+PROTOFIELD_OTHER(ether,FT_ETHER)
+PROTOFIELD_OTHER(float,FT_FLOAT)
+PROTOFIELD_OTHER(double,FT_DOUBLE)
+PROTOFIELD_OTHER(relative_time,FT_RELATIVE_TIME)
+PROTOFIELD_OTHER(string,FT_STRING)
+PROTOFIELD_OTHER(stringz,FT_STRINGZ)
+PROTOFIELD_OTHER(bytes,FT_BYTES)
+PROTOFIELD_OTHER(ubytes,FT_UINT_BYTES)
+PROTOFIELD_OTHER(guid,FT_GUID)
+PROTOFIELD_OTHER(oid,FT_OID)
+PROTOFIELD_OTHER(rel_oid,FT_REL_OID)
+PROTOFIELD_OTHER(systemid,FT_SYSTEM_ID)
+PROTOFIELD_OTHER(eui64,FT_EUI64)
+
+WSLUA_METAMETHOD ProtoField__tostring(lua_State* L) {
+ /* Returns a string with info about a protofield (for debugging purposes). */
+ ProtoField f = checkProtoField(L,1);
+ gchar* s = g_strdup_printf("ProtoField(%i): %s %s %s %s %p %.8x %s",
+ f->hfid,f->name,f->abbrev,
+ ftenum_to_string(f->type),
+ base_to_string(f->base),
+ f->vs,f->mask,f->blob);
+ lua_pushstring(L,s);
+ g_free(s);
+ return 1;
+}
+
+static int ProtoField__gc(lua_State* L) {
+ ProtoField f = toProtoField(L,1);
+
+ /*
+ * A garbage collector for ProtoFields makes little sense.
+ * Even if This cannot be used anymore because it has gone out of scope,
+ * we can destroy the ProtoField only if it is not part of a ProtoFieldArray,
+ * if it actualy belongs to one we need to preserve it as it is pointed by
+ * a field array that may be registered afterwards causing a crash or memory corruption.
+ */
+
+ if (!f) {
+ luaL_argerror(L,1,"BUG: ProtoField_gc called for something not ProtoField");
+ /* g_assert() ?? */
+ } else if (f->hfid == -2) {
+ g_free(f->name);
+ g_free(f->abbrev);
+ g_free(f->blob);
+ g_free(f);
+ }
+
+ return 0;
+}
+
+WSLUA_METHODS ProtoField_methods[] = {
+ WSLUA_CLASS_FNREG(ProtoField,new),
+ WSLUA_CLASS_FNREG(ProtoField,none),
+ WSLUA_CLASS_FNREG(ProtoField,uint8),
+ WSLUA_CLASS_FNREG(ProtoField,uint16),
+ WSLUA_CLASS_FNREG(ProtoField,uint24),
+ WSLUA_CLASS_FNREG(ProtoField,uint32),
+ WSLUA_CLASS_FNREG(ProtoField,uint64),
+ WSLUA_CLASS_FNREG(ProtoField,int8),
+ WSLUA_CLASS_FNREG(ProtoField,int16),
+ WSLUA_CLASS_FNREG(ProtoField,int24),
+ WSLUA_CLASS_FNREG(ProtoField,int32),
+ WSLUA_CLASS_FNREG(ProtoField,int64),
+ WSLUA_CLASS_FNREG(ProtoField,framenum),
+ WSLUA_CLASS_FNREG(ProtoField,ipv4),
+ WSLUA_CLASS_FNREG(ProtoField,ipv6),
+ WSLUA_CLASS_FNREG(ProtoField,ipx),
+ WSLUA_CLASS_FNREG(ProtoField,ether),
+ WSLUA_CLASS_FNREG(ProtoField,bool),
+ WSLUA_CLASS_FNREG(ProtoField,float),
+ WSLUA_CLASS_FNREG(ProtoField,double),
+ WSLUA_CLASS_FNREG(ProtoField,absolute_time),
+ WSLUA_CLASS_FNREG(ProtoField,relative_time),
+ WSLUA_CLASS_FNREG(ProtoField,string),
+ WSLUA_CLASS_FNREG(ProtoField,stringz),
+ WSLUA_CLASS_FNREG(ProtoField,bytes),
+ WSLUA_CLASS_FNREG(ProtoField,ubytes),
+ WSLUA_CLASS_FNREG(ProtoField,guid),
+ WSLUA_CLASS_FNREG(ProtoField,oid),
+ WSLUA_CLASS_FNREG(ProtoField,rel_oid),
+ WSLUA_CLASS_FNREG(ProtoField,systemid),
+ WSLUA_CLASS_FNREG(ProtoField,eui64),
+ { NULL, NULL }
+};
+
+WSLUA_META ProtoField_meta[] = {
+ WSLUA_CLASS_MTREG(ProtoField,tostring),
+ { NULL, NULL }
+};
+
+int ProtoField_register(lua_State* L) {
+ WSLUA_REGISTER_CLASS(ProtoField);
+ return 0;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wslua/wslua_tvb.c b/epan/wslua/wslua_tvb.c
index 5fad6ddbf5..e1d180442c 100644
--- a/epan/wslua/wslua_tvb.c
+++ b/epan/wslua/wslua_tvb.c
@@ -6,6 +6,7 @@
* (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
* (c) 2009, Stig Bjorlykke <stig@bjorlykke.org>
+ * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@@ -28,343 +29,11 @@
#include "config.h"
-#include <epan/wmem/wmem.h>
-
-/* WSLUA_MODULE Tvb Functions for handling packet data */
-
#include "wslua.h"
-#include "wsutil/base64.h"
-
-WSLUA_CLASS_DEFINE(ByteArray,FAIL_ON_NULL("ByteArray"),NOP);
-
-WSLUA_CONSTRUCTOR ByteArray_new(lua_State* L) {
- /* Creates a `ByteArray` object.
-
- Starting in version 1.11.3, if the second argument is a boolean `true`,
- then the first argyument is treated as a raw Lua string of bytes to use,
- instead of a hexadecimal string.
- */
-#define WSLUA_OPTARG_ByteArray_new_HEXBYTES 1 /* A string consisting of hexadecimal bytes like "00 B1 A2" or "1a2b3c4d". */
-#define WSLUA_OPTARG_ByteArray_new_SEPARATOR 2 /* A string separator between hex bytes/words (default=" "),
- or if the boolean value `true` is used, then the first argument
- is treated as raw binary data */
- GByteArray* ba = g_byte_array_new();
- const gchar* s;
- size_t len = 0;
- const gchar* sep = " ";
- gboolean ishex = TRUE;
-
- if (lua_gettop(L) >= 1) {
- s = luaL_checklstring(L,WSLUA_OPTARG_ByteArray_new_HEXBYTES,&len);
-
- if (lua_gettop(L) >= 2) {
- if (lua_type(L,2) == LUA_TBOOLEAN && lua_toboolean(L,2)) {
- ishex = FALSE;
- } else {
- sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_new_SEPARATOR," ");
- }
- }
-
- if (ishex) {
- wslua_hex2bin(L, s, (guint)len, sep); /* this pushes a new string on top of stack */
- s = luaL_checklstring(L, -1, &len); /* get the new binary string */
- g_byte_array_append(ba,s,(guint)len); /* copy it into ByteArray */
- lua_pop(L,1); /* pop the newly created string */
- } else {
- g_byte_array_append(ba,s,(guint)len);
- }
- }
-
- pushByteArray(L,ba);
-
- WSLUA_RETURN(1); /* The new ByteArray object. */
-}
-
-/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
-static int ByteArray__gc(lua_State* L) {
- ByteArray ba = toByteArray(L,1);
-
- if (!ba) return 0;
-
- g_byte_array_free(ba,TRUE);
- return 0;
-}
-
-WSLUA_METAMETHOD ByteArray__concat(lua_State* L) {
- /* Concatenate two `ByteArrays`. */
-#define WSLUA_ARG_ByteArray__cat_FIRST 1 /* First array. */
-#define WSLUA_ARG_ByteArray__cat_SECOND 2 /* Second array. */
-
- ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_FIRST);
- ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__cat_SECOND);
- ByteArray ba;
-
- ba = g_byte_array_new();
- g_byte_array_append(ba,ba1->data,ba1->len);
- g_byte_array_append(ba,ba2->data,ba2->len);
-
- pushByteArray(L,ba);
- WSLUA_RETURN(1); /* The new composite `ByteArray`. */
-}
-
-WSLUA_METAMETHOD ByteArray__eq(lua_State* L) {
- /* Compares two ByteArray values.
-
- @since 1.11.4
- */
-#define WSLUA_ARG_ByteArray__eq_FIRST 1 /* First array. */
-#define WSLUA_ARG_ByteArray__eq_SECOND 2 /* Second array. */
- ByteArray ba1 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_FIRST);
- ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray__eq_SECOND);
- gboolean result = FALSE;
-
- if (ba1->len == ba2->len) {
- if (memcmp(ba1->data, ba2->data, ba1->len) == 0)
- result = TRUE;
- }
-
- lua_pushboolean(L,result);
-
- return 1;
-}
-
-WSLUA_METHOD ByteArray_prepend(lua_State* L) {
- /* Prepend a `ByteArray` to this `ByteArray`. */
-#define WSLUA_ARG_ByteArray_prepend_PREPENDED 2 /* `ByteArray` to be prepended. */
- ByteArray ba = checkByteArray(L,1);
- ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_prepend_PREPENDED);
-
- g_byte_array_prepend(ba,ba2->data,ba2->len);
-
- return 0;
-}
-
-WSLUA_METHOD ByteArray_append(lua_State* L) {
- /* Append a `ByteArray` to this `ByteArray`. */
-#define WSLUA_ARG_ByteArray_append_APPENDED 2 /* `ByteArray` to be appended. */
- ByteArray ba = checkByteArray(L,1);
- ByteArray ba2 = checkByteArray(L,WSLUA_ARG_ByteArray_append_APPENDED);
-
- g_byte_array_append(ba,ba2->data,ba2->len);
-
- return 0;
-}
-
-WSLUA_METHOD ByteArray_set_size(lua_State* L) {
- /* Sets the size of a `ByteArray`, either truncating it or filling it with zeros. */
-#define WSLUA_ARG_ByteArray_set_size_SIZE 2 /* New size of the array. */
-
- ByteArray ba = checkByteArray(L,1);
- int siz = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_size_SIZE);
- guint8* padding;
-
- if (siz < 0) {
- WSLUA_ERROR(ByteArray_set_size,"ByteArray size must be non-negative");
- return 0;
- }
-
- if (ba->len >= (guint)siz) { /* truncate */
- g_byte_array_set_size(ba,siz);
- } else { /* fill */
- padding = (guint8 *)g_malloc0(sizeof(guint8)*(siz - ba->len));
- g_byte_array_append(ba,padding,siz - ba->len);
- g_free(padding);
- }
- return 0;
-}
-
-WSLUA_METHOD ByteArray_set_index(lua_State* L) {
- /* Sets the value of an index of a `ByteArray`. */
-#define WSLUA_ARG_ByteArray_set_index_INDEX 2 /* The position of the byte to be set. */
-#define WSLUA_ARG_ByteArray_set_index_VALUE 3 /* The char value to set [0-255]. */
- ByteArray ba = checkByteArray(L,1);
- int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_INDEX);
- int v = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_VALUE);
-
- if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
- luaL_argerror(L,2,"bad index");
- return 0;
- }
-
- if (idx < 0 || (guint)idx >= ba->len) {
- luaL_argerror(L,2,"index out of range");
- return 0;
- }
-
- if (v < 0 || v > 255) {
- luaL_argerror(L,3,"Byte out of range");
- return 0;
- }
-
- ba->data[idx] = (guint8)v;
-
- return 0;
-}
-
-
-WSLUA_METHOD ByteArray_get_index(lua_State* L) {
- /* Get the value of a byte in a `ByteArray`. */
-#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the byte to get. */
- ByteArray ba = checkByteArray(L,1);
- int idx = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_get_index_INDEX);
-
- if (idx == 0 && ! g_str_equal(luaL_optstring(L,2,""),"0") ) {
- luaL_argerror(L,2,"bad index");
- return 0;
- }
-
- if (idx < 0 || (guint)idx >= ba->len) {
- luaL_argerror(L,2,"index out of range");
- return 0;
- }
- lua_pushnumber(L,ba->data[idx]);
-
- WSLUA_RETURN(1); /* The value [0-255] of the byte. */
-}
-
-WSLUA_METHOD ByteArray_len(lua_State* L) {
- /* Obtain the length of a `ByteArray`. */
- ByteArray ba = checkByteArray(L,1);
-
- lua_pushnumber(L,(lua_Number)ba->len);
-
- WSLUA_RETURN(1); /* The length of the `ByteArray`. */
-}
-
-WSLUA_METHOD ByteArray_subset(lua_State* L) {
- /* Obtain a segment of a `ByteArray`, as a new `ByteArray`. */
-#define WSLUA_ARG_ByteArray_set_index_OFFSET 2 /* The position of the first byte (0=first). */
-#define WSLUA_ARG_ByteArray_set_index_LENGTH 3 /* The length of the segment. */
- ByteArray ba = checkByteArray(L,1);
- int offset = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_OFFSET);
- int len = (int)luaL_checkinteger(L,WSLUA_ARG_ByteArray_set_index_LENGTH);
- ByteArray sub;
-
- if ((offset + len) > (int)ba->len || offset < 0 || len < 1) {
- luaL_error(L,"Out Of Bounds");
- return 0;
- }
-
- sub = g_byte_array_new();
- g_byte_array_append(sub,ba->data + offset,len);
-
- pushByteArray(L,sub);
-
- WSLUA_RETURN(1); /* A `ByteArray` containing the requested segment. */
-}
-
-WSLUA_METHOD ByteArray_base64_decode(lua_State* L) {
- /* Obtain a base64 decoded `ByteArray`.
-
- @since 1.11.3
- */
- ByteArray ba = checkByteArray(L,1);
- ByteArray ba2;
- gchar *data;
- size_t len;
-
- ba2 = g_byte_array_new();
- data = (gchar*)g_malloc (ba->len + 1);
- memcpy(data, ba->data, ba->len);
- data[ba->len] = '\0';
-
- len = ws_base64_decode_inplace(data);
- g_byte_array_append(ba2,data,(int)len);
- g_free(data);
-
- pushByteArray(L,ba2);
- WSLUA_RETURN(1); /* The created `ByteArray`. */
-}
-
-WSLUA_METHOD ByteArray_raw(lua_State* L) {
- /* Obtain a Lua string of the binary bytes in a `ByteArray`.
-
- @since 1.11.3
- */
-#define WSLUA_OPTARG_ByteArray_raw_OFFSET 2 /* The position of the first byte (default=0/first). */
-#define WSLUA_OPTARG_ByteArray_raw_LENGTH 3 /* The length of the segment to get (default=all). */
- ByteArray ba = checkByteArray(L,1);
- guint offset = (guint) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_OFFSET,0);
- int len;
-
- if (!ba) return 0;
- if (offset > ba->len) {
- WSLUA_OPTARG_ERROR(ByteArray_raw,OFFSET,"offset beyond end of byte array");
- return 0;
- }
-
- len = (int) luaL_optinteger(L,WSLUA_OPTARG_ByteArray_raw_LENGTH, ba->len - offset);
- if ((len < 0) || ((guint)len > (ba->len - offset)))
- len = ba->len - offset;
-
- lua_pushlstring(L, &(ba->data[offset]), len);
-
- WSLUA_RETURN(1); /* A Lua string of the binary bytes in the ByteArray. */
-}
-
-WSLUA_METHOD ByteArray_tohex(lua_State* L) {
- /* Obtain a Lua string of the bytes in a `ByteArray` as hex-ascii, with given separator
-
- @since 1.11.3
- */
-#define WSLUA_OPTARG_ByteArray_tohex_LOWERCASE 2 /* True to use lower-case hex characters (default=false). */
-#define WSLUA_OPTARG_ByteArray_tohex_SEPARATOR 3 /* A string separator to insert between hex bytes (default=nil). */
- ByteArray ba = checkByteArray(L,1);
- gboolean lowercase = FALSE;
- const gchar* sep = NULL;
-
- if (!ba) return 0;
-
- lowercase = wslua_optbool(L,WSLUA_OPTARG_ByteArray_tohex_LOWERCASE,FALSE);
- sep = luaL_optstring(L,WSLUA_OPTARG_ByteArray_tohex_SEPARATOR,NULL);
-
- wslua_bin2hex(L, ba->data, ba->len, lowercase, sep);
-
- WSLUA_RETURN(1); /* A hex-ascii string representation of the `ByteArray`. */
-}
-
-WSLUA_METAMETHOD ByteArray__tostring(lua_State* L) {
- /* Obtain a Lua string containing the bytes in a `ByteArray` so that it can be used in
- display filters (e.g. "01FE456789AB"). */
- ByteArray ba = checkByteArray(L,1);
-
- if (!ba) return 0;
-
- wslua_bin2hex(L, ba->data, ba->len, FALSE, NULL);
-
- WSLUA_RETURN(1); /* A hex-ascii string representation of the `ByteArray`. */
-}
-
-static int ByteArray_tvb (lua_State *L);
-
-WSLUA_METHODS ByteArray_methods[] = {
- WSLUA_CLASS_FNREG(ByteArray,new),
- WSLUA_CLASS_FNREG(ByteArray,len),
- WSLUA_CLASS_FNREG(ByteArray,prepend),
- WSLUA_CLASS_FNREG(ByteArray,append),
- WSLUA_CLASS_FNREG(ByteArray,subset),
- WSLUA_CLASS_FNREG(ByteArray,set_size),
- WSLUA_CLASS_FNREG(ByteArray,tvb),
- WSLUA_CLASS_FNREG(ByteArray,base64_decode),
- WSLUA_CLASS_FNREG(ByteArray,get_index),
- WSLUA_CLASS_FNREG(ByteArray,set_index),
- WSLUA_CLASS_FNREG(ByteArray,tohex),
- WSLUA_CLASS_FNREG(ByteArray,raw),
- { NULL, NULL }
-};
+#include <epan/wmem/wmem.h>
-WSLUA_META ByteArray_meta[] = {
- WSLUA_CLASS_MTREG(ByteArray,tostring),
- WSLUA_CLASS_MTREG(ByteArray,concat),
- WSLUA_CLASS_MTREG(ByteArray,eq),
- {"__call",ByteArray_subset},
- { NULL, NULL }
-};
-int ByteArray_register(lua_State* L) {
- WSLUA_REGISTER_CLASS(ByteArray);
- return 0;
-}
+/* WSLUA_MODULE Tvb Functions for handling packet data */
/*
@@ -405,9 +74,16 @@ WSLUA_CLASS_DEFINE(Tvb,FAIL_ON_NULL_OR_EXPIRED("Tvb"),NOP);
static GPtrArray* outstanding_Tvb = NULL;
static GPtrArray* outstanding_TvbRange = NULL;
-#define PUSH_TVB(L,t) {g_ptr_array_add(outstanding_Tvb,t);pushTvb(L,t);}
+/* this is used to push Tvbs that were created brand new by wslua code */
+int push_wsluaTvb(lua_State* L, Tvb t) {
+ g_ptr_array_add(outstanding_Tvb,t);
+ pushTvb(L,t);
+ return 1;
+}
+
#define PUSH_TVBRANGE(L,t) {g_ptr_array_add(outstanding_TvbRange,t);pushTvbRange(L,t);}
+
static void free_Tvb(Tvb tvb) {
if (!tvb) return;
@@ -427,25 +103,7 @@ void clear_outstanding_Tvb(void) {
}
}
-static void free_TvbRange(TvbRange tvbr) {
- if (!(tvbr && tvbr->tvb)) return;
-
- if (!tvbr->tvb->expired) {
- tvbr->tvb->expired = TRUE;
- } else {
- free_Tvb(tvbr->tvb);
- g_free(tvbr);
- }
-}
-
-void clear_outstanding_TvbRange(void) {
- while (outstanding_TvbRange->len) {
- TvbRange tvbr = (TvbRange)g_ptr_array_remove_index_fast(outstanding_TvbRange,0);
- free_TvbRange(tvbr);
- }
-}
-
-
+/* this is used to push Tvbs that just point to pre-existing C-code Tvbs */
Tvb* push_Tvb(lua_State* L, tvbuff_t* ws_tvb) {
Tvb tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
tvb->ws_tvb = ws_tvb;
@@ -456,62 +114,6 @@ Tvb* push_Tvb(lua_State* L, tvbuff_t* ws_tvb) {
}
-
-/*
- * ByteArray_tvb(name)
- */
-WSLUA_CONSTRUCTOR ByteArray_tvb (lua_State *L) {
- /* Creates a new `Tvb` from a `ByteArray` (it gets added to the current frame too). */
-#define WSLUA_ARG_ByteArray_tvb_NAME 2 /* The name to be given to the new data-source. */
- ByteArray ba = checkByteArray(L,1);
- const gchar* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Unnamed") ;
- guint8* data;
- Tvb tvb;
-
- if (!lua_tvb) {
- luaL_error(L,"Tvbs can only be created and used in dissectors");
- return 0;
- }
-
- data = (guint8 *)g_memdup(ba->data, ba->len);
-
- tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
- tvb->ws_tvb = tvb_new_real_data(data, ba->len,ba->len);
- tvb->expired = FALSE;
- tvb->need_free = TRUE;
- tvb_set_free_cb(tvb->ws_tvb, g_free);
-
- add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
- PUSH_TVB(L,tvb);
- WSLUA_RETURN(1); /* The created `Tvb`. */
-}
-
-WSLUA_CONSTRUCTOR TvbRange_tvb (lua_State *L) {
- /* Creates a (sub)`Tvb` from a `TvbRange`. */
-#define WSLUA_ARG_Tvb_new_subset_RANGE 1 /* The `TvbRange` from which to create the new `Tvb`. */
-
- TvbRange tvbr = checkTvbRange(L,WSLUA_ARG_Tvb_new_subset_RANGE);
- Tvb tvb;
-
- if (! (tvbr && tvbr->tvb)) return 0;
- if (tvbr->tvb->expired) {
- luaL_error(L,"expired tvb");
- return 0;
- }
-
- if (tvb_offset_exists(tvbr->tvb->ws_tvb, tvbr->offset + tvbr->len -1 )) {
- tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
- tvb->expired = FALSE;
- tvb->need_free = FALSE;
- tvb->ws_tvb = tvb_new_subset(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, tvbr->len);
- PUSH_TVB(L, tvb);
- return 1;
- } else {
- luaL_error(L,"Out Of Bounds");
- return 0;
- }
-}
-
WSLUA_METAMETHOD Tvb__tostring(lua_State* L) {
/* Convert the bytes of a `Tvb` into a string, to be used for debugging purposes, as '...'
will be appended if the string is too long. */
@@ -615,46 +217,6 @@ WSLUA_METAMETHOD Tvb__call(lua_State* L) {
}
#endif
-WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("TvbRange"),NOP);
-/*
- A `TvbRange` represents a usable range of a `Tvb` and is used to extract data from the `Tvb` that generated it.
-
- `TvbRange`s are created by calling a `Tvb` (e.g. 'tvb(offset,length)'). If the `TvbRange` span is outside the
- `Tvb`'s range the creation will cause a runtime error.
- */
-
-gboolean push_TvbRange(lua_State* L, tvbuff_t* ws_tvb, int offset, int len) {
- TvbRange tvbr;
-
- if (!ws_tvb) {
- luaL_error(L,"expired tvb");
- return FALSE;
- }
-
- if (len == -1) {
- len = tvb_captured_length_remaining(ws_tvb,offset);
- if (len < 0) {
- luaL_error(L,"out of bounds");
- return FALSE;
- }
- } else if ( (guint)(len + offset) > tvb_captured_length(ws_tvb)) {
- luaL_error(L,"Range is out of bounds");
- return FALSE;
- }
-
- tvbr = (TvbRange)g_malloc(sizeof(struct _wslua_tvbrange));
- tvbr->tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
- tvbr->tvb->ws_tvb = ws_tvb;
- tvbr->tvb->expired = FALSE;
- tvbr->tvb->need_free = FALSE;
- tvbr->offset = offset;
- tvbr->len = len;
-
- PUSH_TVBRANGE(L,tvbr);
-
- return TRUE;
-}
-
WSLUA_METHOD Tvb_range(lua_State* L) {
/* Creates a `TvbRange` from this `Tvb`. */
@@ -762,10 +324,100 @@ WSLUA_META Tvb_meta[] = {
int Tvb_register(lua_State* L) {
WSLUA_REGISTER_CLASS(Tvb);
+ outstanding_Tvb = g_ptr_array_new();
return 0;
}
+
+
+WSLUA_CLASS_DEFINE(TvbRange,FAIL_ON_NULL("TvbRange"),NOP);
+/*
+ A `TvbRange` represents a usable range of a `Tvb` and is used to extract data from the `Tvb` that generated it.
+
+ `TvbRange`s are created by calling a `Tvb` (e.g. 'tvb(offset,length)'). If the `TvbRange` span is outside the
+ `Tvb`'s range the creation will cause a runtime error.
+ */
+
+
+static void free_TvbRange(TvbRange tvbr) {
+ if (!(tvbr && tvbr->tvb)) return;
+
+ if (!tvbr->tvb->expired) {
+ tvbr->tvb->expired = TRUE;
+ } else {
+ free_Tvb(tvbr->tvb);
+ g_free(tvbr);
+ }
+}
+
+void clear_outstanding_TvbRange(void) {
+ while (outstanding_TvbRange->len) {
+ TvbRange tvbr = (TvbRange)g_ptr_array_remove_index_fast(outstanding_TvbRange,0);
+ free_TvbRange(tvbr);
+ }
+}
+
+
+gboolean push_TvbRange(lua_State* L, tvbuff_t* ws_tvb, int offset, int len) {
+ TvbRange tvbr;
+
+ if (!ws_tvb) {
+ luaL_error(L,"expired tvb");
+ return FALSE;
+ }
+
+ if (len == -1) {
+ len = tvb_captured_length_remaining(ws_tvb,offset);
+ if (len < 0) {
+ luaL_error(L,"out of bounds");
+ return FALSE;
+ }
+ } else if ( (guint)(len + offset) > tvb_captured_length(ws_tvb)) {
+ luaL_error(L,"Range is out of bounds");
+ return FALSE;
+ }
+
+ tvbr = (TvbRange)g_malloc(sizeof(struct _wslua_tvbrange));
+ tvbr->tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
+ tvbr->tvb->ws_tvb = ws_tvb;
+ tvbr->tvb->expired = FALSE;
+ tvbr->tvb->need_free = FALSE;
+ tvbr->offset = offset;
+ tvbr->len = len;
+
+ PUSH_TVBRANGE(L,tvbr);
+
+ return TRUE;
+}
+
+
+WSLUA_CONSTRUCTOR TvbRange_tvb (lua_State *L) {
+ /* Creates a (sub)`Tvb` from a `TvbRange`. */
+#define WSLUA_ARG_Tvb_new_subset_RANGE 1 /* The `TvbRange` from which to create the new `Tvb`. */
+
+ TvbRange tvbr = checkTvbRange(L,WSLUA_ARG_Tvb_new_subset_RANGE);
+ Tvb tvb;
+
+ if (! (tvbr && tvbr->tvb)) return 0;
+ if (tvbr->tvb->expired) {
+ luaL_error(L,"expired tvb");
+ return 0;
+ }
+
+ if (tvb_offset_exists(tvbr->tvb->ws_tvb, tvbr->offset + tvbr->len -1 )) {
+ tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
+ tvb->expired = FALSE;
+ tvb->need_free = FALSE;
+ tvb->ws_tvb = tvb_new_subset(tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, tvbr->len);
+ return push_wsluaTvb(L, tvb);
+ } else {
+ luaL_error(L,"Out Of Bounds");
+ return 0;
+ }
+}
+
+
/*
* get a Blefuscuoan unsigned integer from a tvb
*/
@@ -1619,7 +1271,7 @@ WSLUA_METHOD TvbRange_raw(lua_State* L) {
}
if ((guint)offset > tvb_captured_length(tvbr->tvb->ws_tvb)) {
- WSLUA_OPTARG_ERROR(Tvb_raw,OFFSET,"offset beyond end of Tvb");
+ WSLUA_OPTARG_ERROR(TvbRange_raw,OFFSET,"offset beyond end of Tvb");
return 0;
}
@@ -1734,7 +1386,6 @@ WSLUA_META TvbRange_meta[] = {
};
int TvbRange_register(lua_State* L) {
- outstanding_Tvb = g_ptr_array_new();
outstanding_TvbRange = g_ptr_array_new();
WSLUA_REGISTER_CLASS(TvbRange);
return 0;