2015-04-29 07:19:08 +00:00
|
|
|
/* nettrace_3gpp_32_423.c
|
|
|
|
*
|
2015-07-26 11:54:12 +00:00
|
|
|
* Decoder for 3GPP TS 32.423 file format for the Wiretap library.
|
2015-04-29 07:19:08 +00:00
|
|
|
* The main purpose is to have Wireshark decode raw message content (<rawMsg> tag).
|
|
|
|
*
|
2018-02-07 11:26:45 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2015-04-29 07:19:08 +00:00
|
|
|
*
|
2019-07-28 04:20:27 +00:00
|
|
|
* Ref: https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=2010
|
2015-04-29 07:19:08 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "wtap-int.h"
|
|
|
|
#include "file_wrappers.h"
|
|
|
|
|
2021-08-20 09:17:14 +00:00
|
|
|
#include <wsutil/exported_pdu_tlvs.h>
|
2015-04-29 07:19:08 +00:00
|
|
|
#include <wsutil/buffer.h>
|
|
|
|
#include "wsutil/tempfile.h"
|
|
|
|
#include "wsutil/os_version_info.h"
|
|
|
|
#include "wsutil/str_util.h"
|
2018-11-15 13:34:05 +00:00
|
|
|
#include <wsutil/inet_addr.h>
|
2021-05-23 23:46:43 +00:00
|
|
|
#include <wsutil/ws_assert.h>
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
#include "nettrace_3gpp_32_423.h"
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* String constants sought in the XML data.
|
|
|
|
* Written as strings instead of lists of chars for readability.
|
|
|
|
* Use the CLEN() macro to get the length of the constant without counting
|
|
|
|
* the null byte at the end.
|
|
|
|
*/
|
|
|
|
#define CLEN(x) (sizeof(x)-1)
|
|
|
|
static const guchar c_xml_magic[] = "<?xml";
|
|
|
|
static const guchar c_file_header[] = "<fileHeader";
|
|
|
|
static const guchar c_file_format_version[] = "fileFormatVersion=\"";
|
|
|
|
static const guchar c_threegpp_doc_no[] = "32.423";
|
|
|
|
static const guchar c_begin_time[] = "<traceCollec beginTime=\"";
|
|
|
|
static const guchar c_s_msg[] = "<msg";
|
|
|
|
static const guchar c_e_msg[] = "</msg>";
|
|
|
|
static const guchar c_s_rawmsg[] = "<rawMsg";
|
|
|
|
static const guchar c_change_time[] = "changeTime=\"";
|
|
|
|
static const guchar c_proto_name[] = "name=\"";
|
|
|
|
static const guchar c_address[] = "ddress"; /* omit the 'a' to cater for "Address" */
|
|
|
|
static const guchar c_s_initiator[] = "<initiator";
|
|
|
|
static const guchar c_e_initiator[] = "</initiator>";
|
|
|
|
static const guchar c_s_target[] = "<target";
|
|
|
|
static const guchar c_e_target[] = "</target>";
|
|
|
|
static const guchar c_protocol[] = "protocol=\"";
|
|
|
|
|
|
|
|
/* These are protocol names we may put in the exported-pdu data based on
|
|
|
|
* what's in the XML. They're defined here as constants so we can use
|
|
|
|
* sizeof()/CLEN() on them and slightly reduce our use of magic constants
|
|
|
|
* for their size. (Modern compilers should make this no slower than that.)
|
|
|
|
*/
|
|
|
|
static const guchar c_sai_req[] = "gsm_map.v3.arg.opcode";
|
|
|
|
static const guchar c_sai_rsp[] = "gsm_map.v3.res.opcode";
|
|
|
|
static const guchar c_nas_eps[] = "nas-eps_plain";
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
#define RINGBUFFER_START_SIZE G_MAXINT
|
|
|
|
#define RINGBUFFER_CHUNK_SIZE 1024
|
|
|
|
|
|
|
|
#define MAX_NAME_LEN 64
|
|
|
|
#define MAX_PROTO_LEN 16
|
|
|
|
#define MAX_DTBL_LEN 32
|
|
|
|
|
|
|
|
/* We expect to find all the info we need to tell if this file is ours
|
|
|
|
* within this many bytes. Must include the beginTime attribute.
|
|
|
|
*/
|
|
|
|
#define MAGIC_BUF_SIZE 1024
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
typedef struct nettrace_3gpp_32_423_file_info {
|
2021-01-04 15:20:27 +00:00
|
|
|
GByteArray *buffer; // holds current chunk of file
|
|
|
|
gint64 start_offset; // where in the file the start of the buffer points
|
|
|
|
nstime_t start_time; // from <traceCollec beginTime=""> attribute
|
2015-04-29 07:19:08 +00:00
|
|
|
} nettrace_3gpp_32_423_file_info_t;
|
|
|
|
|
2015-10-22 11:55:47 +00:00
|
|
|
|
|
|
|
typedef struct exported_pdu_info {
|
2021-01-04 15:20:27 +00:00
|
|
|
guint32 presence_flags;
|
2018-11-15 13:34:05 +00:00
|
|
|
guint8 src_ip[16];
|
2017-10-29 16:38:41 +00:00
|
|
|
guint32 ptype; /* Based on epan/address.h port_type valid for both src and dst*/
|
2015-10-22 11:55:47 +00:00
|
|
|
guint32 src_port;
|
2018-11-15 13:34:05 +00:00
|
|
|
guint8 dst_ip[16];
|
2015-10-22 11:55:47 +00:00
|
|
|
guint32 dst_port;
|
2016-03-30 15:13:46 +00:00
|
|
|
char* proto_col_str;
|
2021-01-04 15:20:27 +00:00
|
|
|
} exported_pdu_info_t;
|
|
|
|
|
|
|
|
/* flags for exported_pdu_info.presence_flags */
|
|
|
|
#define EXP_PDU_TAG_IP_SRC_BIT 0x001
|
|
|
|
#define EXP_PDU_TAG_IP_DST_BIT 0x002
|
|
|
|
#define EXP_PDU_TAG_SRC_PORT_BIT 0x004
|
|
|
|
#define EXP_PDU_TAG_DST_PORT_BIT 0x008
|
|
|
|
#define EXP_PDU_TAG_ORIG_FNO_BIT 0x010
|
|
|
|
#define EXP_PDU_TAG_SS7_OPC_BIT 0x020
|
|
|
|
#define EXP_PDU_TAG_SS7_DPC_BIT 0x040
|
|
|
|
#define EXP_PDU_TAG_IP6_SRC_BIT 0x080
|
|
|
|
#define EXP_PDU_TAG_IP6_DST_BIT 0x100
|
|
|
|
#define EXP_PDU_TAG_DVBCI_EVT_BIT 0x0100
|
|
|
|
#define EXP_PDU_TAG_COL_PROT_BIT 0x0200
|
|
|
|
|
|
|
|
|
wiretap: register most built-in file types from its module.
Remove most of the built-in file types from the table in
wiretap/file_access.c and, instead, have the file types register
themselves, using wtap_register_file_type_subtypes().
This reduces the source code changes needed to add a new file type from
three (add the handler, add the file type to the table in file_access.c,
add a #define for the file type in wiretap/wtap.h) to one (add the
handler). (It also requires adding the handler's source file to
wiretap/CMakeLists.txt, but that's required in both cases.)
A few remain because the WTAP_FILE_TYPE_SUBTYPE_ #define is used
elsewhere; that needs to be fixed.
Fix the wiretap/CMakefile.txt file to scan k12text.l, as that now
contains a registration routine. In the process, avoid scanning files
that don't implement a file type and won't ever have a registration
routine.
Add a Lua routine to fetch the total number of file types; we use that
in some code to construct the wtap_filetypes table, which we need to do
in order to continue to have all the values that used to come from the
WTAP_FILE_TYPE_SUBTYPE_ types.
While we're at it, add modelines to a file that lacked them.
2021-02-14 08:34:10 +00:00
|
|
|
static int nettrace_3gpp_32_423_file_type_subtype = -1;
|
|
|
|
|
|
|
|
void register_nettrace_3gpp_32_423(void);
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Parse a string IPv4 or IPv6 address into bytes for exported_pdu_info.
|
|
|
|
* Also parses the port pairs and transport layer type.
|
|
|
|
*/
|
|
|
|
static char*
|
|
|
|
nettrace_parse_address(char* curr_pos, char* next_pos, gboolean is_src_addr, exported_pdu_info_t *exported_pdu_info)
|
|
|
|
{
|
|
|
|
guint port;
|
|
|
|
char transp_str[5];
|
|
|
|
int scan_found;
|
|
|
|
char str[3];
|
|
|
|
char* end_pos, *skip_pos;
|
|
|
|
char ip_addr_str[WS_INET6_ADDRSTRLEN];
|
|
|
|
int str_len;
|
|
|
|
ws_in6_addr ip6_addr;
|
|
|
|
guint32 ip4_addr;
|
|
|
|
gchar tempchar;
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* curr_pos pointing to first char after address */
|
2016-03-30 15:13:46 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Excample from one trace, unsure if it's generic...
|
|
|
|
* {address == 192.168.73.1, port == 5062, transport == Udp}
|
|
|
|
* {address == [2001:1b70:8294:210a::78], port...
|
|
|
|
* {address == 2001:1B70:8294:210A::90, port...
|
|
|
|
* Address=198.142.204.199,Port=2123
|
|
|
|
*/
|
|
|
|
/* Skip whitespace and equalsigns) */
|
|
|
|
for (skip_pos = curr_pos; skip_pos < next_pos &&
|
|
|
|
((tempchar = *skip_pos) == ' ' ||
|
|
|
|
tempchar == '\t' || tempchar == '\r' || tempchar == '\n' || tempchar == '=');
|
|
|
|
skip_pos++);
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = skip_pos;
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(str, curr_pos, 3);
|
2021-01-04 15:20:27 +00:00
|
|
|
/* If we find "" here we have no IP address */
|
|
|
|
if (strcmp(str, "\"\"") == 0) {
|
|
|
|
return next_pos;
|
|
|
|
}
|
|
|
|
str[1] = 0;
|
|
|
|
if (strcmp(str, "[") == 0) {
|
|
|
|
/* Should we check for a digit here?*/
|
|
|
|
end_pos = strstr(curr_pos, "]");
|
2018-11-15 13:34:05 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
}else {
|
|
|
|
/* Should we check for a digit here?*/
|
|
|
|
end_pos = strstr(curr_pos, ",");
|
|
|
|
}
|
|
|
|
if (!end_pos) {
|
|
|
|
return next_pos;
|
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
str_len = (int)(end_pos - curr_pos)+1;
|
|
|
|
if (str_len > WS_INET6_ADDRSTRLEN) {
|
|
|
|
return next_pos;
|
|
|
|
}
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(ip_addr_str, curr_pos, str_len);
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = end_pos;
|
|
|
|
if (ws_inet_pton6(ip_addr_str, &ip6_addr)) {
|
|
|
|
if (is_src_addr) {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_IP6_SRC_BIT;
|
|
|
|
memcpy(exported_pdu_info->src_ip, ip6_addr.bytes, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_IP6_DST_BIT;
|
|
|
|
memcpy(exported_pdu_info->dst_ip, ip6_addr.bytes, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ws_inet_pton4(ip_addr_str, &ip4_addr)) {
|
|
|
|
if (is_src_addr) {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_IP_SRC_BIT;
|
|
|
|
memcpy(exported_pdu_info->src_ip, &ip4_addr, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_IP_DST_BIT;
|
|
|
|
memcpy(exported_pdu_info->dst_ip, &ip4_addr, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
}
|
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos++;
|
|
|
|
scan_found = sscanf(curr_pos, ", %*s %*s %5u, %*s %*s %4s", &port, transp_str);
|
|
|
|
if (scan_found == 2) {
|
|
|
|
/* Only add port_type once */
|
2021-08-20 09:17:14 +00:00
|
|
|
if (exported_pdu_info->ptype == EXP_PDU_PT_NONE) {
|
2021-01-04 15:20:27 +00:00
|
|
|
if (g_ascii_strncasecmp(transp_str, "udp", 3) == 0) {
|
2021-08-20 09:17:14 +00:00
|
|
|
exported_pdu_info->ptype = EXP_PDU_PT_UDP;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
else if (g_ascii_strncasecmp(transp_str, "tcp", 3) == 0) {
|
2021-08-20 09:17:14 +00:00
|
|
|
exported_pdu_info->ptype = EXP_PDU_PT_TCP;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
else if (g_ascii_strncasecmp(transp_str, "sctp", 4) == 0) {
|
2021-08-20 09:17:14 +00:00
|
|
|
exported_pdu_info->ptype = EXP_PDU_PT_SCTP;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_src_addr) {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_SRC_PORT_BIT;
|
|
|
|
exported_pdu_info->src_port = port;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
exported_pdu_info->presence_flags |= EXP_PDU_TAG_DST_PORT_BIT;
|
|
|
|
exported_pdu_info->dst_port = port;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return next_pos;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Parse a <msg ...><rawMsg ...>XXXX</rawMsg></msg> into packet data. */
|
|
|
|
static gboolean
|
|
|
|
nettrace_msg_to_packet(nettrace_3gpp_32_423_file_info_t *file_info, wtap_rec *rec, Buffer *buf, guint8 *input, gsize len, int *err, gchar **err_info)
|
2015-04-29 07:19:08 +00:00
|
|
|
{
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Convenience macro. haystack must be >= input! */
|
|
|
|
#define STRNSTR(haystack, needle) g_strstr_len(haystack, (len - ((guint8*)(haystack) - (guint8*)input)), needle)
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
gboolean status = TRUE;
|
|
|
|
char *curr_pos, *next_msg_pos, *next_pos, *prev_pos;
|
|
|
|
exported_pdu_info_t exported_pdu_info = {0};
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
char* raw_msg_pos;
|
|
|
|
char* start_msg_tag_cont;
|
|
|
|
char name_str[MAX_NAME_LEN+1];
|
|
|
|
char proto_name_str[MAX_PROTO_LEN+1];
|
|
|
|
char dissector_table_str[MAX_DTBL_LEN+1];
|
|
|
|
int dissector_table_val = 0;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
int name_str_len = 0;
|
|
|
|
int tag_str_len = 0;
|
|
|
|
int proto_str_len, dissector_table_str_len, raw_data_len, pkt_data_len, exp_pdu_tags_len, i, j;
|
|
|
|
guint8 *packet_buf;
|
|
|
|
gint val1, val2;
|
|
|
|
gboolean port_type_defined = FALSE;
|
|
|
|
gboolean use_proto_table = FALSE;
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* We should always and only be called with a <msg....</msg> payload */
|
|
|
|
if (0 != strncmp(input, c_s_msg, CLEN(c_s_msg))) {
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Did not start with \"%s\"", c_s_msg);
|
2021-01-04 15:20:27 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2021-07-25 16:32:27 +00:00
|
|
|
|
2021-09-05 12:57:57 +00:00
|
|
|
curr_pos = input + CLEN(c_s_msg);
|
2015-11-26 08:02:12 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
rec->rec_type = REC_TYPE_PACKET;
|
2021-08-30 02:12:13 +00:00
|
|
|
rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
|
2021-01-04 15:20:27 +00:00
|
|
|
rec->presence_flags = 0; /* start out assuming no special features */
|
|
|
|
rec->ts.secs = 0;
|
|
|
|
rec->ts.nsecs = 0;
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Clear for each iteration */
|
|
|
|
exported_pdu_info.presence_flags = 0;
|
2021-08-20 09:17:14 +00:00
|
|
|
exported_pdu_info.ptype = EXP_PDU_PT_NONE;
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
prev_pos = curr_pos = curr_pos + 4;
|
|
|
|
/* Look for the end of the tag first */
|
|
|
|
next_msg_pos = STRNSTR(curr_pos, ">");
|
|
|
|
if (!next_msg_pos) {
|
|
|
|
/* Something's wrong, bail out */
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
|
|
|
*err_info = g_strdup("Did not find end of tag \">\"");
|
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
/* Check if its a tag close "/>" */
|
|
|
|
if (*(next_msg_pos - 1) == '/') {
|
|
|
|
/* There is no rawmsg here. Should have been caught before we got called */
|
|
|
|
*err = WTAP_ERR_INTERNAL;
|
|
|
|
*err_info = g_strdup("Had \"<msg />\" with no \"<rawMsg>\"");
|
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
start_msg_tag_cont = curr_pos = prev_pos;
|
|
|
|
next_msg_pos = STRNSTR(curr_pos, c_e_msg);
|
|
|
|
if (!next_msg_pos) {
|
|
|
|
/* Something's wrong, bail out */
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Did not find \"%s\"", c_e_msg);
|
2021-01-04 15:20:27 +00:00
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
2020-10-28 21:27:19 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Check if we have a time stamp "changeTime"
|
|
|
|
* expressed in number of seconds and milliseconds (nbsec.ms).
|
|
|
|
* Only needed if we have a "beginTime" for this file.
|
|
|
|
*/
|
|
|
|
if (!nstime_is_unset(&(file_info->start_time))) {
|
|
|
|
int scan_found;
|
|
|
|
guint second = 0, ms = 0;
|
2020-10-28 21:27:19 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = STRNSTR(start_msg_tag_cont, c_change_time);
|
|
|
|
/* Check if we have the tag or if we passed the end of the current message */
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
curr_pos += CLEN(c_change_time);
|
|
|
|
scan_found = sscanf(curr_pos, "%u.%u", &second, &ms);
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (scan_found == 2) {
|
|
|
|
guint start_ms = file_info->start_time.nsecs / 1000000;
|
|
|
|
guint elapsed_ms = start_ms + ms;
|
|
|
|
if (elapsed_ms > 1000) {
|
|
|
|
elapsed_ms -= 1000;
|
|
|
|
second++;
|
2020-10-28 21:27:19 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
rec->presence_flags |= WTAP_HAS_TS;
|
|
|
|
rec->ts.secs = file_info->start_time.secs + second;
|
|
|
|
rec->ts.nsecs = file_info->start_time.nsecs + (elapsed_ms * 1000000);
|
2020-10-28 21:27:19 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
2015-10-22 11:55:47 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* See if we have a "name" */
|
2021-07-25 20:34:11 +00:00
|
|
|
name_str[0] = '\0'; /* if we don't have a name */
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = STRNSTR(start_msg_tag_cont, c_proto_name);
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
/* extract the name */
|
|
|
|
curr_pos += CLEN(c_proto_name);
|
|
|
|
next_pos = STRNSTR(curr_pos, "\"");
|
|
|
|
name_str_len = (int)(next_pos - curr_pos);
|
|
|
|
if (name_str_len > MAX_NAME_LEN) {
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: name_str_len > %d", MAX_NAME_LEN);
|
2021-01-04 15:20:27 +00:00
|
|
|
goto end;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
2020-10-28 21:27:19 +00:00
|
|
|
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(name_str, curr_pos, (gsize)name_str_len + 1);
|
2021-01-04 15:20:27 +00:00
|
|
|
ascii_strdown_inplace(name_str);
|
|
|
|
|
|
|
|
}
|
|
|
|
/* Check if we have "<initiator>"
|
|
|
|
* It might contain an address
|
|
|
|
*/
|
|
|
|
curr_pos = STRNSTR(start_msg_tag_cont, c_s_initiator);
|
|
|
|
/* Check if we have the tag or if we passed the end of the current message */
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
curr_pos += CLEN(c_s_initiator);
|
|
|
|
next_pos = STRNSTR(curr_pos, c_e_initiator);
|
|
|
|
/* Find address */
|
|
|
|
curr_pos = STRNSTR(curr_pos, c_address);
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
curr_pos += CLEN(c_address);
|
|
|
|
nettrace_parse_address(curr_pos, next_pos, TRUE/* SRC */, &exported_pdu_info);
|
|
|
|
}
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Check if we have "<target>"
|
|
|
|
* It might contain an address
|
|
|
|
*/
|
|
|
|
curr_pos = STRNSTR(start_msg_tag_cont, c_s_target);
|
|
|
|
/* Check if we have the tag or if we passed the end of the current message */
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
curr_pos += CLEN(c_s_target);
|
|
|
|
curr_pos = curr_pos + 7;
|
|
|
|
next_pos = STRNSTR(curr_pos, c_e_target);
|
|
|
|
/* Find address */
|
|
|
|
curr_pos = STRNSTR(curr_pos, c_address);
|
|
|
|
if (curr_pos != NULL) {
|
|
|
|
curr_pos += CLEN(c_address);
|
|
|
|
/* curr_pos set below */
|
|
|
|
nettrace_parse_address(curr_pos, next_pos, FALSE/* DST */, &exported_pdu_info);
|
|
|
|
}
|
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Do we have a raw message in the <msg> </msg> section? */
|
|
|
|
raw_msg_pos = STRNSTR(start_msg_tag_cont, c_s_rawmsg);
|
|
|
|
if (raw_msg_pos == NULL) {
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Did not find \"%s\"", c_s_rawmsg);
|
2021-01-04 15:20:27 +00:00
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
curr_pos = STRNSTR(raw_msg_pos, c_protocol);
|
|
|
|
if (curr_pos == NULL) {
|
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Did not find \"%s\"", c_protocol);
|
2021-01-04 15:20:27 +00:00
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos += CLEN(c_protocol);
|
|
|
|
next_pos = STRNSTR(curr_pos, "\"");
|
2015-04-29 07:19:08 +00:00
|
|
|
proto_str_len = (int)(next_pos - curr_pos);
|
2021-01-04 15:20:27 +00:00
|
|
|
if (proto_str_len > MAX_PROTO_LEN){
|
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(proto_name_str, curr_pos, (gsize)proto_str_len+1);
|
2015-04-29 07:19:08 +00:00
|
|
|
ascii_strdown_inplace(proto_name_str);
|
|
|
|
|
|
|
|
/* Do string matching and replace with Wiresharks protocol name */
|
2021-01-04 15:20:27 +00:00
|
|
|
if (strcmp(proto_name_str, "gtpv2-c") == 0) {
|
2015-04-29 07:19:08 +00:00
|
|
|
/* Change to gtpv2 */
|
|
|
|
proto_name_str[5] = '\0';
|
|
|
|
proto_str_len = 5;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
/* XXX Do we need to check for function="S1"? */
|
|
|
|
if (strcmp(proto_name_str, "nas") == 0) {
|
2015-04-29 07:19:08 +00:00
|
|
|
/* Change to nas-eps_plain */
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(proto_name_str, c_nas_eps, sizeof(c_nas_eps));
|
2021-01-04 15:20:27 +00:00
|
|
|
proto_str_len = CLEN(c_nas_eps);
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2016-03-30 15:13:46 +00:00
|
|
|
if (strcmp(proto_name_str, "map") == 0) {
|
2021-01-04 15:20:27 +00:00
|
|
|
/* For GSM map, it looks like the message data is stored like SendAuthenticationInfoArg
|
2016-03-30 15:13:46 +00:00
|
|
|
* use the GSM MAP dissector table to dissect the content.
|
|
|
|
*/
|
2021-01-04 15:20:27 +00:00
|
|
|
exported_pdu_info.proto_col_str = g_strdup("GSM MAP");
|
2016-03-30 15:13:46 +00:00
|
|
|
|
|
|
|
if (strcmp(name_str, "sai_request") == 0) {
|
|
|
|
use_proto_table = TRUE;
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(dissector_table_str, c_sai_req, sizeof(c_sai_req));
|
2021-01-04 15:20:27 +00:00
|
|
|
dissector_table_str_len = CLEN(c_sai_req);
|
2016-03-30 15:13:46 +00:00
|
|
|
dissector_table_val = 56;
|
2021-01-04 15:20:27 +00:00
|
|
|
exported_pdu_info.presence_flags |= EXP_PDU_TAG_COL_PROT_BIT;
|
2016-03-30 15:13:46 +00:00
|
|
|
}
|
|
|
|
else if (strcmp(name_str, "sai_response") == 0) {
|
|
|
|
use_proto_table = TRUE;
|
2021-04-30 10:18:25 +00:00
|
|
|
(void) g_strlcpy(dissector_table_str, c_sai_rsp, sizeof(c_sai_rsp));
|
2021-01-04 15:20:27 +00:00
|
|
|
dissector_table_str_len = CLEN(c_sai_rsp);
|
2016-03-30 15:13:46 +00:00
|
|
|
dissector_table_val = 56;
|
2021-01-04 15:20:27 +00:00
|
|
|
exported_pdu_info.presence_flags |= EXP_PDU_TAG_COL_PROT_BIT;
|
2018-05-04 22:46:20 +00:00
|
|
|
} else {
|
2021-01-04 15:20:27 +00:00
|
|
|
g_free(exported_pdu_info.proto_col_str);
|
|
|
|
exported_pdu_info.proto_col_str = NULL;
|
2016-03-30 15:13:46 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Find the start of the raw data */
|
|
|
|
curr_pos = STRNSTR(next_pos, ">") + 1;
|
|
|
|
next_pos = STRNSTR(curr_pos, "<");
|
2015-04-29 07:19:08 +00:00
|
|
|
raw_data_len = (int)(next_pos - curr_pos);
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Calculate the space needed for exp pdu tags */
|
2016-03-30 15:13:46 +00:00
|
|
|
if (use_proto_table == FALSE) {
|
|
|
|
tag_str_len = (proto_str_len + 3) & 0xfffffffc;
|
|
|
|
exp_pdu_tags_len = tag_str_len + 4;
|
|
|
|
} else {
|
|
|
|
tag_str_len = (dissector_table_str_len + 3) & 0xfffffffc;
|
|
|
|
exp_pdu_tags_len = tag_str_len + 4;
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Add EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL + length */
|
|
|
|
exp_pdu_tags_len += 4 + 4;
|
2016-03-30 15:13:46 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_COL_PROT_BIT) {
|
2018-05-09 10:21:37 +00:00
|
|
|
/* The assert prevents static code analyzers to raise warnings */
|
2021-05-23 23:46:43 +00:00
|
|
|
ws_assert(exported_pdu_info.proto_col_str);
|
2021-01-04 15:20:27 +00:00
|
|
|
exp_pdu_tags_len += 4 + (int)strlen(exported_pdu_info.proto_col_str);
|
2016-03-30 15:13:46 +00:00
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP_SRC_BIT) {
|
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_IPV4_LEN;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
2018-11-15 13:34:05 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP6_SRC_BIT) {
|
2018-11-15 13:34:05 +00:00
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_IPV6_LEN;
|
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_SRC_PORT_BIT) {
|
2015-10-22 11:55:47 +00:00
|
|
|
if (!port_type_defined) {
|
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_PORT_TYPE_LEN;
|
|
|
|
port_type_defined = TRUE;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_PORT_LEN;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP_DST_BIT) {
|
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_IPV4_LEN;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP6_DST_BIT) {
|
2018-11-15 13:34:05 +00:00
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_IPV6_LEN;
|
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_DST_PORT_BIT) {
|
2015-10-22 11:55:47 +00:00
|
|
|
if (!port_type_defined) {
|
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_PORT_TYPE_LEN;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
exp_pdu_tags_len += 4 + EXP_PDU_TAG_PORT_LEN;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
exp_pdu_tags_len += 4; /* account for opt_endofopt */
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
/* Allocate the packet buf */
|
|
|
|
pkt_data_len = raw_data_len / 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
ws_buffer_assure_space(buf, (gsize)pkt_data_len + (gsize)exp_pdu_tags_len);
|
|
|
|
ws_buffer_increase_length(buf, (gsize)pkt_data_len + (gsize)exp_pdu_tags_len);
|
|
|
|
packet_buf = ws_buffer_start_ptr(buf);
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
/* Fill packet buff */
|
2016-03-30 15:13:46 +00:00
|
|
|
if (use_proto_table == FALSE) {
|
Dissector names are not protocol names.
A given protocol's packet format may depend, for example, on which
lower-level protocol is transporting the protocol in question. For
example, protocols that run atop both byte-stream protocols such as TCP
and TLS, and packet-oriented protocols such as UDP or DTLS, might begin
the packet with a length when running atop a byte-stream protocol, to
indicate where this packet ends and the next packet begins in the byte
stream, but not do so when running atop a packet-oriented protocol.
Dissectors can handle this in various ways:
For example, the dissector could attempt to determine the protocol over
which the packet was transported.
Unfortunately, many of those mechanisms do so by fetching data from the
packet_info structure, and many items in that structure act as global
variables, so that, for example, if there are two two PDUs for protocol
A inside a TCP segment, and the first protocol for PDU A contains a PDU
for protocol B, and protocol B's dissector, or a dissector it calls,
modifies the information in the packet_info structure so that it no
longer indicates that the parent protocol is TCP, the second PDU for
protocol A might not be correctly dissected.
Another such mechanism is to query the previous element in the layers
structure of the packet_info structure, which is a list of protocol IDs.
Unfortunately, that is not a list of earlier protocols in the protocol
stack, it's a list of earlier protocols in the dissection, which means
that, in the above example, when the second PDU for protocol A is
dissected, the list is {...,TCP,A,B,...,A}, which means that the
previous element in the list is not TCP, so, again, the second PDU for
protocol A will not be correctly dissected.
An alternative is to have multiple dissectors for the same protocol,
with the part of the protocol that's independent of the protocol
transporting the PDU being dissected by common code. Protocol B might
have an "over a byte-stream transport" dissector and an "over a packet
transport" dissector, with the first dissector being registered for use
over TCP and TLS and the other dissector being registered for use over
packet protocols. This mechanism, unlike the other mechanisms, is not
dependent on information in the packet_info structure that might be
affected by dissectors other than the one for the protocol that
transports protocol B.
Furthermore, in a LINKTYPE_WIRESHARK_UPPER_PDU pcap or pcapng packet for
protocol B, there might not be any information to indicate the protocol
that transports protocol B, so there would have to be separate
dissectors for protocol B, with separate names, so that a tag giving the
protocol name would differ for B-over-byte-stream and B-over-packets.
So:
We rename EXP_PDU_TAG_PROTO_NAME and EXP_PDU_TAG_HEUR_PROTO_NAME to
EXP_PDU_TAG_DISSECTOR_NAME and EXP_PDU_TAG_HEUR_DISSECTOR_NAME, to
emphasize that they are *not* protocol names, they are dissector names
(which has always been the case - if there's a protocol with that name,
but no dissector with that name, Wireshark will not be able to handle
the packet, as it will try to look up a dissector given that name and
fail).
We fix that exported PDU dissector to refer to those tags as dissector
names, not protocol names.
We update documentation to refer to them as DISSECTOR_NAME tags, not
PROTO_NAME tags. (If there is any documentation for this outside the
Wireshark source, it should be updated as well.)
We add comments for calls to dissector_handle_get_dissector_name() where
the dissector name is shown to the user, to indicate that it might be
that the protocol name should be used.
We update the TLS and DTLS dissectors to show the encapsulated protocol
as the string returned by dissector_handle_get_long_name(); as the
default is "Application Data", it appeaers that a descriptive name,
rather than a short API name, should be used. (We continue to use the
dissector name in debugging messages, to indicate which dissector was
called.)
2022-09-11 05:37:11 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_DISSECTOR_NAME);
|
2021-08-20 07:35:33 +00:00
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, tag_str_len);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memset(packet_buf, 0, tag_str_len);
|
|
|
|
memcpy(packet_buf, proto_name_str, proto_str_len);
|
|
|
|
packet_buf += tag_str_len;
|
|
|
|
}
|
|
|
|
else {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_DISSECTOR_TABLE_NAME);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, tag_str_len);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memset(packet_buf, 0, tag_str_len);
|
|
|
|
memcpy(packet_buf, dissector_table_str, dissector_table_str_len);
|
|
|
|
packet_buf += tag_str_len;
|
|
|
|
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, 4); /* option length */
|
|
|
|
packet_buf += 2;
|
|
|
|
phton32(packet_buf, dissector_table_val);
|
|
|
|
packet_buf += 4;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_COL_PROT_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_COL_PROT_TEXT);
|
|
|
|
packet_buf += 2;
|
|
|
|
/* XXX - what if it's longer than 65535 bytes? */
|
|
|
|
phton16(packet_buf, (guint16)strlen(exported_pdu_info.proto_col_str));
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
for (j = 0; j < (int)strlen(exported_pdu_info.proto_col_str); j++) {
|
|
|
|
*packet_buf++ = exported_pdu_info.proto_col_str[j];
|
|
|
|
}
|
|
|
|
g_free(exported_pdu_info.proto_col_str);
|
|
|
|
exported_pdu_info.proto_col_str = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP_SRC_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV4_SRC);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memcpy(packet_buf, exported_pdu_info.src_ip, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
packet_buf += EXP_PDU_TAG_IPV4_LEN;
|
|
|
|
}
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP_DST_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV4_DST);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memcpy(packet_buf, exported_pdu_info.dst_ip, EXP_PDU_TAG_IPV4_LEN);
|
|
|
|
packet_buf += EXP_PDU_TAG_IPV4_LEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP6_SRC_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV6_SRC);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memcpy(packet_buf, exported_pdu_info.src_ip, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
packet_buf += EXP_PDU_TAG_IPV6_LEN;
|
|
|
|
}
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_IP6_DST_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV6_DST);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
packet_buf += 2;
|
2021-01-04 15:20:27 +00:00
|
|
|
memcpy(packet_buf, exported_pdu_info.dst_ip, EXP_PDU_TAG_IPV6_LEN);
|
|
|
|
packet_buf += EXP_PDU_TAG_IPV6_LEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exported_pdu_info.presence_flags & (EXP_PDU_TAG_SRC_PORT_BIT | EXP_PDU_TAG_DST_PORT_BIT)) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_PORT_TYPE);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_PORT_TYPE_LEN);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton32(packet_buf, exported_pdu_info.ptype);
|
|
|
|
packet_buf += 4;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_SRC_PORT_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_SRC_PORT);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_PORT_LEN);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton32(packet_buf, exported_pdu_info.src_port);
|
|
|
|
packet_buf += 4;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
if (exported_pdu_info.presence_flags & EXP_PDU_TAG_DST_PORT_BIT) {
|
2021-08-20 07:35:33 +00:00
|
|
|
phton16(packet_buf, EXP_PDU_TAG_DST_PORT);
|
|
|
|
packet_buf += 2;
|
|
|
|
phton16(packet_buf, EXP_PDU_TAG_PORT_LEN);
|
|
|
|
packet_buf += 4;
|
|
|
|
phton32(packet_buf, exported_pdu_info.dst_port);
|
|
|
|
packet_buf += 4;
|
2015-10-22 11:55:47 +00:00
|
|
|
}
|
|
|
|
|
2015-04-29 07:19:08 +00:00
|
|
|
/* Add end of options */
|
2021-01-04 15:20:27 +00:00
|
|
|
*packet_buf++ = 0;
|
|
|
|
*packet_buf++ = 0;
|
|
|
|
*packet_buf++ = 0;
|
|
|
|
*packet_buf++ = 0;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
/* Convert the hex raw msg data to binary and write to the packet buf*/
|
2021-01-04 15:20:27 +00:00
|
|
|
for (i = 0; i < pkt_data_len; i++) {
|
2019-01-11 13:13:25 +00:00
|
|
|
gchar chr1, chr2;
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
chr1 = *curr_pos++;
|
|
|
|
chr2 = *curr_pos++;
|
2019-01-11 13:13:25 +00:00
|
|
|
val1 = g_ascii_xdigit_value(chr1);
|
|
|
|
val2 = g_ascii_xdigit_value(chr2);
|
2021-01-04 15:20:27 +00:00
|
|
|
if ((val1 != -1) && (val2 != -1)) {
|
|
|
|
*packet_buf++ = ((guint8)val1 * 16) + val2;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
else {
|
2015-04-29 07:19:08 +00:00
|
|
|
/* Something wrong, bail out */
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Could not parse hex data, bufsize %u index %u %c%c",
|
2019-01-11 13:13:25 +00:00
|
|
|
(pkt_data_len + exp_pdu_tags_len),
|
|
|
|
i,
|
|
|
|
chr1,
|
|
|
|
chr2);
|
2018-09-24 12:43:10 +00:00
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2021-01-04 15:20:27 +00:00
|
|
|
status = FALSE;
|
|
|
|
goto end;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2015-10-20 13:47:40 +00:00
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2018-02-09 00:19:12 +00:00
|
|
|
rec->rec_header.packet_header.caplen = pkt_data_len + exp_pdu_tags_len;
|
|
|
|
rec->rec_header.packet_header.len = pkt_data_len + exp_pdu_tags_len;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
end:
|
|
|
|
return status;
|
|
|
|
#undef STRNSTR
|
|
|
|
}
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Read from fh and store into buffer, until buffer contains needle.
|
|
|
|
* Returns location of needle once found, or NULL if it's never found
|
|
|
|
* (due to either EOF or read error).
|
|
|
|
*/
|
|
|
|
static guint8 *
|
|
|
|
read_until(GByteArray *buffer, const guchar *needle, FILE_T fh, int *err, gchar **err_info)
|
|
|
|
{
|
|
|
|
guint8 read_buffer[RINGBUFFER_CHUNK_SIZE];
|
|
|
|
guint8 *found_it;
|
|
|
|
gint bytes_read = 0;
|
|
|
|
|
|
|
|
while (NULL == (found_it = g_strstr_len(buffer->data, buffer->len, needle))) {
|
|
|
|
bytes_read = file_read(read_buffer, RINGBUFFER_CHUNK_SIZE, fh);
|
|
|
|
if (bytes_read < 0) {
|
|
|
|
*err = file_error(fh, err_info);
|
2015-04-29 07:19:08 +00:00
|
|
|
break;
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
|
|
|
if (bytes_read == 0) {
|
2015-04-29 07:19:08 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
g_byte_array_append(buffer, read_buffer, bytes_read);
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
return found_it;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Find a complete packet, parse and return it to wiretap.
|
|
|
|
* Set as the subtype_read function in the file_open function below.
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
nettrace_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info, gint64 *data_offset)
|
2018-11-19 14:35:06 +00:00
|
|
|
{
|
2021-01-04 15:20:27 +00:00
|
|
|
nettrace_3gpp_32_423_file_info_t *file_info = (nettrace_3gpp_32_423_file_info_t *)wth->priv;
|
|
|
|
guint8 *buf_start;
|
|
|
|
guint8 *msg_start, *msg_end;
|
|
|
|
guint msg_offset = 0;
|
|
|
|
gsize msg_len = 0;
|
|
|
|
gboolean status = FALSE;
|
|
|
|
|
|
|
|
/* Make sure we have a start and end of message in our buffer -- end first */
|
|
|
|
msg_end = read_until(file_info->buffer, c_e_msg, wth->fh, err, err_info);
|
|
|
|
if (msg_end == NULL) {
|
|
|
|
goto end;
|
|
|
|
}
|
2018-11-19 14:35:06 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
buf_start = file_info->buffer->data;
|
|
|
|
/* Now search backwards for the message start
|
|
|
|
* (doing it this way should skip over any empty "<msg ... />" tags we have)
|
2018-11-19 14:35:06 +00:00
|
|
|
*/
|
2021-01-04 15:20:27 +00:00
|
|
|
msg_start = g_strrstr_len(buf_start, (guint)(msg_end - buf_start), c_s_msg);
|
|
|
|
if (msg_start == NULL || msg_start > msg_end) {
|
2021-12-18 18:48:20 +00:00
|
|
|
*err_info = ws_strdup_printf("nettrace_3gpp_32_423: Found \"%s\" without matching \"%s\"", c_e_msg, c_s_msg);
|
2021-01-04 15:20:27 +00:00
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
|
|
|
goto end;
|
|
|
|
}
|
2020-02-28 12:48:45 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* We know we have a message, what's its offset from the buffer start? */
|
|
|
|
msg_offset = (guint)(msg_start - buf_start);
|
|
|
|
msg_end += CLEN(c_e_msg);
|
|
|
|
msg_len = (guint)(msg_end - msg_start);
|
2020-02-28 12:48:45 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Tell Wireshark to put us at the start of the "<msg" for seek_read later */
|
|
|
|
*data_offset = file_info->start_offset + msg_offset;
|
2018-11-19 14:35:06 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* pass all of <msg....</msg> to nettrace_msg_to_packet() */
|
|
|
|
status = nettrace_msg_to_packet(file_info, rec, buf, msg_start, msg_len, err, err_info);
|
2018-11-19 14:35:06 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Finally, shift our buffer to the end of this message to get ready for the next one.
|
|
|
|
* Re-use msg_len to get the length of the data we're done with.
|
|
|
|
*/
|
|
|
|
msg_len = msg_end - file_info->buffer->data;
|
|
|
|
while (G_UNLIKELY(msg_len > G_MAXUINT)) {
|
|
|
|
g_byte_array_remove_range(file_info->buffer, 0, G_MAXUINT);
|
|
|
|
msg_len -= G_MAXUINT;
|
2018-11-19 14:35:06 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
g_byte_array_remove_range(file_info->buffer, 0, (guint)msg_len);
|
|
|
|
file_info->start_offset += msg_len;
|
2018-11-19 14:35:06 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
end:
|
|
|
|
if (status == FALSE) {
|
|
|
|
/* There's no more to read. Empty out the buffer */
|
|
|
|
g_byte_array_set_size(file_info->buffer, 0);
|
2018-11-19 14:35:06 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
|
|
|
|
return status;
|
2018-11-19 14:35:06 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Seek to the complete packet at the offset, parse and return it to wiretap.
|
|
|
|
* Set as the subtype_seek_read function in the file_open function below.
|
2015-04-29 07:19:08 +00:00
|
|
|
*/
|
2021-01-04 15:20:27 +00:00
|
|
|
static gboolean
|
|
|
|
nettrace_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
|
2015-04-29 07:19:08 +00:00
|
|
|
{
|
2021-01-04 15:20:27 +00:00
|
|
|
nettrace_3gpp_32_423_file_info_t *file_info = (nettrace_3gpp_32_423_file_info_t *)wth->priv;
|
|
|
|
gboolean status = FALSE;
|
|
|
|
guint8 *msg_end;
|
|
|
|
guint msg_len = 0;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* We stored the offset of the "<msg" for this packet */
|
|
|
|
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
|
|
|
return FALSE;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
msg_end = read_until(file_info->buffer, c_e_msg, wth->random_fh, err, err_info);
|
|
|
|
if (msg_end == NULL) {
|
|
|
|
return FALSE;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
msg_end += CLEN(c_e_msg);
|
|
|
|
msg_len = (guint)(msg_end - file_info->buffer->data);
|
2016-01-13 04:10:05 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
status = nettrace_msg_to_packet(file_info, rec, buf, file_info->buffer->data, msg_len, err, err_info);
|
|
|
|
g_byte_array_set_size(file_info->buffer, 0);
|
|
|
|
return status;
|
|
|
|
}
|
2015-10-20 13:47:40 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Clean up any memory we allocated for dealing with this file.
|
|
|
|
* Set as the subtype_close function in the file_open function below.
|
|
|
|
* (wiretap frees wth->priv itself)
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
nettrace_close(wtap *wth)
|
|
|
|
{
|
|
|
|
nettrace_3gpp_32_423_file_info_t *file_info = (nettrace_3gpp_32_423_file_info_t *)wth->priv;
|
2015-10-20 13:47:40 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (file_info != NULL && file_info->buffer != NULL) {
|
|
|
|
g_byte_array_free(file_info->buffer, TRUE);
|
|
|
|
file_info->buffer = NULL;
|
2018-11-14 13:24:22 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
}
|
2015-10-20 13:47:40 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Test the current file to see if it's one we can read.
|
|
|
|
* Set in file_access.c as the function to be called for this file type.
|
|
|
|
*/
|
2015-04-29 07:19:08 +00:00
|
|
|
wtap_open_return_val
|
|
|
|
nettrace_3gpp_32_423_file_open(wtap *wth, int *err, gchar **err_info)
|
|
|
|
{
|
2021-01-04 15:20:27 +00:00
|
|
|
char magic_buf[MAGIC_BUF_SIZE+1];
|
2015-04-29 07:19:08 +00:00
|
|
|
int bytes_read;
|
|
|
|
char *curr_pos;
|
|
|
|
nettrace_3gpp_32_423_file_info_t *file_info;
|
2021-01-04 15:20:27 +00:00
|
|
|
gint64 start_offset;
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
start_offset = file_tell(wth->fh); // Most likely 0 but doesn't hurt to check
|
|
|
|
bytes_read = file_read(magic_buf, MAGIC_BUF_SIZE, wth->fh);
|
2015-04-29 07:19:08 +00:00
|
|
|
|
|
|
|
if (bytes_read < 0) {
|
|
|
|
*err = file_error(wth->fh, err_info);
|
|
|
|
return WTAP_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
if (bytes_read == 0){
|
|
|
|
return WTAP_OPEN_NOT_MINE;
|
|
|
|
}
|
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
if (memcmp(magic_buf, c_xml_magic, CLEN(c_xml_magic)) != 0){
|
2015-04-29 07:19:08 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
|
|
|
}
|
2016-01-13 04:10:05 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = g_strstr_len(magic_buf, bytes_read, c_file_header);
|
|
|
|
if (!curr_pos) {
|
2015-04-29 07:19:08 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos = g_strstr_len(curr_pos, bytes_read-(curr_pos-magic_buf), c_file_format_version);
|
|
|
|
if (!curr_pos) {
|
2015-04-29 07:19:08 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
curr_pos += CLEN(c_file_format_version);
|
|
|
|
if (memcmp(curr_pos, c_threegpp_doc_no, CLEN(c_threegpp_doc_no)) != 0){
|
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2015-04-29 07:19:08 +00:00
|
|
|
}
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Next we expect something like <traceCollec beginTime="..."/> */
|
|
|
|
curr_pos = g_strstr_len(curr_pos, bytes_read-(curr_pos-magic_buf), c_begin_time);
|
|
|
|
if (!curr_pos) {
|
|
|
|
return WTAP_OPEN_NOT_MINE;
|
|
|
|
}
|
|
|
|
curr_pos += CLEN(c_begin_time);
|
2015-04-29 07:19:08 +00:00
|
|
|
|
2021-01-04 15:20:27 +00:00
|
|
|
/* Ok it's our file. From here we'll need to free memory */
|
|
|
|
file_info = g_new0(nettrace_3gpp_32_423_file_info_t, 1);
|
2021-11-30 06:04:07 +00:00
|
|
|
curr_pos += iso8601_to_nstime(&file_info->start_time, curr_pos, ISO8601_DATETIME);
|
2021-01-04 15:20:27 +00:00
|
|
|
file_info->start_offset = start_offset + (curr_pos - magic_buf);
|
|
|
|
file_info->buffer = g_byte_array_sized_new(RINGBUFFER_START_SIZE);
|
|
|
|
g_byte_array_append(file_info->buffer, curr_pos, (guint)(bytes_read - (curr_pos - magic_buf)));
|
2015-04-29 07:19:08 +00:00
|
|
|
|
wiretap: register most built-in file types from its module.
Remove most of the built-in file types from the table in
wiretap/file_access.c and, instead, have the file types register
themselves, using wtap_register_file_type_subtypes().
This reduces the source code changes needed to add a new file type from
three (add the handler, add the file type to the table in file_access.c,
add a #define for the file type in wiretap/wtap.h) to one (add the
handler). (It also requires adding the handler's source file to
wiretap/CMakeLists.txt, but that's required in both cases.)
A few remain because the WTAP_FILE_TYPE_SUBTYPE_ #define is used
elsewhere; that needs to be fixed.
Fix the wiretap/CMakefile.txt file to scan k12text.l, as that now
contains a registration routine. In the process, avoid scanning files
that don't implement a file type and won't ever have a registration
routine.
Add a Lua routine to fetch the total number of file types; we use that
in some code to construct the wtap_filetypes table, which we need to do
in order to continue to have all the values that used to come from the
WTAP_FILE_TYPE_SUBTYPE_ types.
While we're at it, add modelines to a file that lacked them.
2021-02-14 08:34:10 +00:00
|
|
|
wth->file_type_subtype = nettrace_3gpp_32_423_file_type_subtype;
|
2021-01-04 15:20:27 +00:00
|
|
|
wth->file_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
|
|
|
|
wth->file_tsprec = WTAP_TSPREC_MSEC;
|
2015-04-29 07:19:08 +00:00
|
|
|
wth->subtype_read = nettrace_read;
|
|
|
|
wth->subtype_seek_read = nettrace_seek_read;
|
|
|
|
wth->subtype_close = nettrace_close;
|
|
|
|
wth->snapshot_length = 0;
|
|
|
|
wth->priv = (void*)file_info;
|
|
|
|
|
|
|
|
return WTAP_OPEN_MINE;
|
|
|
|
}
|
2015-08-09 18:55:27 +00:00
|
|
|
|
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.
2021-02-21 22:18:04 +00:00
|
|
|
static const struct supported_block_type nettrace_3gpp_32_423_blocks_supported[] = {
|
|
|
|
/*
|
|
|
|
* We support packet blocks, with no comments or other options.
|
|
|
|
*/
|
|
|
|
{ WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
|
|
|
|
};
|
|
|
|
|
wiretap: register most built-in file types from its module.
Remove most of the built-in file types from the table in
wiretap/file_access.c and, instead, have the file types register
themselves, using wtap_register_file_type_subtypes().
This reduces the source code changes needed to add a new file type from
three (add the handler, add the file type to the table in file_access.c,
add a #define for the file type in wiretap/wtap.h) to one (add the
handler). (It also requires adding the handler's source file to
wiretap/CMakeLists.txt, but that's required in both cases.)
A few remain because the WTAP_FILE_TYPE_SUBTYPE_ #define is used
elsewhere; that needs to be fixed.
Fix the wiretap/CMakefile.txt file to scan k12text.l, as that now
contains a registration routine. In the process, avoid scanning files
that don't implement a file type and won't ever have a registration
routine.
Add a Lua routine to fetch the total number of file types; we use that
in some code to construct the wtap_filetypes table, which we need to do
in order to continue to have all the values that used to come from the
WTAP_FILE_TYPE_SUBTYPE_ types.
While we're at it, add modelines to a file that lacked them.
2021-02-14 08:34:10 +00:00
|
|
|
static const struct file_type_subtype_info nettrace_3gpp_32_423_info = {
|
|
|
|
"3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
|
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.
2021-02-21 22:18:04 +00:00
|
|
|
FALSE, BLOCKS_SUPPORTED(nettrace_3gpp_32_423_blocks_supported),
|
wiretap: register most built-in file types from its module.
Remove most of the built-in file types from the table in
wiretap/file_access.c and, instead, have the file types register
themselves, using wtap_register_file_type_subtypes().
This reduces the source code changes needed to add a new file type from
three (add the handler, add the file type to the table in file_access.c,
add a #define for the file type in wiretap/wtap.h) to one (add the
handler). (It also requires adding the handler's source file to
wiretap/CMakeLists.txt, but that's required in both cases.)
A few remain because the WTAP_FILE_TYPE_SUBTYPE_ #define is used
elsewhere; that needs to be fixed.
Fix the wiretap/CMakefile.txt file to scan k12text.l, as that now
contains a registration routine. In the process, avoid scanning files
that don't implement a file type and won't ever have a registration
routine.
Add a Lua routine to fetch the total number of file types; we use that
in some code to construct the wtap_filetypes table, which we need to do
in order to continue to have all the values that used to come from the
WTAP_FILE_TYPE_SUBTYPE_ types.
While we're at it, add modelines to a file that lacked them.
2021-02-14 08:34:10 +00:00
|
|
|
NULL, NULL, NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
void register_nettrace_3gpp_32_423(void)
|
|
|
|
{
|
2021-02-24 03:10:35 +00:00
|
|
|
nettrace_3gpp_32_423_file_type_subtype = wtap_register_file_type_subtype(&nettrace_3gpp_32_423_info);
|
wiretap: more work on file type/subtypes.
Provide a wiretap routine to get an array of all savable file
type/subtypes, sorted with pcap and pcapng at the top, followed by the
other types, sorted either by the name or the description.
Use that routine to list options for the -F flag for various commands
Rename wtap_get_savable_file_types_subtypes() to
wtap_get_savable_file_types_subtypes_for_file(), to indicate that it
provides an array of all file type/subtypes in which a given file can be
saved. Have it sort all types, other than the default type/subtype and,
if there is one, the "other" type (both of which are put at the top), by
the name or the description.
Don't allow wtap_register_file_type_subtypes() to override any existing
registrations; have them always register a new type. In that routine,
if there are any emply slots in the table, due to an entry being
unregistered, use it rather than allocating a new slot.
Don't allow unregistration of built-in types.
Rename the "dump open table" to the "file type/subtype table", as it has
entries for all types/subtypes, even if we can't write them.
Initialize that table in a routine that pre-allocates the GArray before
filling it with built-in types/subtypes, so it doesn't keep getting
reallocated.
Get rid of wtap_num_file_types_subtypes - it's just a copy of the size
of the GArray.
Don't have wtap_file_type_subtype_description() crash if handed an
file type/subtype that isn't a valid array index - just return NULL, as
we do with wtap_file_type_subtype_name().
In wtap_name_to_file_type_subtype(), don't use WTAP_FILE_TYPE_SUBTYPE_
names for the backwards-compatibility names - map those names to the
current names, and then look them up. This reduces the number of
uses of hardwired WTAP_FILE_TYPE_SUBTYPE_ values.
Clean up the type of wtap_module_count - it has no need to be a gulong.
Have built-in wiretap file handlers register names to be used for their
file type/subtypes, rather than building the table in init.lua.
Add a new Lua C function get_wtap_filetypes() to construct the
wtap_filetypes table, based on the registered names, and use it in
init.lua.
Add a #define WSLUA_INTERNAL_FUNCTION to register functions intended
only for internal use in init.lua, so they can be made available from
Lua without being documented.
Get rid of WTAP_NUM_FILE_TYPES_SUBTYPES - most code has no need to use
it, as it can just request arrays of types, and the space of
type/subtype codes can be sparse due to registration in any case, so
code has to be careful using it.
wtap_get_num_file_types_subtypes() is no longer used, so remove it. It
returns the number of elements in the file type/subtype array, which is
not necessarily the name of known file type/subtypes, as there may have
been some deregistered types, and those types do *not* get removed from
the array, they just get cleared so that they're available for future
allocation (we don't want the indices of any registered types to changes
if another type is deregistered, as those indicates are the type/subtype
values, so we can't shrink the array).
Clean up white space and remove some comments that shouldn't have been
added.
2021-02-17 06:24:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Register name for backwards compatibility with the
|
|
|
|
* wtap_filetypes table in Lua.
|
|
|
|
*/
|
|
|
|
wtap_register_backwards_compatibility_lua_name("NETTRACE_3GPP_32_423",
|
|
|
|
nettrace_3gpp_32_423_file_type_subtype);
|
wiretap: register most built-in file types from its module.
Remove most of the built-in file types from the table in
wiretap/file_access.c and, instead, have the file types register
themselves, using wtap_register_file_type_subtypes().
This reduces the source code changes needed to add a new file type from
three (add the handler, add the file type to the table in file_access.c,
add a #define for the file type in wiretap/wtap.h) to one (add the
handler). (It also requires adding the handler's source file to
wiretap/CMakeLists.txt, but that's required in both cases.)
A few remain because the WTAP_FILE_TYPE_SUBTYPE_ #define is used
elsewhere; that needs to be fixed.
Fix the wiretap/CMakefile.txt file to scan k12text.l, as that now
contains a registration routine. In the process, avoid scanning files
that don't implement a file type and won't ever have a registration
routine.
Add a Lua routine to fetch the total number of file types; we use that
in some code to construct the wtap_filetypes table, which we need to do
in order to continue to have all the values that used to come from the
WTAP_FILE_TYPE_SUBTYPE_ types.
While we're at it, add modelines to a file that lacked them.
2021-02-14 08:34:10 +00:00
|
|
|
}
|
|
|
|
|
2015-08-09 18:55:27 +00:00
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2015-08-09 18:55:27 +00:00
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: t
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
|
|
|
|
* :indentSize=8:tabSize=8:noTabs=false:
|
|
|
|
*/
|