aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wslua
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2021-02-21 14:18:04 -0800
committerGuy Harris <gharris@sonic.net>2021-02-21 23:18:35 +0000
commit842a7cccf9ec96ab7ce8945d4de77537f69efc2f (patch)
tree8e27dfa6aed434b1e0cd5e6ba7a0078c310ab829 /epan/wslua
parentb8ce02e6fb43dedb8d1a480a154cc7cca0c5c353 (diff)
wiretap: have file handlers advertise blocks and options supported.
Instead of a "supports name resolution" Boolean and bitflags for types of comments supported, provide a list of block types that the file type/subtype supports, with each block type having a list of options supported. Indicate whether "supported" means "one instance" or "multiple instances". "Supports" doesn't just mean "can be written", it also means "could be read". Rename WTAP_BLOCK_IF_DESCRIPTION to WTAP_BLOCK_IF_ID_AND_INFO, to indicate that it provides, in addition to information about the interface, an ID (implicitly, in pcapng files, by its ordinal number) that is associated with every packet in the file. Emphasize that in comments - just because your capture file format can list the interfaces on which a capture was done, that doesn't mean it supports this; it doesn't do so if the file doesn't indicate, for every packet, on which of those interfaces it was captured (I'm looking at *you*, Microsoft Network Monitor...). Use APIs to query that information to do what the "does this file type/subtype support name resolution information", "does this file type/subtype support all of these comment types", and "does this file type/subtype support - and require - interface IDs" APIs did. Provide backwards compatibility for Lua. This allows us to eliminate the WTAP_FILE_TYPE_SUBTYPE_ values for IBM's iptrace; do so.
Diffstat (limited to 'epan/wslua')
-rw-r--r--epan/wslua/wslua_file_handler.c272
1 files changed, 267 insertions, 5 deletions
diff --git a/epan/wslua/wslua_file_handler.c b/epan/wslua/wslua_file_handler.c
index 49602878a8..75c2111f73 100644
--- a/epan/wslua/wslua_file_handler.c
+++ b/epan/wslua/wslua_file_handler.c
@@ -606,6 +606,31 @@ wslua_filehandler_dump_finish(wtap_dumper *wdh, int *err, gchar **err_info)
return (retval == 1);
}
+/*
+ * Prototype table of option support.
+ * We start out saying we don't support comments, and we don't mention
+ * other options.
+ */
+static const struct supported_option_type option_type_proto[] = {
+ { OPT_COMMENT, OPTION_NOT_SUPPORTED }
+};
+
+/*
+ * Prototype table of block type support.
+ * We start out saying we only support packets.
+ */
+static const struct supported_block_type block_type_proto[] = {
+ { WTAP_BLOCK_SECTION, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_IF_ID_AND_INFO, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_NAME_RESOLUTION, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_IF_STATISTICS, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_DECRYPTION_SECRETS, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_FT_SPECIFIC_REPORT, BLOCK_NOT_SUPPORTED, 0, NULL },
+ { WTAP_BLOCK_FT_SPECIFIC_EVENT, BLOCK_NOT_SUPPORTED, 0, NULL }
+};
+
+#define NUM_LISTED_BLOCK_TYPES (sizeof block_type_proto / sizeof block_type_proto[0])
WSLUA_CONSTRUCTOR FileHandler_new(lua_State* L) {
/* Creates a new FileHandler */
@@ -619,6 +644,7 @@ WSLUA_CONSTRUCTOR FileHandler_new(lua_State* L) {
const gchar* internal_description = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_INTERNAL_DESCRIPTION);
const gchar* type = luaL_checkstring(L,WSLUA_ARG_FileHandler_new_TYPE);
FileHandler fh = (FileHandler) g_malloc0(sizeof(struct _wslua_filehandler));
+ struct supported_block_type *supported_blocks;
fh->is_reader = (strchr(type,'r') != NULL) ? TRUE : FALSE;
fh->is_writer = (strchr(type,'w') != NULL) ? TRUE : FALSE;
@@ -640,7 +666,27 @@ WSLUA_CONSTRUCTOR FileHandler_new(lua_State* L) {
fh->finfo.default_file_extension = NULL;
fh->finfo.additional_file_extensions = NULL;
fh->finfo.writing_must_seek = FALSE;
- fh->finfo.has_name_resolution = FALSE;
+ supported_blocks = (struct supported_block_type *)g_memdup(&block_type_proto, sizeof block_type_proto);
+ /*
+ * Add a list of options to the seciton block, interface block, and
+ * packet block, so the file handler can indicate comment support.
+ */
+ for (size_t i = 0; i < NUM_LISTED_BLOCK_TYPES; i++) {
+ switch (supported_blocks[i].type) {
+
+ case WTAP_BLOCK_SECTION:
+ case WTAP_BLOCK_IF_ID_AND_INFO:
+ case WTAP_BLOCK_PACKET:
+ supported_blocks[i].num_supported_options = OPTION_TYPES_SUPPORTED(option_type_proto);
+ supported_blocks[i].supported_options = (struct supported_option_type *)g_memdup(&option_type_proto, sizeof option_type_proto);
+ break;
+
+ default:
+ break;
+ }
+ }
+ fh->finfo.num_supported_blocks = NUM_LISTED_BLOCK_TYPES;
+ fh->finfo.supported_blocks = supported_blocks;
fh->finfo.can_write_encap = NULL;
fh->finfo.dump_open = NULL;
/* this will be set to a new file_type when registered */
@@ -975,13 +1021,229 @@ WSLUA_ATTRIBUTE_NAMED_BOOLEAN_SETTER(FileHandler,writing_must_seek,finfo.writing
/* 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);
+static inline struct supported_block_type *
+safe_cast_away_block_type_const(const struct supported_block_type *arg)
+{
+ /*
+ * Cast away constness without a warning; we know we can do this
+ * because, for Lua file handlers, the table of supported block
+ * types is in allocated memory, so that we *can* modify it.
+ *
+ * The pointer in the file_type_subtype_info structure is a
+ * pointer to const because compiled file handlers will
+ * normally set it to point to a static const structure.
+ */
+DIAG_OFF_CAST_AWAY_CONST
+ return (struct supported_block_type *)arg;
+DIAG_ON_CAST_AWAY_CONST
+}
+
+WSLUA_ATTRIBUTE_GET(FileHandler,writes_name_resolution,{ \
+ gboolean supports_name_resolution = FALSE; \
+ for (size_t i = 0; i < obj->finfo.num_supported_blocks; i++) { \
+ /* \
+ * If WTAP_BLOCK_NAME_RESOLUTION is supported, name \
+ * resolution is supported. \
+ */ \
+ if (obj->finfo.supported_blocks[i].type == WTAP_BLOCK_NAME_RESOLUTION) { \
+ supports_name_resolution = (obj->finfo.supported_blocks[i].support != BLOCK_NOT_SUPPORTED); \
+ break; \
+ } \
+ } \
+ lua_pushboolean(L, supports_name_resolution); \
+});
+WSLUA_ATTRIBUTE_SET(FileHandler,writes_name_resolution, { \
+ gboolean supports_name_resolution; \
+ if (!lua_isboolean(L,-1) ) \
+ return luaL_error(L, "FileHandler's attribute`writes_name_resolution' must be a boolean"); \
+ supports_name_resolution = lua_toboolean(L,-1); \
+ /* \
+ * Update support for WTAP_BLOCK_NAME_RESOLUTION; the entry for \
+ * it should be there. \
+ */ \
+ for (size_t i = 0; i < obj->finfo.num_supported_blocks; i++) { \
+ if (obj->finfo.supported_blocks[i].type == WTAP_BLOCK_NAME_RESOLUTION) { \
+ struct supported_block_type *supported_blocks;
+ supported_blocks = safe_cast_away_block_type_const(obj->finfo.supported_blocks); \
+
+ supported_blocks[i].support = supports_name_resolution ? ONE_BLOCK_SUPPORTED : BLOCK_NOT_SUPPORTED; \
+ break; \
+ } \
+ } \
+});
/* 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);
+static inline struct supported_option_type *
+safe_cast_away_option_type_const(const struct supported_option_type *arg)
+{
+ /*
+ * Cast away constness without a warning; we know we can do this
+ * because, for Lua file handlers, the table of supported option
+ * types is in allocated memory, so that we *can* modify it.
+ *
+ * The pointer in the file_type_subtype_info structure is a
+ * pointer to const because compiled file handlers will
+ * normally set it to point to a static const structure.
+ */
+DIAG_OFF_CAST_AWAY_CONST
+ return (struct supported_option_type *)arg;
+DIAG_ON_CAST_AWAY_CONST
+}
+
+WSLUA_ATTRIBUTE_GET(FileHandler,supported_comment_types,{ \
+ guint supported_comment_types = 0; \
+ for (size_t i = 0; i < obj->finfo.num_supported_blocks; i++) { \
+ size_t num_supported_options; \
+ const struct supported_option_type *supported_options;
+\
+ /* \
+ * Is this block type supported? \
+ */ \
+ if (obj->finfo.supported_blocks[i].support == BLOCK_NOT_SUPPORTED) { \
+ /* \
+ * No - skip it. \
+ */ \
+ continue; \
+ } \
+\
+ /* \
+ * Yes - what type of block is it? \
+ */ \
+ switch (obj->finfo.supported_blocks[i].type) { \
+\
+ case WTAP_BLOCK_SECTION: \
+ /* \
+ * Section block - does this block type support comments? \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = obj->finfo.supported_blocks[i].supported_options; \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ if (supported_options[i].support != OPTION_NOT_SUPPORTED) \
+ supported_comment_types |= WTAP_COMMENT_PER_SECTION; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ case WTAP_BLOCK_IF_ID_AND_INFO: \
+ /* \
+ * Interface block - does this block type support comments? \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = obj->finfo.supported_blocks[i].supported_options; \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ if (supported_options[i].support != OPTION_NOT_SUPPORTED) \
+ supported_comment_types |= WTAP_COMMENT_PER_INTERFACE; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ case WTAP_BLOCK_PACKET: \
+ /* \
+ * Packet block - does this block type support comments? \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = obj->finfo.supported_blocks[i].supported_options; \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ if (supported_options[i].support != OPTION_NOT_SUPPORTED) \
+ supported_comment_types |= WTAP_COMMENT_PER_PACKET; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ default: \
+ break;\
+ } \
+ } \
+ lua_pushnumber(L, (lua_Number)supported_comment_types); \
+});
+WSLUA_ATTRIBUTE_SET(FileHandler,supported_comment_types, { \
+ guint supported_comment_types; \
+ size_t num_supported_options; \
+ struct supported_option_type *supported_options; \
+ if (!lua_isnumber(L,-1) ) \
+ return luaL_error(L, "FileHandler's attribute`supported_comment_types' must be a number"); \
+ supported_comment_types = wslua_toguint(L,-1); \
+ /* \
+ * Update support for comments in the relevant block types; the entries \
+ * for comments in those types should be there. \
+ */ \
+ for (size_t i = 0; i < obj->finfo.num_supported_blocks; i++) { \
+\
+ /* \
+ * Is this block type supported? \
+ */ \
+ if (obj->finfo.supported_blocks[i].support == BLOCK_NOT_SUPPORTED) { \
+ /* \
+ * No - skip it. \
+ */ \
+ continue; \
+ } \
+\
+ /* \
+ * Yes - what type of block is it? \
+ */ \
+ switch (obj->finfo.supported_blocks[i].type) { \
+\
+ case WTAP_BLOCK_SECTION: \
+ /* \
+ * Section block - update the comment support. \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = safe_cast_away_option_type_const(obj->finfo.supported_blocks[i].supported_options); \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ supported_options[i].support = \
+ (supported_comment_types &= WTAP_COMMENT_PER_SECTION) ? \
+ ONE_OPTION_SUPPORTED : OPTION_NOT_SUPPORTED ; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ case WTAP_BLOCK_IF_ID_AND_INFO: \
+ /* \
+ * Interface block - does this block type support comments? \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = safe_cast_away_option_type_const(obj->finfo.supported_blocks[i].supported_options); \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ supported_options[i].support = \
+ (supported_comment_types &= WTAP_COMMENT_PER_INTERFACE) ? \
+ ONE_OPTION_SUPPORTED : OPTION_NOT_SUPPORTED ; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ case WTAP_BLOCK_PACKET: \
+ /* \
+ * Packet block - does this block type support comments? \
+ */ \
+ num_supported_options = obj->finfo.supported_blocks[i].num_supported_options; \
+ supported_options = safe_cast_away_option_type_const(obj->finfo.supported_blocks[i].supported_options); \
+ for (size_t j = 0; j < num_supported_options; i++) { \
+ if (supported_options[i].opt == OPT_COMMENT) { \
+ supported_options[i].support = \
+ (supported_comment_types &= WTAP_COMMENT_PER_PACKET) ? \
+ ONE_OPTION_SUPPORTED : OPTION_NOT_SUPPORTED ; \
+ break; \
+ } \
+ } \
+ break; \
+\
+ default: \
+ break;\
+ } \
+ } \
+});
/* 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