2017-12-07 20:33:22 -08:00
|
|
|
/* file_packet_provider_data.c
|
|
|
|
* Routines for a packet_provider_data for packets from a file.
|
2017-12-03 21:01:18 -08:00
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-07 12:26:45 +01:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2017-12-03 21:01:18 -08:00
|
|
|
*/
|
2021-11-12 17:23:04 +00:00
|
|
|
#include "config.h"
|
2017-12-03 21:01:18 -08:00
|
|
|
|
2024-08-06 07:32:42 +02:00
|
|
|
#include <stdint.h>
|
2017-12-03 21:01:18 -08:00
|
|
|
#include <glib.h>
|
2017-12-07 19:31:43 -08:00
|
|
|
#include "cfile.h"
|
2017-12-03 21:01:18 -08:00
|
|
|
|
2023-12-18 10:54:02 -08:00
|
|
|
const nstime_t *
|
2024-07-07 09:29:58 -04:00
|
|
|
cap_file_provider_get_frame_ts(struct packet_provider_data *prov, uint32_t frame_num)
|
2023-12-18 10:54:02 -08:00
|
|
|
{
|
|
|
|
const frame_data *fd = NULL;
|
|
|
|
|
|
|
|
if (prov->ref && prov->ref->num == frame_num) {
|
|
|
|
fd = prov->ref;
|
|
|
|
} else if (prov->prev_dis && prov->prev_dis->num == frame_num) {
|
|
|
|
fd = prov->prev_dis;
|
|
|
|
} else if (prov->prev_cap && prov->prev_cap->num == frame_num) {
|
|
|
|
fd = prov->prev_cap;
|
|
|
|
} else if (prov->frames) {
|
|
|
|
fd = frame_data_sequence_find(prov->frames, frame_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (fd && fd->has_ts) ? &fd->abs_ts : NULL;
|
|
|
|
}
|
|
|
|
|
2017-12-06 19:51:18 +01:00
|
|
|
static int
|
2024-07-04 13:32:14 -05:00
|
|
|
frame_cmp(const void *a, const void *b, void *user_data _U_)
|
2017-12-06 19:51:18 +01:00
|
|
|
{
|
|
|
|
const frame_data *fdata1 = (const frame_data *) a;
|
|
|
|
const frame_data *fdata2 = (const frame_data *) b;
|
|
|
|
|
|
|
|
return (fdata1->num < fdata2->num) ? -1 :
|
|
|
|
(fdata1->num > fdata2->num) ? 1 :
|
|
|
|
0;
|
|
|
|
}
|
|
|
|
|
2017-12-03 21:01:18 -08:00
|
|
|
const char *
|
2024-07-07 09:29:58 -04:00
|
|
|
cap_file_provider_get_interface_name(struct packet_provider_data *prov, uint32_t interface_id, unsigned section_number)
|
2017-12-03 21:01:18 -08:00
|
|
|
{
|
|
|
|
wtapng_iface_descriptions_t *idb_info;
|
|
|
|
wtap_block_t wtapng_if_descr = NULL;
|
|
|
|
char* interface_name;
|
|
|
|
|
2017-12-07 19:31:43 -08:00
|
|
|
idb_info = wtap_file_get_idb_info(prov->wth);
|
2017-12-03 21:01:18 -08:00
|
|
|
|
Improve interface displaying and writing with multiple sections
Update the functions that get an interface name or description
to also take the section number in the record (0 if not present.)
Store a mapping of SHB number and interface number to global
interface number, and provide a function to access it. Use the
function to display the correct interface name and description
when there are multiple SHBs.
Use this information to rewrite interface numbers when writing a
pcapng file through wtap dumper, since we don't write additional
SHBs to a file when dumping. We could, but we'd have to store
exactly when to write the extra SHB when reading the file in
sequentially (unlike the other internal blocks, IDB, NRB, and
DSBs, that we intentionally move to the start.)
Since we're changing the number of sections, perhaps we should edit
the SHB options more?
Merging handles interface numbers in its own manner, but also needs
to know about the per-SHB interface ID to global ID mapping when
doing so.
Capinfos and capture file properties still require a bit more work
for proper output.
Fix #16531, fix #18049
2023-12-05 07:03:06 -05:00
|
|
|
unsigned gbl_iface_id = wtap_file_get_shb_global_interface_id(prov->wth, section_number, interface_id);
|
|
|
|
|
|
|
|
if (gbl_iface_id < idb_info->interface_data->len)
|
|
|
|
wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, gbl_iface_id);
|
2017-12-03 21:01:18 -08:00
|
|
|
|
|
|
|
g_free(idb_info);
|
|
|
|
|
|
|
|
if (wtapng_if_descr) {
|
|
|
|
if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_NAME, &interface_name) == WTAP_OPTTYPE_SUCCESS)
|
|
|
|
return interface_name;
|
2021-07-13 23:48:19 -07:00
|
|
|
if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCRIPTION, &interface_name) == WTAP_OPTTYPE_SUCCESS)
|
2017-12-03 21:01:18 -08:00
|
|
|
return interface_name;
|
2018-08-10 19:08:40 -07:00
|
|
|
if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_HARDWARE, &interface_name) == WTAP_OPTTYPE_SUCCESS)
|
|
|
|
return interface_name;
|
2017-12-03 21:01:18 -08:00
|
|
|
}
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
2024-07-07 09:29:58 -04:00
|
|
|
cap_file_provider_get_interface_description(struct packet_provider_data *prov, uint32_t interface_id, unsigned section_number)
|
2017-12-03 21:01:18 -08:00
|
|
|
{
|
|
|
|
wtapng_iface_descriptions_t *idb_info;
|
|
|
|
wtap_block_t wtapng_if_descr = NULL;
|
|
|
|
char* interface_name;
|
|
|
|
|
2017-12-07 19:31:43 -08:00
|
|
|
idb_info = wtap_file_get_idb_info(prov->wth);
|
2017-12-03 21:01:18 -08:00
|
|
|
|
Improve interface displaying and writing with multiple sections
Update the functions that get an interface name or description
to also take the section number in the record (0 if not present.)
Store a mapping of SHB number and interface number to global
interface number, and provide a function to access it. Use the
function to display the correct interface name and description
when there are multiple SHBs.
Use this information to rewrite interface numbers when writing a
pcapng file through wtap dumper, since we don't write additional
SHBs to a file when dumping. We could, but we'd have to store
exactly when to write the extra SHB when reading the file in
sequentially (unlike the other internal blocks, IDB, NRB, and
DSBs, that we intentionally move to the start.)
Since we're changing the number of sections, perhaps we should edit
the SHB options more?
Merging handles interface numbers in its own manner, but also needs
to know about the per-SHB interface ID to global ID mapping when
doing so.
Capinfos and capture file properties still require a bit more work
for proper output.
Fix #16531, fix #18049
2023-12-05 07:03:06 -05:00
|
|
|
interface_id = wtap_file_get_shb_global_interface_id(prov->wth, section_number, interface_id);
|
|
|
|
|
2017-12-03 21:01:18 -08:00
|
|
|
if (interface_id < idb_info->interface_data->len)
|
|
|
|
wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, interface_id);
|
|
|
|
|
|
|
|
g_free(idb_info);
|
|
|
|
|
|
|
|
if (wtapng_if_descr) {
|
2021-07-13 23:48:19 -07:00
|
|
|
if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCRIPTION, &interface_name) == WTAP_OPTTYPE_SUCCESS)
|
2017-12-03 21:01:18 -08:00
|
|
|
return interface_name;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-12-06 19:51:18 +01:00
|
|
|
|
2021-04-29 07:23:21 -04:00
|
|
|
wtap_block_t
|
2021-07-07 22:43:29 -07:00
|
|
|
cap_file_provider_get_modified_block(struct packet_provider_data *prov, const frame_data *fd)
|
2017-12-06 19:51:18 +01:00
|
|
|
{
|
2021-07-08 01:11:23 -07:00
|
|
|
if (prov->frames_modified_blocks)
|
|
|
|
return (wtap_block_t)g_tree_lookup(prov->frames_modified_blocks, fd);
|
2017-12-06 19:51:18 +01:00
|
|
|
|
2021-06-15 00:06:02 +01:00
|
|
|
/* ws_warning? */
|
2017-12-06 19:51:18 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-08-22 19:46:08 +02:00
|
|
|
cap_file_provider_set_modified_block(struct packet_provider_data *prov, frame_data *fd, const wtap_block_t new_block)
|
2017-12-06 19:51:18 +01:00
|
|
|
{
|
2021-07-08 01:11:23 -07:00
|
|
|
if (!prov->frames_modified_blocks)
|
|
|
|
prov->frames_modified_blocks = g_tree_new_full(frame_cmp, NULL, NULL, (GDestroyNotify)wtap_block_unref);
|
2017-12-06 19:51:18 +01:00
|
|
|
|
2021-04-29 07:23:21 -04:00
|
|
|
/* insert new packet block */
|
2024-07-04 13:32:14 -05:00
|
|
|
g_tree_replace(prov->frames_modified_blocks, fd, (void *)new_block);
|
2017-12-06 19:51:18 +01:00
|
|
|
|
2024-07-07 09:29:58 -04:00
|
|
|
fd->has_modified_block = 1;
|
2017-12-06 19:51:18 +01:00
|
|
|
}
|