aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHadriel Kaplan <hadrielk@yahoo.com>2015-07-20 10:35:06 -0400
committerAnders Broman <a.broman58@gmail.com>2015-08-06 03:32:13 +0000
commit910438b17f3f8b9ca9cfdbb87b3daf49dd7eb9a0 (patch)
treef57b1dd36c4e20cd7b9758476cb862b74cd1a320
parent1420f3df6376f45157b7f363c6c07da3a9ac6f29 (diff)
Pcapng: support Name Resolution Block options
Make pcapng decode options in an NRB during read, and store the comment option, and write it back out as well. Also make it handle plugin handlers for unknown options in received NRB(s). Change-Id: I81863ef8d85cb1c8b5ba6673ba0e562efe77714f Reviewed-on: https://code.wireshark.org/review/9723 Petri-Dish: Hadriel Kaplan <hadrielk@yahoo.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--debian/libwiretap0.symbols4
-rw-r--r--editcap.c17
-rw-r--r--file.c26
-rw-r--r--mergecap.c2
-rw-r--r--reordercap.c13
-rw-r--r--tshark.c13
-rw-r--r--ui/gtk/file_import_dlg.c4
-rw-r--r--ui/qt/resolved_addresses_dialog.cpp30
-rw-r--r--ui/qt/resolved_addresses_dialog.h2
-rw-r--r--ui/qt/resolved_addresses_dialog.ui14
-rw-r--r--ui/tap_export_pdu.c4
-rw-r--r--wiretap/file_access.c19
-rw-r--r--wiretap/nettrace_3gpp_32_423.c3
-rw-r--r--wiretap/pcapng.c291
-rw-r--r--wiretap/pcapng_module.h17
-rw-r--r--wiretap/wtap-int.h8
-rw-r--r--wiretap/wtap.c59
-rw-r--r--wiretap/wtap.h105
18 files changed, 473 insertions, 158 deletions
diff --git a/debian/libwiretap0.symbols b/debian/libwiretap0.symbols
index e34163ec42..5bd3483823 100644
--- a/debian/libwiretap0.symbols
+++ b/debian/libwiretap0.symbols
@@ -51,6 +51,8 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_file_encap@Base 1.9.1
wtap_file_get_idb_info@Base 1.9.1
wtap_file_get_shb_info@Base 1.9.1
+ wtap_file_get_nrb_for_new_file@Base 1.99.9
+ wtap_free_nrb@Base 1.99.9
wtap_file_size@Base 1.9.1
wtap_file_tsprec@Base 1.99.0
wtap_file_type_subtype@Base 1.12.0~rc1
@@ -63,6 +65,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_get_file_extension_type_extensions@Base 1.12.0~rc1
wtap_get_file_extension_type_name@Base 1.12.0~rc1
wtap_get_file_extensions_list@Base 1.9.1
+ wtap_get_nrb_comment@Base 1.99.9
wtap_get_num_encap_types@Base 1.9.1
wtap_get_num_file_type_extensions@Base 1.12.0~rc1
wtap_get_num_file_types_subtypes@Base 1.12.0~rc1
@@ -93,5 +96,6 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_short_string_to_file_type_subtype@Base 1.9.1
wtap_snapshot_length@Base 1.9.1
wtap_strerror@Base 1.9.1
+ wtap_write_nrb_comment@Base 1.99.9
wtap_write_shb_comment@Base 1.9.1
wtap_wtap_encap_to_pcap_encap@Base 1.9.1
diff --git a/editcap.c b/editcap.c
index 12a9e826bd..a636abebbe 100644
--- a/editcap.c
+++ b/editcap.c
@@ -924,8 +924,9 @@ DIAG_ON(cast-qual)
const struct wtap_pkthdr *phdr;
struct wtap_pkthdr temp_phdr;
- wtapng_iface_descriptions_t *idb_inf;
- wtapng_section_t *shb_hdr;
+ wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_section_t *shb_hdr = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
#ifdef HAVE_PLUGINS
char* init_progfile_dir_error;
@@ -1278,6 +1279,7 @@ DIAG_ON(cast-qual)
shb_hdr = wtap_file_get_shb_info(wth);
idb_inf = wtap_file_get_idb_info(wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(wth);
/*
* Now, process the rest, if any ... we only write if there is an extra
@@ -1325,7 +1327,7 @@ DIAG_ON(cast-qual)
pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
- FALSE /* compressed */, shb_hdr, idb_inf, &err);
+ FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
if (pdh == NULL) {
fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1367,7 +1369,7 @@ DIAG_ON(cast-qual)
pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
- FALSE /* compressed */, shb_hdr, idb_inf, &err);
+ FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
if (pdh == NULL) {
fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1396,7 +1398,7 @@ DIAG_ON(cast-qual)
pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
- FALSE /* compressed */, shb_hdr, idb_inf, &err);
+ FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
if (pdh == NULL) {
fprintf(stderr, "editcap: Can't open or create %s: %s\n",
filename, wtap_strerror(err));
@@ -1760,7 +1762,7 @@ DIAG_ON(cast-qual)
pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
snaplen ? MIN(snaplen, wtap_snapshot_length(wth)): wtap_snapshot_length(wth),
- FALSE /* compressed */, shb_hdr, idb_inf, &err);
+ FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
if (pdh == NULL) {
fprintf(stderr, "editcap: Can't open or create %s: %s\n",
filename, wtap_strerror(err));
@@ -1777,6 +1779,9 @@ DIAG_ON(cast-qual)
exit(2);
}
g_free(shb_hdr);
+ shb_hdr = NULL;
+ wtap_free_nrb(nrb_hdr);
+ nrb_hdr = NULL;
g_free(filename);
if (frames_user_comments) {
diff --git a/file.c b/file.c
index 1183a169a2..449269fbc4 100644
--- a/file.c
+++ b/file.c
@@ -1317,6 +1317,7 @@ cf_merge_files(char **out_filenamep, int in_file_count,
}
shb_hdr->section_length = -1;
/* options */
+ /* TODO: handle comments from each file being merged */
shb_hdr->opt_comment = g_string_free(comment_gstr, FALSE); /* NULL if not available */
shb_hdr->shb_hardware = NULL; /* NULL if not available, UTF-8 string containing the */
/* description of the hardware used to create this section. */
@@ -1325,6 +1326,8 @@ cf_merge_files(char **out_filenamep, int in_file_count,
shb_hdr->shb_user_appl = g_strdup("Wireshark"); /* NULL if not available, UTF-8 string containing the name */
/* of the application used to create this section. */
+ /* TODO: handle name resolution info from each file being merged */
+
/* create fake IDB info */
idb_inf = g_new(wtapng_iface_descriptions_t,1);
/* TODO make this the number of DIFFERENT encapsulation types
@@ -1366,7 +1369,8 @@ cf_merge_files(char **out_filenamep, int in_file_count,
pdh = wtap_dump_fdopen_ng(out_fd, file_type,
selected_frame_type,
merge_max_snapshot_length(in_file_count, in_files),
- FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
+ FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */,
+ NULL, &open_err);
if (pdh == NULL) {
ws_close(out_fd);
@@ -4671,12 +4675,15 @@ cf_save_records(capture_file *cf, const char *fname, guint save_format,
or moving the capture file, we have to do it by writing the packets
out in Wiretap. */
- wtapng_section_t *shb_hdr = NULL;
+ wtapng_section_t *shb_hdr = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
int encap;
+ /* XXX: what free's this shb_hdr? */
shb_hdr = wtap_file_get_shb_info(cf->wth);
idb_inf = wtap_file_get_idb_info(cf->wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
/* Determine what file encapsulation type we should use. */
encap = wtap_dump_file_encap_type(cf->linktypes);
@@ -4691,10 +4698,10 @@ cf_save_records(capture_file *cf, const char *fname, guint save_format,
from which we're reading the packets that we're writing!) */
fname_new = g_strdup_printf("%s~", fname);
pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
} else {
pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
}
g_free(idb_inf);
idb_inf = NULL;
@@ -4891,8 +4898,9 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
int err;
wtap_dumper *pdh;
save_callback_args_t callback_args;
- wtapng_section_t *shb_hdr;
- wtapng_iface_descriptions_t *idb_inf;
+ wtapng_section_t *shb_hdr = NULL;
+ wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
int encap;
cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
@@ -4904,8 +4912,10 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
written, don't special-case the operation - read each packet
and then write it out if it's one of the specified ones. */
+ /* XXX: what free's this shb_hdr? */
shb_hdr = wtap_file_get_shb_info(cf->wth);
idb_inf = wtap_file_get_idb_info(cf->wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
/* Determine what file encapsulation type we should use. */
encap = wtap_dump_file_encap_type(cf->linktypes);
@@ -4920,10 +4930,10 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
from which we're reading the packets that we're writing!) */
fname_new = g_strdup_printf("%s~", fname);
pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
} else {
pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
}
g_free(idb_inf);
idb_inf = NULL;
diff --git a/mergecap.c b/mergecap.c
index 2af10dea19..3f1d192891 100644
--- a/mergecap.c
+++ b/mergecap.c
@@ -524,7 +524,7 @@ DIAG_ON(cast-qual)
}
pdh = wtap_dump_fdopen_ng(out_fd, file_type, frame_type, snaplen,
- FALSE /* compressed */, shb_hdr, idb_inf, &open_err);
+ FALSE /* compressed */, shb_hdr, idb_inf, NULL, &open_err);
g_string_free(comment_gstr, TRUE);
} else {
pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, FALSE /* compressed */, &open_err);
diff --git a/reordercap.c b/reordercap.c
index 4c64033926..a5d936cead 100644
--- a/reordercap.c
+++ b/reordercap.c
@@ -191,8 +191,9 @@ main(int argc, char *argv[])
guint wrong_order_count = 0;
gboolean write_output_regardless = TRUE;
guint i;
- wtapng_section_t *shb_hdr;
- wtapng_iface_descriptions_t *idb_inf;
+ wtapng_section_t *shb_hdr = NULL;
+ wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
GPtrArray *frames;
FrameRecord_t *prevFrame = NULL;
@@ -275,15 +276,19 @@ DIAG_ON(cast-qual)
shb_hdr = wtap_file_get_shb_info(wth);
idb_inf = wtap_file_get_idb_info(wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(wth);
/* Open outfile (same filetype/encap as input file) */
pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth),
- 65535, FALSE, shb_hdr, idb_inf, &err);
+ 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err);
g_free(idb_inf);
+ idb_inf = NULL;
+
if (pdh == NULL) {
fprintf(stderr, "reordercap: Failed to open output file: (%s) - error %s\n",
outfile, wtap_strerror(err));
g_free(shb_hdr);
+ wtap_free_nrb(nrb_hdr);
exit(1);
}
@@ -357,9 +362,11 @@ DIAG_ON(cast-qual)
fprintf(stderr, "reordercap: Error closing %s: %s\n", outfile,
wtap_strerror(err));
g_free(shb_hdr);
+ wtap_free_nrb(nrb_hdr);
exit(1);
}
g_free(shb_hdr);
+ wtap_free_nrb(nrb_hdr);
/* Finally, close infile */
wtap_fdclose(wth);
diff --git a/tshark.c b/tshark.c
index 4b363c3b8e..20cb6694db 100644
--- a/tshark.c
+++ b/tshark.c
@@ -3134,8 +3134,9 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
char *save_file_string = NULL;
gboolean filtering_tap_listeners;
guint tap_flags;
- wtapng_section_t *shb_hdr;
- wtapng_iface_descriptions_t *idb_inf;
+ wtapng_section_t *shb_hdr = NULL;
+ wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
char *appname = NULL;
struct wtap_pkthdr phdr;
Buffer buf;
@@ -3164,6 +3165,9 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
/* Snapshot length of input file not known. */
snapshot_length = WTAP_MAX_PACKET_SIZE;
}
+
+ nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
+
/* If we don't have an application name add Tshark */
if (shb_hdr->shb_user_appl == NULL) {
appname = g_strdup_printf("TShark (Wireshark) %s", get_ws_vcs_version_info());
@@ -3176,7 +3180,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
snapshot_length, FALSE /* compressed */, &err);
else
pdh = wtap_dump_open_ng(save_file, out_file_type, linktype,
- snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, &err);
+ snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
g_free(idb_inf);
idb_inf = NULL;
@@ -3380,6 +3384,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
wtap_dump_close(pdh, &err);
g_free(shb_hdr);
g_free(appname);
+ wtap_free_nrb(nrb_hdr);
exit(2);
}
}
@@ -3485,6 +3490,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
wtap_dump_close(pdh, &err);
g_free(shb_hdr);
g_free(appname);
+ wtap_free_nrb(nrb_hdr);
exit(2);
}
}
@@ -3599,6 +3605,7 @@ out:
g_free(save_file_string);
g_free(shb_hdr);
g_free(appname);
+ wtap_free_nrb(nrb_hdr);
return err;
}
diff --git a/ui/gtk/file_import_dlg.c b/ui/gtk/file_import_dlg.c
index fd7e2f5d8c..06e3a5790b 100644
--- a/ui/gtk/file_import_dlg.c
+++ b/ui/gtk/file_import_dlg.c
@@ -518,7 +518,9 @@ file_import_open(text_import_info_t *info)
g_array_append_val(idb_inf->interface_data, int_data);
- info->wdh = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, info->encapsulation, info->max_frame_length, FALSE, shb_hdr, idb_inf, &err);
+ info->wdh = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, info->encapsulation,
+ info->max_frame_length, FALSE,
+ shb_hdr, idb_inf, NULL, &err);
if (info->wdh == NULL) {
open_failure_alert_box(capfile_name, err, TRUE);
fclose(info->import_text_file);
diff --git a/ui/qt/resolved_addresses_dialog.cpp b/ui/qt/resolved_addresses_dialog.cpp
index 43334e2c5b..f9f06a189d 100644
--- a/ui/qt/resolved_addresses_dialog.cpp
+++ b/ui/qt/resolved_addresses_dialog.cpp
@@ -29,6 +29,7 @@
#include "file.h"
#include "epan/addr_resolv.h"
+#include <wiretap/wtap.h>
#include <QMenu>
#include <QPushButton>
@@ -193,6 +194,14 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, CaptureFile *c
ui->plainTextEdit->setWordWrapMode(QTextOption::NoWrap);
ui->plainTextEdit->setTabStopWidth(ui->plainTextEdit->fontMetrics().averageCharWidth() * 8);
+ if (capture_file->isValid()) {
+ wtap* wth = capture_file->capFile()->wth;
+ if (wth) {
+ // might return null
+ comment_ = wtap_get_nrb_comment(wth);
+ }
+ }
+
GHashTable *ipv4_hash_table = get_ipv4_hash_table();
if (ipv4_hash_table) {
g_hash_table_foreach(ipv4_hash_table, ipv4_hash_table_resolved_to_qstringlist, &host_addresses_);
@@ -265,6 +274,7 @@ void ResolvedAddressesDialog::fillShowMenu()
show_menu->clear();
show_menu->addAction(ui->actionAddressesHosts);
+ show_menu->addAction(ui->actionComment);
show_menu->addAction(ui->actionIPv4HashTable);
show_menu->addAction(ui->actionIPv6HashTable);
show_menu->addAction(ui->actionPortNames);
@@ -285,6 +295,19 @@ void ResolvedAddressesDialog::fillBlocks()
QString lines;
ui->plainTextEdit->appendPlainText(tr("# Resolved addresses found in %1").arg(file_name_));
+ if (ui->actionComment->isChecked()) {
+ lines = "\n";
+ lines.append(tr("# Comments\n#\n# "));
+ if (!comment_.isEmpty()) {
+ lines.append("\n\n");
+ lines.append(comment_);
+ lines.append("\n");
+ } else {
+ lines.append(no_entries_);
+ }
+ ui->plainTextEdit->appendPlainText(lines);
+ }
+
if (ui->actionAddressesHosts->isChecked()) {
lines = "\n";
lines.append(tr("# Hosts\n#\n# "));
@@ -385,6 +408,11 @@ void ResolvedAddressesDialog::on_actionAddressesHosts_triggered()
fillBlocks();
}
+void ResolvedAddressesDialog::on_actionComment_triggered()
+{
+ fillBlocks();
+}
+
void ResolvedAddressesDialog::on_actionIPv4HashTable_triggered()
{
fillBlocks();
@@ -418,6 +446,7 @@ void ResolvedAddressesDialog::on_actionEthernetWKA_triggered()
void ResolvedAddressesDialog::on_actionShowAll_triggered()
{
ui->actionAddressesHosts->setChecked(true);
+ ui->actionComment->setChecked(true);
ui->actionIPv4HashTable->setChecked(true);
ui->actionIPv6HashTable->setChecked(true);
ui->actionPortNames->setChecked(true);
@@ -431,6 +460,7 @@ void ResolvedAddressesDialog::on_actionShowAll_triggered()
void ResolvedAddressesDialog::on_actionHideAll_triggered()
{
ui->actionAddressesHosts->setChecked(false);
+ ui->actionComment->setChecked(false);
ui->actionIPv4HashTable->setChecked(false);
ui->actionIPv6HashTable->setChecked(false);
ui->actionPortNames->setChecked(false);
diff --git a/ui/qt/resolved_addresses_dialog.h b/ui/qt/resolved_addresses_dialog.h
index 01aef1e4a0..d268b28017 100644
--- a/ui/qt/resolved_addresses_dialog.h
+++ b/ui/qt/resolved_addresses_dialog.h
@@ -44,6 +44,7 @@ protected slots:
private slots:
void on_actionAddressesHosts_triggered();
+ void on_actionComment_triggered();
void on_actionIPv4HashTable_triggered();
void on_actionIPv6HashTable_triggered();
void on_actionPortNames_triggered();
@@ -57,6 +58,7 @@ private slots:
private:
Ui::ResolvedAddressesDialog *ui;
QString file_name_;
+ QString comment_;
QStringList host_addresses_;
QStringList v4_hash_addrs_;
QStringList v6_hash_addrs_;
diff --git a/ui/qt/resolved_addresses_dialog.ui b/ui/qt/resolved_addresses_dialog.ui
index 7e174085ac..c5ab5c6946 100644
--- a/ui/qt/resolved_addresses_dialog.ui
+++ b/ui/qt/resolved_addresses_dialog.ui
@@ -28,6 +28,20 @@
</widget>
</item>
</layout>
+ <action name="actionComment">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Comment</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the comment.</string>
+ </property>
+ </action>
<action name="actionIPv4HashTable">
<property name="checkable">
<bool>true</bool>
diff --git a/ui/tap_export_pdu.c b/ui/tap_export_pdu.c
index 7a315a8b29..0055c1290f 100644
--- a/ui/tap_export_pdu.c
+++ b/ui/tap_export_pdu.c
@@ -163,7 +163,9 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
g_array_append_val(idb_inf->interface_data, int_data);
- exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, &err);
+ exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
+ WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE,
+ FALSE, shb_hdr, idb_inf, NULL, &err);
if (exp_pdu_tap_data->wdh == NULL) {
open_failure_alert_box(capfile_name, err, TRUE);
goto end;
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index 79cddb3ec0..527fa34574 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -2143,12 +2143,13 @@ wtap_dumper *
wtap_dump_open(const char *filename, int file_type_subtype, int encap,
int snaplen, gboolean compressed, int *err)
{
- return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, err);
+ return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
}
static wtap_dumper *
wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
- wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+ wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtapng_name_res_t *nrb_hdr, int *err)
{
wtap_dumper *wdh;
@@ -2159,6 +2160,8 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co
/* Set Section Header Block data */
wdh->shb_hdr = shb_hdr;
+ /* Set Name Resolution Block data */
+ wdh->nrb_hdr = nrb_hdr;
/* Set Interface Description Block data */
if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
wdh->interface_data = idb_inf->interface_data;
@@ -2189,7 +2192,8 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co
wtap_dumper *
wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
- int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+ int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtapng_name_res_t *nrb_hdr, int *err)
{
wtap_dumper *wdh;
WFILE_T fh;
@@ -2201,7 +2205,7 @@ wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
/* Allocate and initialize a data structure for the output stream. */
wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
- shb_hdr, idb_inf, err);
+ shb_hdr, idb_inf, nrb_hdr, err);
if (wdh == NULL)
return NULL;
@@ -2251,12 +2255,13 @@ wtap_dumper *
wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
gboolean compressed, int *err)
{
- return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, err);
+ return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
}
wtap_dumper *
wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
- gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+ gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtapng_name_res_t *nrb_hdr, int *err)
{
wtap_dumper *wdh;
WFILE_T fh;
@@ -2268,7 +2273,7 @@ wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
/* Allocate and initialize a data structure for the output stream. */
wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
- shb_hdr, idb_inf, err);
+ shb_hdr, idb_inf, nrb_hdr, err);
if (wdh == NULL)
return NULL;
diff --git a/wiretap/nettrace_3gpp_32_423.c b/wiretap/nettrace_3gpp_32_423.c
index 8af96939de..36a76a0207 100644
--- a/wiretap/nettrace_3gpp_32_423.c
+++ b/wiretap/nettrace_3gpp_32_423.c
@@ -344,7 +344,8 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
g_array_append_val(idb_inf->interface_data, int_data);
- wdh_exp_pdu = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, &exp_pdu_file_err);
+ wdh_exp_pdu = wtap_dump_fdopen_ng(import_file_fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU,
+ WTAP_MAX_PACKET_SIZE, FALSE, shb_hdr, idb_inf, NULL, &exp_pdu_file_err);
if (wdh_exp_pdu == NULL) {
return WTAP_OPEN_ERROR;
}
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index ad1840b4ce..fe1bef44de 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -66,7 +66,7 @@ static void
pcapng_close(wtap *wth);
-/* pcapng: common block header for every block type */
+/* pcapng: common block header file encoding for every block type */
typedef struct pcapng_block_header_s {
guint32 block_type;
guint32 block_total_length;
@@ -91,7 +91,7 @@ typedef struct pcapng_block_header_s {
*/
#define MAX_BLOCK_SIZE (16*1024*1024)
-/* pcapng: section header block */
+/* pcapng: section header block file encoding */
typedef struct pcapng_section_header_block_s {
/* pcapng_block_header_t */
guint32 magic;
@@ -106,7 +106,7 @@ typedef struct pcapng_section_header_block_s {
*/
#define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
-/* pcapng: interface description block */
+/* pcapng: interface description block file encoding */
typedef struct pcapng_interface_description_block_s {
guint16 linktype;
guint16 reserved;
@@ -119,7 +119,7 @@ typedef struct pcapng_interface_description_block_s {
*/
#define MIN_IDB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
-/* pcapng: packet block (obsolete) */
+/* pcapng: packet block file encoding (obsolete) */
typedef struct pcapng_packet_block_s {
guint16 interface_id;
guint16 drops_count;
@@ -137,7 +137,7 @@ typedef struct pcapng_packet_block_s {
*/
#define MIN_PB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
-/* pcapng: enhanced packet block */
+/* pcapng: enhanced packet block file encoding */
typedef struct pcapng_enhanced_packet_block_s {
guint32 interface_id;
guint32 timestamp_high;
@@ -154,7 +154,7 @@ typedef struct pcapng_enhanced_packet_block_s {
*/
#define MIN_EPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
-/* pcapng: simple packet block */
+/* pcapng: simple packet block file encoding */
typedef struct pcapng_simple_packet_block_s {
guint32 packet_len;
/* ... Packet Data ... */
@@ -166,7 +166,7 @@ typedef struct pcapng_simple_packet_block_s {
*/
#define MIN_SPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
-/* pcapng: name resolution block */
+/* pcapng: name resolution block file encoding */
typedef struct pcapng_name_resolution_block_s {
guint16 record_type;
guint16 record_len;
@@ -179,7 +179,7 @@ typedef struct pcapng_name_resolution_block_s {
*/
#define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
-/* pcapng: interface statistics block */
+/* pcapng: interface statistics block file encoding */
typedef struct pcapng_interface_statistics_block_s {
guint32 interface_id;
guint32 timestamp_high;
@@ -192,7 +192,7 @@ typedef struct pcapng_interface_statistics_block_s {
*/
#define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
-/* pcapng: common option header for every option type */
+/* pcapng: common option header file encoding for every option type */
typedef struct pcapng_option_header_s {
guint16 option_code;
guint16 option_length;
@@ -205,22 +205,6 @@ struct option {
guint16 value_length;
};
-/* Block types */
-#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
-#define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */
-#define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */
-#define BLOCK_TYPE_NRB 0x00000004 /* Name Resolution Block */
-#define BLOCK_TYPE_ISB 0x00000005 /* Interface Statistics Block */
-#define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */
-#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
-/* TODO: the following are not yet well defined in the draft spec:
- * Compression Block
- * Encryption Block
- * Fixed Length Block
- * Directory Block
- * Traffic Statistics and Monitoring Blocks
- * Event/Security Block
- */
/* Option codes: 16-bit field */
#define OPT_EOFOPT 0x0000
@@ -263,70 +247,9 @@ struct option {
/* MSBit of option code means "local type" */
#define OPT_LOCAL_FLAG 0x8000
+/* Note: many of the defined structures for block data are defined in wtap.h */
-/* Capture section */
-#if 0
-/* Moved to wtap.h */
-typedef struct wtapng_section_s {
- /* mandatory */
- guint64 section_length;
- /* options */
- gchar *opt_comment; /* NULL if not available */
- gchar *shb_hardware; /* NULL if not available */
- gchar *shb_os; /* NULL if not available */
- gchar *shb_user_appl; /* NULL if not available */
-} wtapng_section_t;
-#endif
-
-#if 0
-/* Moved to wtap.h */
-
-/* Interface Description
- *
- * Options:
- * if_name 2 A UTF-8 string containing the name of the device used to capture data. "eth0" / "\Device\NPF_{AD1CE675-96D0-47C5-ADD0-2504B9126B68}" / ...
- * if_description 3 A UTF-8 string containing the description of the device used to capture data. "Broadcom NetXtreme" / "First Ethernet Interface" / ...
- * if_IPv4addr 4 Interface network address and netmask. This option can be repeated multiple times within the same Interface Description Block when multiple IPv4 addresses are assigned to the interface. 192 168 1 1 255 255 255 0
- * if_IPv6addr 5 Interface network address and prefix length (stored in the last byte). This option can be repeated multiple times within the same Interface Description Block when multiple IPv6 addresses are assigned to the interface. 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44 40"
- * if_MACaddr 6 Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
- * if_EUIaddr 7 Interface Hardware EUI address (64 bits), if available. TODO: give a good example
- * if_speed 8 Interface speed (in bps). 100000000 for 100Mbps
- * if_tsresol 9 Resolution of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the resolution of the timestamp as as a negative power of 10 (e.g. 6 means microsecond resolution, timestamps are the number of microseconds since 1/1/1970). If the Most Significant Bit is equal to one, the remaining bits indicates the resolution as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a resolution of 10^-6 is assumed (i.e. timestamps have the same resolution of the standard 'libpcap' timestamps). 6
- * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
- * if_filter 11 The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO). (TODO: better use different options for different fields? e.g. if_filter_pcap, if_filter_bpf, ...) 00 "tcp port 23 and host 10.0.0.5"
- * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed. This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory))) because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
- * if_fcslen 13 An integer value that specified the length of the Frame Check Sequence (in bits) for this interface. For link layers whose FCS length can change during time, the Packet Block Flags Word can be used (see Appendix A (Packet Block Flags Word)). 4
- * if_tsoffset 14 A 64 bits integer value that specifies an offset (in seconds) that must be added to the timestamp of each packet to obtain the absolute timestamp of a packet. If the option is missing, the timestamps stored in the packet must be considered absolute timestamps. The time zone of the offset can be specified with the option if_tzone. TODO: won't a if_tsoffset_low for fractional second offsets be useful for highly synchronized capture systems? 1234
- */
-
-typedef struct wtapng_if_descr_s {
- /* mandatory */
- guint16 link_type;
- guint encap;
- guint32 snap_len;
- /* options */
- gchar *opt_comment; /* NULL if not available */
- gchar *if_name; /* NULL if not available, opt 2 A UTF-8 string containing the name of the device used to capture data. */
- gchar *if_description; /* NULL if not available, opt 3 A UTF-8 string containing the description of the device used to capture data. */
- /* XXX: if_IPv4addr opt 4 Interface network address and netmask.*/
- /* XXX: if_IPv6addr opt 5 Interface network address and prefix length (stored in the last byte).*/
- /* XXX: if_MACaddr opt 6 Interface Hardware MAC address (48 bits).*/
- /* XXX: if_EUIaddr opt 7 Interface Hardware EUI address (64 bits)*/
- guint64 if_speed; /* 0 if unknown, opt 8 Interface speed (in bps). 100000000 for 100Mbps */
- guint8 if_tsresol; /* default is 6 for microsecond resolution, opt 9 Resolution of timestamps.
- * If the Most Significant Bit is equal to zero, the remaining bits indicates the resolution of the timestamp as as a negative power of 10
- */
- /* XXX: if_tzone 10 Time zone for GMT support (TODO: specify better). */
- gchar *if_filter; /* NULL if not available, opt 11 The filter (e.g. "capture only TCP traffic") used to capture traffic.
- * The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more).
- */
- gchar *if_os; /* NULL if not available, 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed. */
- gint8 if_fcslen; /* -1 if unknown or changes between packets, opt 13 An integer value that specified the length of the Frame Check Sequence (in bits) for this interface. */
- /* XXX: guint64 if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/
-} wtapng_if_descr_t;
-#endif
-
-/* Packets */
+/* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
typedef struct wtapng_packet_s {
/* mandatory */
guint32 ts_high; /* seconds since 1.1.1970 */
@@ -340,7 +263,7 @@ typedef struct wtapng_packet_s {
/* XXX - put the packet data / pseudo_header here as well? */
} wtapng_packet_t;
-/* Simple Packets */
+/* Simple Packet data */
typedef struct wtapng_simple_packet_s {
/* mandatory */
guint32 cap_len; /* data length in the file */
@@ -348,34 +271,9 @@ typedef struct wtapng_simple_packet_s {
/* XXX - put the packet data / pseudo_header here as well? */
} wtapng_simple_packet_t;
-/* Name Resolution */
-typedef struct wtapng_name_res_s {
- /* options */
- gchar *opt_comment; /* NULL if not available */
- /* XXX */
-} wtapng_name_res_t;
-
-#if 0
-/* Interface Statistics moved to wtap.h*/
-typedef struct wtapng_if_stats_s {
- /* mandatory */
- guint32 interface_id;
- guint32 ts_high;
- guint32 ts_low;
- /* options */
- gchar *opt_comment; /* NULL if not available */
- guint64 isb_starttime;
- guint64 isb_endtime;
- guint64 isb_ifrecv;
- guint64 isb_ifdrop;
- guint64 isb_filteraccept;
- guint64 isb_osdrop;
- guint64 isb_usrdeliv;
-} wtapng_if_stats_t;
-#endif
-
+/* Block data to be passed between functions during reading */
typedef struct wtapng_block_s {
- guint32 type; /* block_type as defined by pcapng */
+ guint32 type; /* block_type as defined by pcapng */
union {
wtapng_section_t section;
wtapng_if_descr_t if_descr;
@@ -1739,9 +1637,15 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
pcapng_name_resolution_block_t nrb;
Buffer nrb_rec;
guint32 v4_addr;
- guint record_len;
+ guint record_len, opt_cont_buf_len;
char *namep;
int namelen;
+ int bytes_read;
+ pcapng_option_header_t oh;
+ guint8 *option_content;
+#ifdef HAVE_PLUGINS
+ option_handler handler;
+#endif
/*
* Is this block long enough to be an NRB?
@@ -1771,7 +1675,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
return FALSE;
}
- to_read = bh->block_total_length - 8 - 4; /* We have read the header adn should not read the final block_total_length */
+ to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
pcapng_debug1("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
@@ -1953,6 +1857,79 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
}
}
+ /* Options
+ * opt_comment 1
+ *
+ * TODO:
+ * ns_dnsname 2
+ * ns_dnsIP4addr 3
+ * ns_dnsIP6addr 4
+ */
+
+ /* Allocate enough memory to hold all options */
+ opt_cont_buf_len = to_read;
+ option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
+ if (opt_cont_buf_len != 0 && option_content == NULL) {
+ *err = ENOMEM; /* we assume we're out of memory */
+ ws_buffer_free(&nrb_rec);
+ return FALSE;
+ }
+
+ while (to_read != 0) {
+ /* read option */
+ bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
+ if (bytes_read <= 0) {
+ pcapng_debug0("pcapng_read_name_resolution_block: failed to read option");
+ g_free(option_content);
+ ws_buffer_free(&nrb_rec);
+ return FALSE;
+ }
+ to_read -= bytes_read;
+
+ /* handle option content */
+ switch (oh.option_code) {
+ case(OPT_EOFOPT):
+ if (to_read != 0) {
+ pcapng_debug1("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
+ }
+ /* padding should be ok here, just get out of this */
+ to_read = 0;
+ break;
+ case(OPT_COMMENT):
+ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+ wblock->data.name_res.opt_comment = g_strndup((char *)option_content, oh.option_length);
+ pcapng_debug2("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, wblock->data.name_res.opt_comment);
+ } else {
+ pcapng_debug1("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
+ }
+ break;
+ break;
+ default:
+#ifdef HAVE_PLUGINS
+ /*
+ * Do we have a handler for this network resolution block option code?
+ */
+ if (option_handlers[BT_INDEX_NRB] != NULL &&
+ (handler = (option_handler)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
+ GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
+ /* Yes - call the handler. */
+ if (!handler(pn->byte_swapped, oh.option_length,
+ option_content, err, err_info)) {
+
+ g_free(option_content);
+ ws_buffer_free(&nrb_rec);
+ return FALSE;
+ }
+ } else
+#endif
+ {
+ pcapng_debug2("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
+ oh.option_code, oh.option_length);
+ }
+ }
+ }
+
+ g_free(option_content);
ws_buffer_free(&nrb_rec);
return TRUE;
}
@@ -3752,6 +3729,84 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
wdh->addrinfo_lists->ipv6_addr_list = NULL;
}
+ /* add options, if any */
+ if (wdh->nrb_hdr) {
+ gboolean have_options = FALSE;
+ guint32 options_total_length = 0;
+ struct option option_hdr;
+ guint32 comment_len = 0, comment_pad_len = 0;
+ wtapng_name_res_t *nrb_hdr = wdh->nrb_hdr;
+ gint prev_rec_off = rec_off;
+
+ /* get lengths first to make sure we can fit this into the block */
+ if (nrb_hdr->opt_comment) {
+ have_options = TRUE;
+ comment_len = (guint32)strlen(nrb_hdr->opt_comment) & 0xffff;
+ if ((comment_len % 4)) {
+ comment_pad_len = 4 - (comment_len % 4);
+ } else {
+ comment_pad_len = 0;
+ }
+ options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
+ }
+
+ if (have_options) {
+ /* End-of options tag */
+ options_total_length += 4;
+
+ if (rec_off + options_total_length > NRES_REC_MAX_SIZE) {
+ /* Too much; copy the block header. */
+ memcpy(rec_data, &bh, sizeof(bh));
+
+ /* End of record */
+ memset(rec_data + rec_off, 0, 4);
+ rec_off += 4;
+
+ memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length));
+
+ pcapng_debug2("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off);
+
+ if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
+ g_free(rec_data);
+ return FALSE;
+ }
+ wdh->bytes_dumped += bh.block_total_length;
+
+ /*Start a new NRB */
+ prev_rec_off = rec_off = 8; /* block type + block total length */
+ bh.block_type = BLOCK_TYPE_NRB;
+ bh.block_total_length = rec_off + 8; /* end-of-record + block total length */
+ }
+
+ bh.block_total_length += options_total_length;
+
+ if (comment_len > 0) {
+ option_hdr.type = OPT_COMMENT;
+ option_hdr.value_length = comment_len;
+
+ memcpy(rec_data + rec_off, &option_hdr, sizeof(option_hdr));
+ rec_off += sizeof(option_hdr);
+
+ /* Write the comments string */
+ memcpy(rec_data + rec_off, nrb_hdr->opt_comment, comment_len);
+ rec_off += comment_len;
+ memset(rec_data + rec_off, 0, comment_pad_len);
+ rec_off += comment_pad_len;
+
+ pcapng_debug2("pcapng_write_name_resolution_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
+ comment_len,
+ comment_pad_len);
+ }
+
+ /* Write end of options */
+ memset(rec_data + rec_off, 0, 4);
+ rec_off += 4;
+
+ /* sanity check */
+ g_assert((gint)options_total_length == rec_off - prev_rec_off);
+ }
+ }
+
/* We know the total length now; copy the block header. */
memcpy(rec_data, &bh, sizeof(bh));
diff --git a/wiretap/pcapng_module.h b/wiretap/pcapng_module.h
index ef5701678b..1707a4d04f 100644
--- a/wiretap/pcapng_module.h
+++ b/wiretap/pcapng_module.h
@@ -21,6 +21,23 @@
#ifndef __PCAP_MODULE_H__
#define __PCAP_MODULE_H__
+/* Block type codes in the file */
+#define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
+#define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */
+#define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */
+#define BLOCK_TYPE_NRB 0x00000004 /* Name Resolution Block */
+#define BLOCK_TYPE_ISB 0x00000005 /* Interface Statistics Block */
+#define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */
+#define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
+/* TODO: the following are not yet well defined in the draft spec:
+ * Compression Block
+ * Encryption Block
+ * Fixed Length Block
+ * Directory Block
+ * Traffic Statistics and Monitoring Blocks
+ * Event/Security Block
+ */
+
/*
* Reader and writer routines for pcap-ng block types.
*/
diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h
index c98e4572a0..01f0ecdeb5 100644
--- a/wiretap/wtap-int.h
+++ b/wiretap/wtap-int.h
@@ -53,6 +53,7 @@ struct wtap {
struct wtapng_section_s shb_hdr;
guint number_of_interfaces; /**< The number of interfaces a capture was made on, number of IDB:s in a pcapng file or equivalent(?)*/
GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?)*/
+ wtapng_name_res_t *nrb_hdr; /**< holds the Name Res Block's comment/custom_opts, or NULL */
void *priv; /* this one holds per-file state and is free'd automatically by wtap_close() */
void *wslua_data; /* this one holds wslua state info and is not free'd */
@@ -111,9 +112,10 @@ struct wtap_dumper {
int tsprecision; /**< timestamp precision of the lower 32bits
* e.g. WTAP_TSPREC_USEC
*/
- addrinfo_lists_t *addrinfo_lists; /**< Struct containing lists of resolved addresses */
- struct wtapng_section_s *shb_hdr;
- GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?) NULL if not present.*/
+ addrinfo_lists_t *addrinfo_lists; /**< Struct containing lists of resolved addresses */
+ wtapng_section_t *shb_hdr;
+ wtapng_name_res_t *nrb_hdr; /**< name resolution comment/custom_opt, or NULL */
+ GArray *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?) NULL if not present.*/
};
WS_DLL_PUBLIC gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf,
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index 897f0944cb..02ca1780a4 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -186,6 +186,39 @@ wtap_file_get_shb_info(wtap *wth)
return shb_hdr;
}
+const gchar*
+wtap_get_nrb_comment(wtap *wth)
+{
+ g_assert(wth);
+
+ if (wth == NULL)
+ return NULL;
+
+ return wth->nrb_hdr ? wth->nrb_hdr->opt_comment : NULL;
+}
+
+void
+wtap_write_nrb_comment(wtap *wth, gchar *comment)
+{
+ g_assert(wth);
+
+ if (wth == NULL)
+ return;
+
+ if (wth->nrb_hdr == NULL) {
+ wth->nrb_hdr = g_new0(wtapng_name_res_t,1);
+ } else {
+ g_free(wth->nrb_hdr->opt_comment);
+ }
+
+ /*
+ * I'd prefer this function duplicate the passed-in comment,
+ * but wtap_write_shb_comment() assumes the caller duplicated
+ * it so we'll stick with that.
+ */
+ wth->nrb_hdr->opt_comment = comment;
+}
+
void
wtap_write_shb_comment(wtap *wth, gchar *comment)
{
@@ -206,6 +239,32 @@ wtap_file_get_idb_info(wtap *wth)
return idb_info;
}
+wtapng_name_res_t *
+wtap_file_get_nrb_for_new_file(wtap *wth)
+{
+ wtapng_name_res_t *nrb_hdr;
+
+ if (wth == NULL || wth->nrb_hdr == NULL)
+ return NULL;
+
+ nrb_hdr = g_new0(wtapng_name_res_t,1);
+
+ nrb_hdr->opt_comment = g_strdup(wth->nrb_hdr->opt_comment);
+
+ return nrb_hdr;
+}
+
+void
+wtap_free_nrb(wtapng_name_res_t *nrb_hdr)
+{
+ if (nrb_hdr == NULL)
+ return;
+
+ g_free(nrb_hdr->opt_comment);
+ g_free(nrb_hdr);
+}
+
+
/* Table of the encapsulation types we know about. */
struct encap_type_info {
const char *name;
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 9f9f4871d1..0fc273e61e 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1396,6 +1396,14 @@ typedef struct wtapng_if_stats_s {
} wtapng_if_stats_t;
+/* Name Resolution, pcap-ng Name Resolution Block (NRB). */
+typedef struct wtapng_name_res_s {
+ /* options */
+ gchar *opt_comment; /**< NULL if not available */
+ /* XXX */
+} wtapng_name_res_t;
+
+
/** A struct with lists of resolved addresses.
* Used when writing name resoultion blocks (NRB)
*/
@@ -1653,8 +1661,64 @@ WS_DLL_PUBLIC
int wtap_file_tsprec(wtap *wth);
WS_DLL_PUBLIC
wtapng_section_t* wtap_file_get_shb_info(wtap *wth);
+
+/**
+ * @brief Gets existing interface descriptions.
+ * @details Returns a new struct containing a pointer to the existing
+ * description, without creating new descriptions internally.
+ * @note The returned pointer must be g_free'd, but its internal
+ * interface_data must not.
+ *
+ * @param wth The current wtap.
+ * @return A new struct of the existing section descriptions, which must be g_free'd.
+ */
WS_DLL_PUBLIC
wtapng_iface_descriptions_t *wtap_file_get_idb_info(wtap *wth);
+
+/**
+ * @brief Gets new name resolution info for new file, based on existing info.
+ * @details Creates a new wtapng_name_res_t name resolution info and only
+ * copies appropriate members for a new file.
+ *
+ * @note Use wtap_free_nrb() to free the returned pointer.
+ *
+ * @param wth The current wiretap header.
+ * @return The new name resolution info, which must be wtap_free_nrb'd.
+ */
+WS_DLL_PUBLIC
+wtapng_name_res_t* wtap_file_get_nrb_for_new_file(wtap *wth);
+
+/**
+ * Free's the name resolution info and all of its members.
+ */
+WS_DLL_PUBLIC
+void wtap_free_nrb(wtapng_name_res_t *nrb_hdr);
+
+/**
+ * @brief Gets the name resolution comment, if any.
+ * @details This retrieves the name resolution comment string pointer,
+ * possibly NULL.
+ *
+ * @param wth The wiretap session.
+ * @return The comment string.
+ */
+WS_DLL_PUBLIC
+const gchar* wtap_get_nrb_comment(wtap *wth);
+
+/**
+ * @brief Sets or replaces the name resolution comment.
+ * @details The passed-in comment string is set to be the comment
+ * for the name resolution block. The passed-in string's
+ * ownership will be owned by the block, so it should be
+ * duplicated before passing into this function.
+ *
+ * @param wth The wiretap session.
+ * @param comment The comment string.
+ */
+WS_DLL_PUBLIC
+void wtap_write_nrb_comment(wtap *wth, gchar *comment);
+
+/*** sets/replaces the section header comment ***/
WS_DLL_PUBLIC
void wtap_write_shb_comment(wtap *wth, gchar *comment);
@@ -1705,20 +1769,49 @@ WS_DLL_PUBLIC
gboolean wtap_dump_supports_comment_types(int filetype, guint32 comment_types);
WS_DLL_PUBLIC
-wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
+wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype, int encap,
int snaplen, gboolean compressed, int *err);
+/**
+ * @brief Opens a new capture file for writing.
+ *
+ * @param filename The new file's name.
+ * @param file_type_subtype The WTAP_FILE_TYPE_SUBTYPE_XXX file type.
+ * @param encap The WTAP_ENCAP_XXX encapsulation type (WTAP_ENCAP_PER_PACKET for multi)
+ * @param snaplen The maximum packet capture length.
+ * @param compressed True if file should be compressed.
+ * @param shb_hdr The section header block information, or NULL.
+ * @param idb_inf The interface description information, or NULL.
+ * @param nrb_hdr The name resolution comment/custom_opts information, or NULL.
+ * @param[out] err Will be set to an error code on failure.
+ * @return The newly created dumper object, or NULL on failure.
+ */
WS_DLL_PUBLIC
-wtap_dumper* wtap_dump_open_ng(const char *filename, int filetype, int encap,
- int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err);
+wtap_dumper* wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
+ int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtapng_name_res_t *nrb_hdr, int *err);
WS_DLL_PUBLIC
-wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen,
+wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
gboolean compressed, int *err);
+/**
+ * @brief Creates a dumper for an existing file descriptor.
+ *
+ * @param file_type_subtype The WTAP_FILE_TYPE_SUBTYPE_XXX file type.
+ * @param encap The WTAP_ENCAP_XXX encapsulation type (WTAP_ENCAP_PER_PACKET for multi)
+ * @param snaplen The maximum packet capture length.
+ * @param compressed True if file should be compressed.
+ * @param shb_hdr The section header block information, or NULL.
+ * @param idb_inf The interface description information, or NULL.
+ * @param nrb_hdr The name resolution comment/custom_opts information, or NULL.
+ * @param[out] err Will be set to an error code on failure.
+ * @return The newly created dumper object, or NULL on failure.
+ */
WS_DLL_PUBLIC
-wtap_dumper* wtap_dump_fdopen_ng(int fd, int filetype, int encap, int snaplen,
- gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err);
+wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
+ gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+ wtapng_name_res_t *nrb_hdr, int *err);
WS_DLL_PUBLIC