Remove some single-SHB assumptions.

Make wtap_file_get_shb() take a section number argument, and update code
that called it.  In most cases, we convert the code to iterate over
sections; in cases where a big code change would be required, we
temporarily pass it 0 and mark the code as "needs to be updated for
multiple sections".

Eliminate cf_read_section_comment(); in calls outside file.c, other code
directly calls the libwiretap routines it calls and, inside file.c, we
just transplant the code and then fix it not to assume a single SHB.

Change-Id: I85e94d0a4fc878e9d937088759be04cb004e019b
Reviewed-on: https://code.wireshark.org/review/37000
Petri-Dish: Guy Harris <gharris@sonic.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <gharris@sonic.net>
This commit is contained in:
Guy Harris 2020-05-01 10:28:04 -07:00 committed by Guy Harris
parent 3a32757313
commit 582ad24c38
7 changed files with 252 additions and 198 deletions

View File

@ -184,8 +184,8 @@ typedef struct _capture_info {
wtap_compression_type compression_type;
int file_encap;
int file_tsprec;
wtap *wth;
gint64 filesize;
wtap_block_t shb;
guint64 packet_bytes;
gboolean times_known;
nstime_t start_time;
@ -744,38 +744,51 @@ print_stats(const gchar *filename, capture_info *cf_info)
}
if (cap_order) printf ("Strict time order: %s\n", order_string(cf_info->order));
if (cf_info->shb != NULL) {
if (cap_file_more_info) {
char *str;
gboolean has_multiple_sections = (wtap_file_get_num_shbs(cf_info->wth) > 1);
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture hardware: ", str);
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture oper-sys: ", str);
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture application: ", str);
}
if (cap_comment) {
unsigned int i;
char *str;
for (guint section_number = 0;
section_number < wtap_file_get_num_shbs(cf_info->wth);
section_number++) {
wtap_block_t shb;
for (i = 0; wtap_block_get_nth_string_option_value(cf_info->shb, OPT_COMMENT, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) {
show_option_string("Capture comment: ", str);
// If we have more than one section, add headers for each section.
if (has_multiple_sections)
printf("Section %u:\n\n", section_number);
shb = wtap_file_get_shb(cf_info->wth, section_number);
if (shb != NULL) {
if (cap_file_more_info) {
char *str;
if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture hardware: ", str);
if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture oper-sys: ", str);
if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS)
show_option_string("Capture application: ", str);
}
}
if (cap_comment) {
unsigned int i;
char *str;
if (cap_file_idb && cf_info->num_interfaces != 0) {
guint i;
g_assert(cf_info->num_interfaces == cf_info->idb_info_strings->len);
printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
for (i = 0; i < cf_info->idb_info_strings->len; i++) {
gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
guint32 packet_count = 0;
if (i < cf_info->interface_packet_counts->len)
packet_count = g_array_index(cf_info->interface_packet_counts, guint32, i);
printf ("Interface #%u info:\n", i);
printf ("%s", s);
printf (" Number of packets = %u\n", packet_count);
for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) {
show_option_string("Capture comment: ", str);
}
}
if (cap_file_idb && cf_info->num_interfaces != 0) {
guint i;
g_assert(cf_info->num_interfaces == cf_info->idb_info_strings->len);
printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
for (i = 0; i < cf_info->idb_info_strings->len; i++) {
gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
guint32 packet_count = 0;
if (i < cf_info->interface_packet_counts->len)
packet_count = g_array_index(cf_info->interface_packet_counts, guint32, i);
printf ("Interface #%u info:\n", i);
printf ("%s", s);
printf (" Number of packets = %u\n", packet_count);
}
}
}
@ -1026,27 +1039,36 @@ print_stats_table(const gchar *filename, capture_info *cf_info)
putquote();
}
if (cf_info->shb != NULL) {
for (guint section_number = 0;
section_number < wtap_file_get_num_shbs(cf_info->wth);
section_number++) {
wtap_block_t shb;
// If we have more than one section, add headers for each section.
if (wtap_file_get_num_shbs(cf_info->wth) > 1)
printf("Section %u: \n", section_number);
shb = wtap_file_get_shb(cf_info->wth, section_number);
if (cap_file_more_info) {
char *str;
putsep();
putquote();
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
printf("%s", str);
}
putquote();
putsep();
putquote();
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
printf("%s", str);
}
putquote();
putsep();
putquote();
if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
printf("%s", str);
}
putquote();
@ -1068,7 +1090,11 @@ print_stats_table(const gchar *filename, capture_info *cf_info)
char *opt_comment;
gboolean have_cap = FALSE;
for (i = 0; wtap_block_get_nth_string_option_value(cf_info->shb, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
// If we have more than one section, add headers for each section.
if (wtap_file_get_num_shbs(cf_info->wth) > 1)
printf("Section %u: \n", section_number);
for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
have_cap = TRUE;
putsep();
putquote();
@ -1134,7 +1160,6 @@ static int
process_cap_file(const char *filename, gboolean need_separator)
{
int status = 0;
wtap *wth;
int err;
gchar *err_info;
gint64 size;
@ -1159,8 +1184,8 @@ process_cap_file(const char *filename, gboolean need_separator)
guint i;
wtapng_iface_descriptions_t *idb_info;
wth = wtap_open_offline(filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (!wth) {
cf_info.wth = wtap_open_offline(filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (!cf_info.wth) {
cfile_open_failure_message("capinfos", filename, err, err_info);
return 2;
}
@ -1176,11 +1201,9 @@ process_cap_file(const char *filename, gboolean need_separator)
nstime_set_zero(&cur_time);
nstime_set_zero(&prev_time);
cf_info.shb = wtap_file_get_shb(wth);
cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES);
idb_info = wtap_file_get_idb_info(wth);
idb_info = wtap_file_get_idb_info(cf_info.wth);
g_assert(idb_info->interface_data != NULL);
@ -1194,9 +1217,9 @@ process_cap_file(const char *filename, gboolean need_separator)
/* Register callbacks for new name<->address maps from the file and
decryption secrets from the file. */
wtap_set_cb_new_ipv4(wth, count_ipv4_address);
wtap_set_cb_new_ipv6(wth, count_ipv6_address);
wtap_set_cb_new_secrets(wth, count_decryption_secret);
wtap_set_cb_new_ipv4(cf_info.wth, count_ipv4_address);
wtap_set_cb_new_ipv6(cf_info.wth, count_ipv6_address);
wtap_set_cb_new_secrets(cf_info.wth, count_decryption_secret);
/* Zero out the counters for the callbacks. */
num_ipv4_addresses = 0;
@ -1206,7 +1229,7 @@ process_cap_file(const char *filename, gboolean need_separator)
/* Tally up data that we need to parse through the file to find */
wtap_rec_init(&rec);
ws_buffer_init(&buf, 1514);
while (wtap_read(wth, &rec, &buf, &err, &err_info, &data_offset)) {
while (wtap_read(cf_info.wth, &rec, &buf, &err, &err_info, &data_offset)) {
if (rec.presence_flags & WTAP_HAS_TS) {
prev_time = cur_time;
cur_time = rec.ts;
@ -1267,7 +1290,7 @@ process_cap_file(const char *filename, gboolean need_separator)
* grow the array to be big enough for the new number of
* interfaces.
*/
idb_info = wtap_file_get_idb_info(wth);
idb_info = wtap_file_get_idb_info(cf_info.wth);
cf_info.num_interfaces = idb_info->interface_data->len;
g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
@ -1303,7 +1326,7 @@ process_cap_file(const char *filename, gboolean need_separator)
* We do this at the end, so we can get information for all IDBs in
* the file, even those that come after packet records.
*/
idb_info = wtap_file_get_idb_info(wth);
idb_info = wtap_file_get_idb_info(cf_info.wth);
cf_info.idb_info_strings = g_array_sized_new(FALSE, FALSE, sizeof(gchar*), cf_info.num_interfaces);
cf_info.num_interfaces = idb_info->interface_data->len;
@ -1328,35 +1351,35 @@ process_cap_file(const char *filename, gboolean need_separator)
" (will continue anyway, checksums might be incorrect)\n");
} else {
cleanup_capture_info(&cf_info);
wtap_close(wth);
wtap_close(cf_info.wth);
return 2;
}
}
/* File size */
size = wtap_file_size(wth, &err);
size = wtap_file_size(cf_info.wth, &err);
if (size == -1) {
fprintf(stderr,
"capinfos: Can't get size of \"%s\": %s.\n",
filename, g_strerror(err));
cleanup_capture_info(&cf_info);
wtap_close(wth);
wtap_close(cf_info.wth);
return 2;
}
cf_info.filesize = size;
/* File Type */
cf_info.file_type = wtap_file_type_subtype(wth);
cf_info.compression_type = wtap_get_compression_type(wth);
cf_info.file_type = wtap_file_type_subtype(cf_info.wth);
cf_info.compression_type = wtap_get_compression_type(cf_info.wth);
/* File Encapsulation */
cf_info.file_encap = wtap_file_encap(wth);
cf_info.file_encap = wtap_file_encap(cf_info.wth);
cf_info.file_tsprec = wtap_file_tsprec(wth);
cf_info.file_tsprec = wtap_file_tsprec(cf_info.wth);
/* Packet size limit (snaplen) */
cf_info.snaplen = wtap_snapshot_length(wth);
cf_info.snaplen = wtap_snapshot_length(cf_info.wth);
if (cf_info.snaplen > 0)
cf_info.snap_set = TRUE;
else
@ -1406,7 +1429,7 @@ process_cap_file(const char *filename, gboolean need_separator)
}
cleanup_capture_info(&cf_info);
wtap_close(wth);
wtap_close(cf_info.wth);
return status;
}

View File

@ -89,6 +89,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_file_get_idb_info@Base 1.9.1
wtap_file_get_nrb@Base 2.1.2
wtap_file_get_nrb_for_new_file@Base 1.99.9
wtap_file_get_num_shbs@Base 3.3.0
wtap_file_get_shb@Base 1.99.9
wtap_file_get_shb_for_new_file@Base 1.99.9
wtap_file_size@Base 1.9.1

47
file.c
View File

@ -3930,26 +3930,6 @@ cf_unignore_frame(capture_file *cf, frame_data *frame)
}
}
/*
* Read the section comment.
*/
const gchar *
cf_read_section_comment(capture_file *cf)
{
wtap_block_t shb_inf;
char *shb_comment;
/* Get the SHB. */
/* XXX - support multiple SHBs */
shb_inf = wtap_file_get_shb(cf->provider.wth);
/* Get the first comment from the SHB. */
/* XXX - support multiple comments */
if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS)
return NULL;
return shb_comment;
}
/*
* Modify the section comment.
*/
@ -3959,9 +3939,9 @@ cf_update_section_comment(capture_file *cf, gchar *comment)
wtap_block_t shb_inf;
gchar *shb_comment;
/* Get the SHB. */
/* Get the first SHB. */
/* XXX - support multiple SHBs */
shb_inf = wtap_file_get_shb(cf->provider.wth);
shb_inf = wtap_file_get_shb(cf->provider.wth, 0);
/* Get the first comment from the SHB. */
/* XXX - support multiple comments */
@ -4054,8 +4034,27 @@ cf_comment_types(capture_file *cf)
{
guint32 comment_types = 0;
if (cf_read_section_comment(cf) != NULL)
comment_types |= WTAP_COMMENT_PER_SECTION;
/*
* Does this file have any sections with at least one comment?
*/
for (guint section_number = 0;
section_number < wtap_file_get_num_shbs(cf->provider.wth);
section_number++) {
wtap_block_t shb_inf;
char *shb_comment;
shb_inf = wtap_file_get_shb(cf->provider.wth, section_number);
/* Try to get the first comment from that SHB. */
if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0,
&shb_comment) == WTAP_OPTTYPE_SUCCESS) {
/* We succeeded, so this file has at least one section comment. */
comment_types |= WTAP_COMMENT_PER_SECTION;
/* We don't need to search any more. */
break;
}
}
if (cf->packet_comment_count != 0)
comment_types |= WTAP_COMMENT_PER_PACKET;
return comment_types;

9
file.h
View File

@ -671,15 +671,6 @@ cf_merge_files_to_tempfile(gpointer pd_window, char **out_filenamep,
int in_file_count, const char *const *in_filenames,
int file_type, gboolean do_append);
/**
* Get the comment on a capture from the SHB data block
* XXX - should support multiple sections.
*
* @param cf the capture file
*/
const gchar* cf_read_section_comment(capture_file *cf);
/**
* Update(replace) the comment on a capture from the SHB data block
* XXX - should support multiple sections.

View File

@ -99,7 +99,15 @@ void CaptureFilePropertiesDialog::updateWidgets()
ui->commentsTextEdit->setEnabled(enable);
fillDetails();
ui->commentsTextEdit->setText(cf_read_section_comment(cap_file_.capFile()));
// XXX - this just handles the first comment in the first section;
// add support for multiple sections with multiple comments.
wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, 0);
char *shb_comment;
if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, 0,
&shb_comment) == WTAP_OPTTYPE_SUCCESS)
ui->commentsTextEdit->setText(shb_comment);
else
ui->commentsTextEdit->setText(NULL);
WiresharkDialog::updateWidgets();
}
@ -252,107 +260,116 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
out << table_end;
}
// Capture Section
out << section_tmpl_.arg(tr("Capture"));
out << table_begin;
// Information from file sections.
for (guint section_number = 0;
section_number < wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth);
section_number++) {
wtap_block_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->provider.wth);
char *str;
// If we have more than one section, add headers for each section.
if (wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth) > 1)
out << section_tmpl_.arg(QString(tr("Section %1"))
.arg(section_number));
if (shb_inf != nullptr) {
QString capture_hardware(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_hardware = str;
}
}
// capture HW
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Hardware"))
<< table_data_tmpl.arg(capture_hardware)
<< table_row_end;
QString capture_os(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_os = str;
}
}
out << table_row_begin
<< table_vheader_tmpl.arg(tr("OS"))
<< table_data_tmpl.arg(capture_os)
<< table_row_end;
QString capture_app(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_app = str;
}
}
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Application"))
<< table_data_tmpl.arg(capture_app)
<< table_row_end;
}
out << table_end;
// capture interfaces info
if (summary.ifaces->len > 0) {
out << section_tmpl_.arg(tr("Interfaces"));
// Capture Section
out << section_tmpl_.arg(tr("Capture"));
out << table_begin;
out << table_ul_row_begin
<< table_hheader20_tmpl.arg(tr("Interface"))
<< table_hheader20_tmpl.arg(tr("Dropped packets"))
<< table_hheader20_tmpl.arg(tr("Capture filter"))
<< table_hheader20_tmpl.arg(tr("Link type"))
<< table_hheader20_tmpl.arg(tr("Packet size limit"))
<< table_row_end;
}
wtap_block_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->provider.wth, section_number);
char *str;
for (guint i = 0; i < summary.ifaces->len; i++) {
iface_summary_info iface;
iface = g_array_index(summary.ifaces, iface_summary_info, i);
if (shb_inf != nullptr) {
QString capture_hardware(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_hardware = str;
}
}
// capture HW
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Hardware"))
<< table_data_tmpl.arg(capture_hardware)
<< table_row_end;
/* interface */
QString interface_name(unknown);
if (iface.descr) {
interface_name = iface.descr;
} else if (iface.name)
{
interface_name = iface.name;
QString capture_os(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_os = str;
}
}
out << table_row_begin
<< table_vheader_tmpl.arg(tr("OS"))
<< table_data_tmpl.arg(capture_os)
<< table_row_end;
QString capture_app(unknown);
if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
if (str[0] != '\0') {
capture_app = str;
}
}
out << table_row_begin
<< table_vheader_tmpl.arg(tr("Application"))
<< table_data_tmpl.arg(capture_app)
<< table_row_end;
}
/* Dropped count */
QString interface_drops(unknown);
if (iface.drops_known) {
interface_drops = QString("%1 (%2%)").arg(iface.drops).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
summary.packet_count ? (100.0 * (gint64)iface.drops)/summary.packet_count : 0, 'f', 1));
}
/* Capture filter */
QString interface_cfilter(unknown);
if (iface.cfilter && iface.cfilter[0] != '\0') {
interface_cfilter = iface.cfilter;
} else if (iface.name) {
interface_cfilter = QString(tr("none"));
}
QString interface_snaplen = QString(tr("%1 bytes").arg(iface.snap));
out << table_row_begin
<< table_data_tmpl.arg(interface_name)
<< table_data_tmpl.arg(interface_drops)
<< table_data_tmpl.arg(interface_cfilter)
<< table_data_tmpl.arg(wtap_encap_description(iface.encap_type))
<< table_data_tmpl.arg(interface_snaplen)
<< table_row_end;
}
if (summary.ifaces->len > 0) {
out << table_end;
// capture interfaces info
if (summary.ifaces->len > 0) {
out << section_tmpl_.arg(tr("Interfaces"));
out << table_begin;
out << table_ul_row_begin
<< table_hheader20_tmpl.arg(tr("Interface"))
<< table_hheader20_tmpl.arg(tr("Dropped packets"))
<< table_hheader20_tmpl.arg(tr("Capture filter"))
<< table_hheader20_tmpl.arg(tr("Link type"))
<< table_hheader20_tmpl.arg(tr("Packet size limit"))
<< table_row_end;
}
for (guint i = 0; i < summary.ifaces->len; i++) {
iface_summary_info iface;
iface = g_array_index(summary.ifaces, iface_summary_info, i);
/* interface */
QString interface_name(unknown);
if (iface.descr) {
interface_name = iface.descr;
} else if (iface.name) {
interface_name = iface.name;
}
/* Dropped count */
QString interface_drops(unknown);
if (iface.drops_known) {
interface_drops = QString("%1 (%2%)").arg(iface.drops).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
summary.packet_count ? (100.0 * (gint64)iface.drops)/summary.packet_count : 0, 'f', 1));
}
/* Capture filter */
QString interface_cfilter(unknown);
if (iface.cfilter && iface.cfilter[0] != '\0') {
interface_cfilter = iface.cfilter;
} else if (iface.name) {
interface_cfilter = QString(tr("none"));
}
QString interface_snaplen = QString(tr("%1 bytes").arg(iface.snap));
out << table_row_begin
<< table_data_tmpl.arg(interface_name)
<< table_data_tmpl.arg(interface_drops)
<< table_data_tmpl.arg(interface_cfilter)
<< table_data_tmpl.arg(wtap_encap_description(iface.encap_type))
<< table_data_tmpl.arg(interface_snaplen)
<< table_row_end;
}
if (summary.ifaces->len > 0) {
out << table_end;
}
}
// Statistics Section
@ -520,16 +537,23 @@ void CaptureFilePropertiesDialog::fillDetails()
cursor.insertHtml(summary);
cursor.insertBlock(); // Work around rendering oddity.
QString file_comments = cf_read_section_comment(cap_file_.capFile());
if (!file_comments.isEmpty()) {
QString file_comments_html;
// XXX - this just shows the first comment in the first section;
// add support for multiple sections with multiple comments.
wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, 0);
char *shb_comment;
if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, 0,
&shb_comment) == WTAP_OPTTYPE_SUCCESS) {
QString section_comment = shb_comment;
QString section_comment_html;
QString comment_escaped = html_escape(file_comments).replace('\n', "<br>");
file_comments_html = section_tmpl_.arg(tr("File Comment"));
file_comments_html += para_tmpl_.arg(comment_escaped);
if (!section_comment.isEmpty()) {
QString comment_escaped = html_escape(section_comment).replace('\n', "<br>");
section_comment_html += section_tmpl_.arg(QString(tr("Section Comment")));
section_comment_html += para_tmpl_.arg(comment_escaped);
cursor.insertBlock();
cursor.insertHtml(file_comments_html);
cursor.insertBlock();
cursor.insertHtml(section_comment_html);
}
}
if (cap_file_.capFile()->packet_comment_count > 0) {

View File

@ -95,13 +95,19 @@ wtap_file_tsprec(wtap *wth)
return wth->file_tsprec;
}
wtap_block_t
wtap_file_get_shb(wtap *wth)
guint
wtap_file_get_num_shbs(wtap *wth)
{
if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0))
return wth->shb_hdrs->len;
}
wtap_block_t
wtap_file_get_shb(wtap *wth, guint shb_num)
{
if ((wth == NULL) || (wth->shb_hdrs == NULL) || (shb_num >= wth->shb_hdrs->len))
return NULL;
return g_array_index(wth->shb_hdrs, wtap_block_t, 0);
return g_array_index(wth->shb_hdrs, wtap_block_t, shb_num);
}
GArray*

View File

@ -1860,20 +1860,30 @@ int wtap_file_encap(wtap *wth);
WS_DLL_PUBLIC
int wtap_file_tsprec(wtap *wth);
/**
* @brief Gets number of section header blocks.
* @details Returns the number of existing SHBs.
*
* @param wth The wiretap session.
* @return The number of existing section headers.
*/
WS_DLL_PUBLIC
guint wtap_file_get_num_shbs(wtap *wth);
/**
* @brief Gets existing section header block, not for new file.
* @details Returns the pointer to the existing SHB, without creating a
* @details Returns the pointer to an existing SHB, without creating a
* new one. This should only be used for accessing info, not
* for creating a new file based on existing SHB info. Use
* wtap_file_get_shb_for_new_file() for that.
*
* @param wth The wiretap session.
* @return The existing section header, which must NOT be g_free'd.
*
* XXX - need to be updated to handle multiple SHBs.
* @param shb_num The ordinal number (0-based) of the section header
* in the file
* @return The specified existing section header, which must NOT be g_free'd.
*/
WS_DLL_PUBLIC
wtap_block_t wtap_file_get_shb(wtap *wth);
wtap_block_t wtap_file_get_shb(wtap *wth, guint shb_num);
/**
* @brief Gets new section header block for new file, based on existing info.