Add initial pcapng name resolution record support. Wireshark has read

support; TShark has read+write support. Additionally TShark can read a
"hosts" file and write those records to a capture file.

This uses "struct addrinfo" in many places and probably won't compile on
some platforms.

svn path=/trunk/; revision=36318
This commit is contained in:
Gerald Combs 2011-03-24 22:47:57 +00:00
parent 57833dc778
commit fcf51fc73b
13 changed files with 570 additions and 87 deletions

View File

@ -10,6 +10,8 @@ S<[ B<-c> E<lt>packets per fileE<gt> ]>
S<[ B<-C> E<lt>choplenE<gt> ]>
S<[ B<-E> E<lt>error probabilityE<gt> ]>
S<[ B<-F> E<lt>file formatE<gt> ]>
S<[ B<-W> E<lt>file format optionE<gt>]>
S<[ B<-H> E<lt>input hosts file<gt> ]>
S<[ B<-A> E<lt>start timeE<gt> ]>
S<[ B<-B> E<lt>stop timeE<gt> ]>
S<[ B<-h> ]>
@ -150,6 +152,30 @@ B<Editcap> can write the file in several formats, B<editcap -F>
provides a list of the available output formats. The default
is the B<libpcap> format.
=item -W E<lt>file format optionE<gt>
Save extra information in the file if the format supports it. For
example,
-F pcapng -W n
will save host name resolution records along with captured packets.
Future versions of Wireshark may automatically change the capture format to
B<pcapng> as needed.
The argument is a string that may contain the following letter:
B<n> write network address resolution information (pcapng only)
=item -H E<lt>input "hosts" fileE<gt>
Read a list of address to host name mappings and include the result in
the output file. Implies B<-W n>.
The input file format is described at
L<http://en.wikipedia.org/wiki/Hosts_%28file%29>.
=item -A E<lt>start timeE<gt>
Saves only the packets whose timestamp is on or after start time.

View File

@ -18,6 +18,7 @@ S<[ B<-E> E<lt>field print optionE<gt> ]>
S<[ B<-f> E<lt>capture filterE<gt> ]>
S<[ B<-F> E<lt>file formatE<gt> ]>
S<[ B<-h> ]>
S<[ B<-H> E<lt>input hosts fileE<gt> ]>
S<[ B<-i> E<lt>capture interfaceE<gt>|- ]>
S<[ B<-I> ]>
S<[ B<-K> E<lt>keytabE<gt> ]>
@ -37,6 +38,7 @@ S<[ B<-T> pdml|psml|ps|text|fields ]>
S<[ B<-v> ]>
S<[ B<-V> ]>
S<[ B<-w> E<lt>outfileE<gt>|- ]>
S<[ B<-W> E<lt>file format optionE<gt>]>
S<[ B<-x> ]>
S<[ B<-X> E<lt>eXtension optionE<gt>]>
S<[ B<-y> E<lt>capture link typeE<gt> ]>
@ -398,6 +400,14 @@ B<currentprefs> Dumps a copy of the current preferences file to stdout.
Print the version and options and exits.
=item -H E<lt>input hosts fileE<gt>
Read a list of entries from a "hosts" file, which will then be written
to a capture file. Implies B<-W n>.
The "hosts" file format is documented at
L<http://en.wikipedia.org/wiki/Hosts_(file)>.
=item -i E<lt>capture interfaceE<gt> | -
Set the name of the network interface or pipe to use for live packet
@ -617,6 +627,22 @@ NOTE: -w provides raw packet data, not text. If you want text output
you need to redirect stdout (e.g. using '>'), don't use the B<-w>
option for this.
=item -W E<lt>file format optionE<gt>
Save extra information in the file if the format supports it. For
example,
-F pcapng -W n
will save host name resolution records along with captured packets.
Future versions of Wireshark may automatically change the capture format to
B<pcapng> as needed.
The argument is a string that may contain the following letter:
B<n> write network address resolution information (pcapng only)
=item -x
Cause B<TShark> to print a hex and ASCII dump of the packet data

View File

@ -149,6 +149,11 @@
#define HASH_IPV4_ADDRESS(addr) (g_htonl(addr) & (HASHHOSTSIZE - 1))
/*
* XXX Some of this is duplicated in addrinfo_list. We may want to replace the
* addr and name parts with a struct addrinfo or create our own addrinfo-like
* struct that simply points to the data below.
*/
typedef struct hashipv4 {
guint addr;
gboolean is_dummy_entry; /* name is IPv4 address in dot format */
@ -272,6 +277,9 @@ static int ipxnet_resolution_initialized = 0;
static int service_resolution_initialized = 0;
static gboolean new_resolved_objects = FALSE;
static struct addrinfo *addrinfo_list = NULL; /* IPv4 and IPv6 */
static struct addrinfo *addrinfo_list_last = NULL;
static hashether_t *add_eth_name(const guint8 *addr, const gchar *name);
static void add_serv_port_cb(const guint32 port);
@ -2015,7 +2023,7 @@ ipxnet_addr_lookup(const gchar *name, gboolean *success)
} /* ipxnet_addr_lookup */
static gboolean
gboolean
read_hosts_file (const char *hostspath)
{
FILE *hf;
@ -2065,6 +2073,7 @@ read_hosts_file (const char *hostspath)
/*
* Add the aliases, too, if there are any.
* XXX - host_lookup() only returns the first entry.
*/
while ((cp = strtok(NULL, " \t")) != NULL) {
if (is_ipv6) {
@ -2112,6 +2121,10 @@ add_ip_name_from_string (const char *addr, const char *name)
return TRUE;
} /* add_ip_name_from_string */
struct addrinfo *
get_addrinfo_list(void) {
return addrinfo_list;
}
/* Read in a list of subnet definition - name pairs.
* <line> = <comment> | <entry> | <whitespace>
@ -2359,6 +2372,7 @@ subnet_name_lookup_init(void)
g_free(subnetspath);
}
/*
* External Functions
*/
@ -2366,6 +2380,7 @@ subnet_name_lookup_init(void)
void
host_name_lookup_init(void) {
char *hostspath;
struct addrinfo *ai;
#ifdef HAVE_GNU_ADNS
#ifdef _WIN32
@ -2375,6 +2390,11 @@ host_name_lookup_init(void) {
#endif /* _WIN32 */
#endif /*GNU_ADNS */
if (!addrinfo_list) {
ai = g_malloc0(sizeof(struct addrinfo));
addrinfo_list = addrinfo_list_last = ai;
}
/*
* Load the user's hosts file, if they have one.
*/
@ -2392,7 +2412,7 @@ host_name_lookup_init(void) {
report_open_failure(hostspath, errno, FALSE);
}
g_free(hostspath);
#ifdef HAVE_C_ARES
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
if (ares_library_init(ARES_LIB_INIT_ALL) == ARES_SUCCESS) {
@ -2646,6 +2666,8 @@ add_ipv4_name(const guint addr, const gchar *name)
{
int hash_idx;
hashipv4_t *tp;
struct addrinfo *ai;
struct sockaddr_in *sa4;
hash_idx = HASH_IPV4_ADDRESS(addr);
@ -2675,6 +2697,25 @@ add_ipv4_name(const guint addr, const gchar *name)
g_strlcpy(tp->name, name, MAXNAMELEN);
tp->resolve = TRUE;
new_resolved_objects = TRUE;
if (!addrinfo_list) {
ai = g_malloc0(sizeof(struct addrinfo));
addrinfo_list = addrinfo_list_last = ai;
}
sa4 = g_malloc0(sizeof(struct sockaddr_in));
sa4->sin_family = AF_INET;
sa4->sin_addr.s_addr = addr;
ai = g_malloc0(sizeof(struct addrinfo));
ai->ai_family = AF_INET;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_canonname = (char *) tp->name;
ai->ai_addr = (struct sockaddr*) sa4;
addrinfo_list_last->ai_next = ai;
addrinfo_list_last = ai;
} /* add_ipv4_name */
/* -------------------------- */
@ -2683,6 +2724,8 @@ add_ipv6_name(const struct e_in6_addr *addrp, const gchar *name)
{
int hash_idx;
hashipv6_t *tp;
struct addrinfo *ai;
struct sockaddr_in6 *sa6;
hash_idx = HASH_IPV6_ADDRESS(*addrp);
@ -2709,11 +2752,28 @@ add_ipv6_name(const struct e_in6_addr *addrp, const gchar *name)
tp = tp->next;
}
}
g_strlcpy(tp->name, name, MAXNAMELEN);
tp->resolve = TRUE;
new_resolved_objects = TRUE;
if (!addrinfo_list) {
ai = g_malloc0(sizeof(struct addrinfo));
addrinfo_list = addrinfo_list_last = ai;
}
sa6 = g_malloc0(sizeof(struct sockaddr_in6));
sa6->sin6_family = AF_INET;
memcpy(sa6->sin6_addr.s6_addr, addrp, 16);
ai = g_malloc0(sizeof(struct addrinfo));
ai->ai_family = AF_INET6;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_canonname = (char *) tp->name;
ai->ai_addr = (struct sockaddr *) sa6;
addrinfo_list_last->ai_next = ai;
addrinfo_list_last = ai;
} /* add_ipv6_name */
/* -----------------

View File

@ -176,9 +176,40 @@ extern void add_ipv4_name(const guint addr, const gchar *name);
/* adds a hostname/IPv6 in the hash table */
extern void add_ipv6_name(const struct e_in6_addr *addr, const gchar *name);
/* read a "hosts" file and add its entries to the IPv4 & IPv6 hash tables */
extern gboolean read_hosts_file (const char *hostspath);
/* adds a hostname in the hash table */
extern gboolean add_ip_name_from_string (const char *addr, const char *name);
/** Get a list of host name to address mappings we know about.
*
* Each list element is an addrinfo struct with the following fields defined:
* - ai_family: 0, AF_INET or AF_INET6
* - ai_addrlen: Length of ai_addr
* - ai_canonname: Host name or NULL
* - ai_addr: Pointer to a struct sockaddr or NULL (see below)
* - ai_next: Next element or NULL
* All other fields are zero-filled.
*
* If ai_family is 0, this is a dummy entry which should only appear at the beginning of the list.
*
* If ai_family is AF_INET, ai_addr points to a struct sockaddr_in with the following fields defined:
* - sin_family: AF_INET
* - sin_addr: Host IPv4 address
* All other fields are zero-filled.
*
* If ai_family is AF_INET6, ai_addr points to a struct sockaddr_in6 with the following fields defined:
* - sin6_family: AF_INET6
* - sin6_addr: Host IPv6 address
* All other fields are zero-filled.
*
* The list and its elements MUST NOT be modified or freed.
*
* @return The first element in our list of known addresses. May be NULL.
*/
extern struct addrinfo *get_addrinfo_list(void);
/* add ethernet address / name corresponding to IP address */
extern void add_ether_byip(const guint ip, const guint8 *eth);

View File

@ -13,6 +13,8 @@ abs_time_secs_to_str
abs_time_to_str
add_new_data_source
add_ip_name_from_string
add_ipv4_name
add_ipv6_name
add_itu_tcap_subdissector
address_to_str_buf
AdmissionRejectReason_vals DATA
@ -500,6 +502,7 @@ geoip_db_name
geoip_db_num_dbs
geoip_db_type
get_addr_name
get_addrinfo_list
get_asn1_ctx
get_basename
get_ber_identifier
@ -862,6 +865,7 @@ range_copy
range_empty
range_foreach
ranges_are_equal
read_hosts_file
read_keytab_file
read_keytab_file_from_preferences
read_prefs

4
file.c
View File

@ -73,6 +73,7 @@
#include <epan/dfilter/dfilter-macro.h>
#include <wsutil/file_util.h>
#include <epan/strutil.h>
#include <epan/addr_resolv.h>
#ifdef HAVE_LIBPCAP
gboolean auto_scroll_live;
@ -359,6 +360,9 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
ber_set_filename(cf->filename);
}
wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
return CF_OK;
fail:

View File

@ -166,7 +166,7 @@ static void report_counts_siginfo(int);
#endif /* _WIN32 */
#endif /* HAVE_LIBPCAP */
static int load_cap_file(capture_file *, char *, int, int, gint64);
static int load_cap_file(capture_file *, char *, int, gboolean, int, gint64);
static gboolean process_packet(capture_file *cf, gint64 offset,
const struct wtap_pkthdr *whdr, union wtap_pseudo_header *pseudo_header,
const guchar *pd, gboolean filtering_tap_listeners, guint tap_flags);
@ -819,6 +819,7 @@ main(int argc, char *argv[])
#endif
gboolean quiet = FALSE;
int out_file_type = WTAP_FILE_PCAP;
gboolean out_file_name_res = FALSE;
gchar *cf_name = NULL, *rfilter = NULL;
#ifdef HAVE_PCAP_OPEN_DEAD
struct bpf_program fcode;
@ -845,7 +846,7 @@ main(int argc, char *argv[])
#define OPTSTRING_I ""
#endif
#define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:De:E:f:F:G:hi:" OPTSTRING_I "K:lLnN:o:pPqr:R:s:St:T:u:vVw:xX:y:z:"
#define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:De:E:f:F:G:hH:i:" OPTSTRING_I "K:lLnN:o:pPqr:R:s:St:T:u:vVw:W:xX:y:z:"
static const char optstring[] = OPTSTRING;
@ -1159,6 +1160,20 @@ main(int argc, char *argv[])
return 1;
}
break;
case 'W': /* Select extra information to save in our capture file */
/* This is patterned after the -N flag which may not be the best idea. */
if (strchr(optarg, 'n'))
out_file_name_res = TRUE;
break;
case 'H': /* Read address to name mappings from a hosts file */
if (! read_hosts_file(optarg))
{
cmdarg_err("Can't read host entries from \"%s\"", optarg);
return 1;
}
out_file_name_res = TRUE;
break;
case 'h': /* Print help and exit */
print_usage(TRUE);
return 0;
@ -1694,11 +1709,11 @@ main(int argc, char *argv[])
/* Process the packets in the file */
#ifdef HAVE_LIBPCAP
err = load_cap_file(&cfile, global_capture_opts.save_file, out_file_type,
err = load_cap_file(&cfile, global_capture_opts.save_file, out_file_type, out_file_name_res,
global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0);
#else
err = load_cap_file(&cfile, NULL, out_file_type, 0, 0);
err = load_cap_file(&cfile, NULL, out_file_type, out_file_name_res, 0, 0);
#endif
if (err != 0) {
/* We still dump out the results of taps, etc., as we might have
@ -2548,7 +2563,7 @@ process_packet_second_pass(capture_file *cf, frame_data *fdata,
static int
load_cap_file(capture_file *cf, char *save_file, int out_file_type,
int max_packet_count, gint64 max_byte_count)
gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count)
{
gint linktype;
int snapshot_length;
@ -2616,6 +2631,13 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
pdh = NULL;
}
if (pdh && out_file_name_res) {
if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
wtap_file_type_short_string(out_file_type));
}
}
/* Do we have any tap listeners with filters? */
filtering_tap_listeners = have_filtering_tap_listeners();
@ -3341,6 +3363,9 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
cf->state = FILE_READ_IN_PROGRESS;
wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
return CF_OK;
fail:

View File

@ -286,11 +286,7 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
}
errno = ENOMEM;
wth = (wtap *)g_malloc(sizeof(wtap));
if (wth == NULL) {
*err = errno;
return NULL;
}
wth = (wtap *)g_malloc0(sizeof(wtap));
/* Open the file */
errno = WTAP_ERR_CANT_OPEN;
@ -394,241 +390,247 @@ success:
/* Table of the file types we know about. */
static const struct file_type_info dump_open_table_base[] = {
/* WTAP_FILE_UNKNOWN (only used internally for initialization) */
{ NULL, NULL, NULL, NULL, FALSE,
{ NULL, NULL, NULL, NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_WTAP (only used internally while capturing) */
{ NULL, NULL, NULL, NULL, FALSE,
{ NULL, NULL, NULL, NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_PCAP */
{ "Wireshark/tcpdump/... - libpcap", "libpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "Wireshark/tcpdump/... - libpcap", "libpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_PCAP_NSEC */
{ "Wireshark - nanosecond libpcap", "nseclibpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "Wireshark - nanosecond libpcap", "nseclibpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_PCAP_AIX */
{ "AIX tcpdump - libpcap", "aixlibpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "AIX tcpdump - libpcap", "aixlibpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
NULL, NULL },
/* WTAP_FILE_PCAP_SS991029 */
{ "Modified tcpdump - libpcap", "modlibpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "Modified tcpdump - libpcap", "modlibpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_PCAP_NOKIA */
{ "Nokia tcpdump - libpcap ", "nokialibpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "Nokia tcpdump - libpcap ", "nokialibpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_PCAP_SS990417 */
{ "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_PCAP_SS990915 */
{ "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "*.pcap;*.cap", ".pcap", TRUE,
{ "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "*.pcap;*.cap", ".pcap", TRUE, FALSE,
libpcap_dump_can_write_encap, libpcap_dump_open },
/* WTAP_FILE_5VIEWS */
{ "Accellent 5Views capture", "5views", "*.5vw", ".5vw", FALSE,
{ "Accellent 5Views capture", "5views", "*.5vw", ".5vw", FALSE, FALSE,
_5views_dump_can_write_encap, _5views_dump_open },
/* WTAP_FILE_IPTRACE_1_0 */
{ "AIX iptrace 1.0", "iptrace_1", "*.*", NULL, FALSE,
{ "AIX iptrace 1.0", "iptrace_1", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_IPTRACE_2_0 */
{ "AIX iptrace 2.0", "iptrace_2", "*.*", NULL, FALSE,
{ "AIX iptrace 2.0", "iptrace_2", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_BER */
{ "ASN.1 Basic Encoding Rules", "ber", "*.*", NULL, FALSE,
{ "ASN.1 Basic Encoding Rules", "ber", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_HCIDUMP */
{ "Bluetooth HCI dump", "hcidump", "*.*", NULL, FALSE,
{ "Bluetooth HCI dump", "hcidump", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_CATAPULT_DCT2000 */
{ "Catapult DCT2000 trace (.out format)", "dct2000", "*.out", ".out", FALSE,
{ "Catapult DCT2000 trace (.out format)", "dct2000", "*.out", ".out", FALSE, FALSE,
catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open },
/* WTAP_FILE_NETXRAY_OLD */
{ "Cinco Networks NetXRay 1.x", "netxray1", "*.cap", ".cap", FALSE,
{ "Cinco Networks NetXRay 1.x", "netxray1", "*.cap", ".cap", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_NETXRAY_1_0 */
{ "Cinco Networks NetXRay 2.0 or later", "netxray2", "*.cap", ".cap", FALSE,
{ "Cinco Networks NetXRay 2.0 or later", "netxray2", "*.cap", ".cap", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_COSINE */
{ "CoSine IPSX L2 capture", "cosine", "*.*", NULL, FALSE,
{ "CoSine IPSX L2 capture", "cosine", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_CSIDS */
{ "CSIDS IPLog", "csids", "*.*", NULL, FALSE,
{ "CSIDS IPLog", "csids", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_DBS_ETHERWATCH */
{ "DBS Etherwatch (VMS)", "etherwatch", "*.*", NULL, FALSE,
{ "DBS Etherwatch (VMS)", "etherwatch", "*.*", NULL, FALSE, FALSE,
NULL, NULL},
/* WTAP_FILE_ERF */
{ "Endace ERF capture", "erf", "*.erf", ".erf", FALSE,
{ "Endace ERF capture", "erf", "*.erf", ".erf", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_EYESDN */
{ "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "*.trc", ".trc", FALSE,
{ "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "*.trc", ".trc", FALSE, FALSE,
eyesdn_dump_can_write_encap, eyesdn_dump_open },
/* WTAP_FILE_NETTL */
{ "HP-UX nettl trace", "nettl", "*.TRC0;*.TRC1", ".TRC0", FALSE,
{ "HP-UX nettl trace", "nettl", "*.TRC0;*.TRC1", ".TRC0", FALSE, FALSE,
nettl_dump_can_write_encap, nettl_dump_open },
/* WTAP_FILE_ISERIES */
{ "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "*.*", NULL, FALSE,
{ "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_ISERIES_UNICODE */
{ "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "*.*", NULL, FALSE,
{ "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_I4BTRACE */
{ "I4B ISDN trace", "i4btrace", "*.*", NULL, FALSE,
{ "I4B ISDN trace", "i4btrace", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_ASCEND */
{ "Lucent/Ascend access server trace", "ascend", "*.*", NULL, FALSE,
{ "Lucent/Ascend access server trace", "ascend", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_NETMON_1_x */
{ "Microsoft NetMon 1.x", "netmon1", "*.cap", ".cap", FALSE,
{ "Microsoft NetMon 1.x", "netmon1", "*.cap", ".cap", FALSE, FALSE,
netmon_dump_can_write_encap, netmon_dump_open },
/* WTAP_FILE_NETMON_2_x */
{ "Microsoft NetMon 2.x", "netmon2", "*.cap", ".cap", FALSE,
{ "Microsoft NetMon 2.x", "netmon2", "*.cap", ".cap", FALSE, FALSE,
netmon_dump_can_write_encap, netmon_dump_open },
/* WTAP_FILE_NGSNIFFER_UNCOMPRESSED */
{ "NA Sniffer (DOS)", "ngsniffer", "*.cap;*.enc;*.trc;*.fdc;*.syc", ".cap", FALSE,
{ "NA Sniffer (DOS)", "ngsniffer", "*.cap;*.enc;*.trc;*.fdc;*.syc", ".cap", FALSE, FALSE,
ngsniffer_dump_can_write_encap, ngsniffer_dump_open },
/* WTAP_FILE_NGSNIFFER_COMPRESSED */
{ "NA Sniffer (DOS), compressed", "ngsniffer_comp", "*.caz", ".caz", FALSE,
{ "NA Sniffer (DOS), compressed", "ngsniffer_comp", "*.caz", ".caz", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_NETXRAY_1_1 */
{ "NA Sniffer (Windows) 1.1", "ngwsniffer_1_1", "*.cap", ".cap", FALSE,
{ "NA Sniffer (Windows) 1.1", "ngwsniffer_1_1", "*.cap", ".cap", FALSE, FALSE,
netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1 },
/* WTAP_FILE_NETXRAY_2_00x */
{ "NA Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "*.cap", ".cap", FALSE,
{ "NA Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "*.cap", ".cap", FALSE, FALSE,
netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0 },
/* WTAP_FILE_NETWORK_INSTRUMENTS_V9 */
{ "Network Instruments Observer (V9)", "niobserverv9", "*.bfr", ".bfr", FALSE,
{ "Network Instruments Observer (V9)", "niobserverv9", "*.bfr", ".bfr", FALSE, FALSE,
network_instruments_dump_can_write_encap, network_instruments_dump_open },
/* WTAP_FILE_LANALYZER */
{ "Novell LANalyzer","lanalyzer", "*.tr1", ".tr1", FALSE,
{ "Novell LANalyzer","lanalyzer", "*.tr1", ".tr1", FALSE, FALSE,
lanalyzer_dump_can_write_encap, lanalyzer_dump_open },
/* WTAP_FILE_PPPDUMP */
{ "pppd log (pppdump format)", "pppd", "*.*", NULL, FALSE,
{ "pppd log (pppdump format)", "pppd", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_RADCOM */
{ "RADCOM WAN/LAN analyzer", "radcom", "*.*", NULL, FALSE,
{ "RADCOM WAN/LAN analyzer", "radcom", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_SNOOP */
{ "Sun snoop", "snoop", "*.snoop;*.cap", ".snoop", FALSE,
{ "Sun snoop", "snoop", "*.snoop;*.cap", ".snoop", FALSE, FALSE,
snoop_dump_can_write_encap, snoop_dump_open },
/* WTAP_FILE_SHOMITI */
{ "Shomiti/Finisar Surveyor", "shomiti", "*.cap", ".cap", FALSE,
{ "Shomiti/Finisar Surveyor", "shomiti", "*.cap", ".cap", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_VMS */
{ "TCPIPtrace (VMS)", "tcpiptrace", "*.*", NULL, FALSE,
{ "TCPIPtrace (VMS)", "tcpiptrace", "*.*", NULL, FALSE, FALSE,
NULL, NULL},
/* WTAP_FILE_K12 */
{ "Tektronix K12xx 32-bit .rf5 format", "rf5", "*.rf5", ".rf5", TRUE,
{ "Tektronix K12xx 32-bit .rf5 format", "rf5", "*.rf5", ".rf5", TRUE, FALSE,
k12_dump_can_write_encap, k12_dump_open },
/* WTAP_FILE_TOSHIBA */
{ "Toshiba Compact ISDN Router snoop", "toshiba", "*.*", NULL, FALSE,
{ "Toshiba Compact ISDN Router snoop", "toshiba", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_VISUAL_NETWORKS */
{ "Visual Networks traffic capture", "visual", "*.*", NULL, FALSE,
{ "Visual Networks traffic capture", "visual", "*.*", NULL, FALSE, FALSE,
visual_dump_can_write_encap, visual_dump_open },
/* WTAP_FILE_ETHERPEEK_V56 */
{ "WildPackets Ether/TokenPeek (V5 & V6)", "peek56", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE,
{ "WildPackets Ether/TokenPeek (V5 & V6)", "peek56", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_ETHERPEEK_V7 */
{ "WildPackets Ether/Token/AiroPeek (V7)", "peek7", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE,
{ "WildPackets Ether/Token/AiroPeek (V7)", "peek7", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_ETHERPEEK_V9 */
{ "WildPackets Ether/AiroPeek (V9)", "peek9", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE,
{ "WildPackets Ether/AiroPeek (V9)", "peek9", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_MPEG */
{ "MPEG", "mpeg", "*.mpeg;*.mpg;*.mp3", ".mpeg", FALSE,
{ "MPEG", "mpeg", "*.mpeg;*.mpg;*.mp3", ".mpeg", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_K12TEXT */
{ "K12 text file", "k12text", "*.txt", ".txt", TRUE,
{ "K12 text file", "k12text", "*.txt", ".txt", TRUE, FALSE,
k12text_dump_can_write_encap, k12text_dump_open },
/* WTAP_FILE_NETSCREEN */
{ "NetScreen snoop text file", "netscreen", "*.*", NULL, FALSE,
{ "NetScreen snoop text file", "netscreen", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_COMMVIEW */
{ "TamoSoft CommView", "commview", "*.ncf", ".ncf", TRUE,
{ "TamoSoft CommView", "commview", "*.ncf", ".ncf", TRUE, FALSE,
commview_dump_can_write_encap, commview_dump_open },
/* WTAP_FILE_PCAPNG */
{ "Wireshark - pcapng (experimental)", "pcapng", "*.pcapng", NULL, FALSE,
{ "Wireshark - pcapng", "pcapng", "*.pcapng", NULL, FALSE, TRUE,
pcapng_dump_can_write_encap, pcapng_dump_open },
/* WTAP_FILE_BTSNOOP */
{ "Symbian OS btsnoop", "btsnoop", "*.log", ".log", FALSE,
{ "Symbian OS btsnoop", "btsnoop", "*.log", ".log", FALSE, FALSE,
btsnoop_dump_can_write_encap, btsnoop_dump_open_h4 },
/* WTAP_FILE_X2E_XORAYA */
{ NULL, NULL, NULL, NULL, FALSE, NULL, NULL },
{ NULL, NULL, NULL, NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_TNEF */
{ "Transport-Neutral Encapsulation Format", "tnef", "*.*", NULL, FALSE, NULL, NULL },
{ "Transport-Neutral Encapsulation Format", "tnef", "*.*", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_DCT3TRACE */
{ "Gammu DCT3 trace", "dct3trace", "*.xml", NULL, FALSE, NULL, NULL },
{ "Gammu DCT3 trace", "dct3trace", "*.xml", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_PACKETLOGGER */
{ "PacketLogger", "pklg", "*.pklg", NULL, FALSE, NULL, NULL },
{ "PacketLogger", "pklg", "*.pklg", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_DAINTREE_SNA */
{ "Daintree SNA", "dsna", "*.dcf", NULL, FALSE, NULL, NULL },
{ "Daintree SNA", "dsna", "*.dcf", NULL, FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_NETSCALER_1_0 */
{ "NetScaler Trace (Version 1.0)", "nstrace10", "*.*", "*.*", FALSE,
{ "NetScaler Trace (Version 1.0)", "nstrace10", "*.*", "*.*", FALSE, FALSE,
nstrace_10_dump_can_write_encap, nstrace_dump_open },
/* WTAP_FILE_NETSCALER_2_0 */
{ "NetScaler Trace (Version 2.0)", "nstrace20", "*.cap", "*.cap", FALSE,
{ "NetScaler Trace (Version 2.0)", "nstrace20", "*.cap", "*.cap", FALSE, FALSE,
nstrace_20_dump_can_write_encap, nstrace_dump_open },
/* WTAP_FILE_JPEG_JFIF */
{ "JPEG/JFIF", "jpeg", "*.jpg;*.jpeg;*.jfif", ".jpg", FALSE, NULL, NULL },
{ "JPEG/JFIF", "jpeg", "*.jpg;*.jpeg;*.jfif", ".jpg", FALSE, FALSE,
NULL, NULL },
/* WTAP_FILE_IPFIX */
{ "IPFIX File Format", "ipfix", "*.pfx;*.ipfix", NULL, FALSE,
{ "IPFIX File Format", "ipfix", "*.pfx;*.ipfix", NULL, FALSE, FALSE,
NULL, NULL }
};
@ -752,6 +754,14 @@ gboolean wtap_dump_can_compress(int filetype _U_)
}
#endif
gboolean wtap_dump_has_name_resolution(int filetype)
{
if (filetype < 0 || filetype >= wtap_num_file_types
|| dump_open_table[filetype].has_name_resolution == FALSE)
return FALSE;
return TRUE;
}
static gboolean wtap_dump_open_check(int filetype, int encap, gboolean comressed, int *err);
static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
@ -879,7 +889,6 @@ static gboolean wtap_dump_open_check(int filetype, int encap, gboolean compresse
if (*err != 0)
return FALSE;
/* All systems go! */
return TRUE;
}
@ -889,20 +898,16 @@ static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
{
wtap_dumper *wdh;
wdh = (wtap_dumper *)g_malloc(sizeof (wtap_dumper));
wdh = (wtap_dumper *)g_malloc0(sizeof (wtap_dumper));
if (wdh == NULL) {
*err = errno;
return NULL;
}
wdh->fh = NULL;
wdh->file_type = filetype;
wdh->snaplen = snaplen;
wdh->encap = encap;
wdh->compressed = compressed;
wdh->bytes_dumped = 0;
wdh->priv = NULL;
wdh->subtype_write = NULL;
wdh->subtype_close = NULL;
return wdh;
}
@ -994,6 +999,14 @@ void wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
wdh->bytes_dumped = bytes_dumped;
}
gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, struct addrinfo *addrinfo_list)
{
if (!wdh || wdh->file_type < 0 || wdh->file_type >= wtap_num_file_types
|| dump_open_table[wdh->file_type].has_name_resolution == FALSE)
return FALSE;
wdh->addrinfo_list = addrinfo_list;
return TRUE;
}
/* internally open a file for writing (compressed or not) */
#ifdef HAVE_LIBZ

View File

@ -36,6 +36,28 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Needed for addrinfo */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#include "wtap-int.h"
#include "file_wrappers.h"
#include "buffer.h"
@ -125,6 +147,13 @@ typedef struct pcapng_simple_packet_block_s {
/* ... Padding ... */
} pcapng_simple_packet_block_t;
/* pcapng: simple packet block */
typedef struct pcapng_name_resolution_block_s {
guint16 record_type;
guint16 record_len;
/* ... Record ... */
} pcapng_name_resolution_block_t;
/* pcapng: interface statistics block */
typedef struct pcapng_interface_statistics_block_s {
guint32 interface_id;
@ -281,6 +310,8 @@ typedef struct {
gint8 if_fcslen;
GArray *interface_data;
guint number_of_interfaces;
wtap_new_ipv4_callback_t add_new_ipv4;
wtap_new_ipv6_callback_t add_new_ipv6;
} pcapng_t;
static int
@ -1052,6 +1083,116 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
return block_read;
}
#define NRES_ENDOFRECORD 0
#define NRES_IP4RECORD 1
#define NRES_IP6RECORD 2
#define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
/* IPv6 + MAXNAMELEN */
#define MAX_NRB_REC_SIZE (16 + 64)
static int
pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock _U_,int *err, gchar **err_info _U_)
{
int bytes_read = 0;
int block_read = 0;
int to_read;
guint64 file_offset64;
pcapng_name_resolution_block_t nrb;
guchar nrb_rec[MAX_NRB_REC_SIZE];
guint32 v4_addr;
errno = WTAP_ERR_CANT_READ;
to_read = bh->block_total_length
- sizeof(pcapng_block_header_t)
- sizeof(bh->block_total_length);
while (block_read < to_read) {
bytes_read = file_read(&nrb, 1, sizeof nrb, fh);
if (bytes_read != sizeof nrb) {
pcapng_debug0("pcapng_read_name_resolution_block: failed to read record header");
*err = file_error(fh);
return 0;
}
block_read += bytes_read;
if (pn->byte_swapped) {
nrb.record_type = BSWAP32(nrb.record_type);
nrb.record_len = BSWAP32(nrb.record_len);
}
switch(nrb.record_type) {
case NRES_ENDOFRECORD:
/* There shouldn't be any more data */
to_read = 0;
break;
case NRES_IP4RECORD:
if (nrb.record_len < 6 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv4 record");
return 0;
}
bytes_read = file_read(nrb_rec, 1, nrb.record_len, fh);
if (bytes_read != nrb.record_len) {
pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv4 record data");
*err = file_error(fh);
return 0;
}
block_read += bytes_read;
if (pn->add_new_ipv4) {
memcpy(&v4_addr, nrb_rec, 4);
if (pn->byte_swapped)
v4_addr = BSWAP32(v4_addr);
pn->add_new_ipv4(v4_addr, nrb_rec + 4);
}
file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
if (file_offset64 <= 0) {
if (*err != 0)
return -1;
return 0;
}
block_read += PADDING4(nrb.record_len);
break;
case NRES_IP6RECORD:
if (nrb.record_len < 18 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv6 record");
return 0;
}
bytes_read = file_read(nrb_rec, 1, nrb.record_len, fh);
if (bytes_read != nrb.record_len) {
pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv6 record data");
*err = file_error(fh);
return 0;
}
block_read += bytes_read;
if (pn->add_new_ipv6) {
pn->add_new_ipv6(nrb_rec, nrb_rec + 16);
}
file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
if (file_offset64 <= 0) {
if (*err != 0)
return -1;
return 0;
}
block_read += PADDING4(nrb.record_len);
break;
default:
pcapng_debug1("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
file_offset64 = file_seek(fh, nrb.record_len + PADDING4(nrb.record_len), SEEK_CUR, err);
if (file_offset64 <= 0) {
if (*err != 0)
return -1;
return 0;
}
block_read += nrb.record_len + PADDING4(nrb.record_len);
break;
}
}
return block_read;
}
static int
pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock,int *err, gchar **err_info _U_)
{
@ -1248,6 +1389,9 @@ pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t
case(BLOCK_TYPE_EPB):
bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE);
break;
case(BLOCK_TYPE_NRB):
bytes_read = pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info);
break;
case(BLOCK_TYPE_ISB):
bytes_read = pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info);
break;
@ -1375,6 +1519,9 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
wblock.packet_header = &wth->phdr;
wblock.file_encap = &wth->file_encap;
pcapng->add_new_ipv4 = wth->add_new_ipv4;
pcapng->add_new_ipv6 = wth->add_new_ipv6;
/* read next block */
while (1) {
bytes_read = pcapng_read_block(wth->fh, FALSE, pcapng, &wblock, err, err_info);
@ -1486,6 +1633,7 @@ pcapng_close(wtap *wth)
typedef struct {
GArray *interface_data;
guint number_of_interfaces;
struct addrinfo *addrinfo_list_last;
} pcapng_dump_t;
static gboolean
@ -1638,6 +1786,97 @@ pcapng_write_packet_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
return TRUE;
}
/* Arbitrary. */
#define NRES_REC_MAX_SIZE ((WTAP_MAX_PACKET_SIZE * 4) + 16)
static gboolean
pcapng_write_name_resolution_block(wtap_dumper *wdh, pcapng_dump_t *pcapng, int *err)
{
pcapng_block_header_t bh;
pcapng_name_resolution_block_t nrb;
struct addrinfo *ai;
struct sockaddr_in *sa4;
struct sockaddr_in6 *sa6;
guchar *rec_data;
gint rec_off, namelen, tot_rec_len;
if (! pcapng->addrinfo_list_last || ! pcapng->addrinfo_list_last->ai_next) {
return TRUE;
}
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 */
rec_data = g_malloc(NRES_REC_MAX_SIZE);
for (; pcapng->addrinfo_list_last && pcapng->addrinfo_list_last->ai_next; pcapng->addrinfo_list_last = pcapng->addrinfo_list_last->ai_next ) {
ai = pcapng->addrinfo_list_last->ai_next; /* Skips over the first (dummy) entry */
namelen = strlen(ai->ai_canonname) + 1;
if (ai->ai_family == AF_INET) {
nrb.record_type = NRES_IP4RECORD;
nrb.record_len = 4 + namelen;
tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
bh.block_total_length += tot_rec_len;
if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE)
break;
sa4 = (struct sockaddr_in *) ai->ai_addr;
memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
rec_off += 4;
memcpy(rec_data + rec_off, &(sa4->sin_addr.s_addr), 4);
rec_off += 4;
memcpy(rec_data + rec_off, ai->ai_canonname, namelen);
rec_off += namelen;
memset(rec_data + rec_off, 0, PADDING4(namelen));
rec_off += PADDING4(namelen);
pcapng_debug1("NRB: added IPv4 record for %s", ai->ai_canonname);
} else if (ai->ai_family == AF_INET6) {
nrb.record_type = NRES_IP6RECORD;
nrb.record_len = 16 + namelen;
tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
bh.block_total_length += tot_rec_len;
if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE)
break;
sa6 = (struct sockaddr_in6 *) ai->ai_addr;
memcpy(rec_data + rec_off, &nrb, sizeof(nrb));
rec_off += 4;
memcpy(rec_data + rec_off, sa6->sin6_addr.s6_addr, 16);
rec_off += 16;
memcpy(rec_data + rec_off, ai->ai_canonname, namelen);
rec_off += namelen;
memset(rec_data + rec_off, 0, PADDING4(namelen));
rec_off += PADDING4(namelen);
pcapng_debug1("NRB: added IPv6 record for %s", ai->ai_canonname);
}
}
/* We know the total length now; 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));
if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) {
g_free(rec_data);
return FALSE;
}
g_free(rec_data);
wdh->bytes_dumped += bh.block_total_length;
return TRUE;
}
static gboolean
pcapng_write_block(wtap_dumper *wdh, /*pcapng_t *pn, */wtapng_block_t *wblock, int *err)
@ -1691,6 +1930,9 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
phdr->pkt_encap,
wtap_encap_string(phdr->pkt_encap));
if (!pcapng->addrinfo_list_last)
pcapng->addrinfo_list_last = wdh->addrinfo_list;
interface_id = pcapng_lookup_interface_id_by_encap(phdr->pkt_encap, wdh);
if (interface_id == G_MAXUINT32) {
/* write the interface description block */
@ -1724,6 +1966,11 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
wtap_encap_string(phdr->pkt_encap));
}
/* Flush any hostname resolution info we may have */
while (pcapng->addrinfo_list_last && pcapng->addrinfo_list_last->ai_next) {
pcapng_write_name_resolution_block(wdh, pcapng, err);
}
wblock.frame_buffer = pd;
wblock.pseudo_header = pseudo_header;
wblock.packet_header = NULL;
@ -1786,10 +2033,9 @@ pcapng_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
/* This is a pcapng file */
wdh->subtype_write = pcapng_dump;
wdh->subtype_close = pcapng_dump_close;
pcapng = (pcapng_dump_t *)g_malloc(sizeof(pcapng_dump_t));
pcapng = (pcapng_dump_t *)g_malloc0(sizeof(pcapng_dump_t));
wdh->priv = (void *)pcapng;
pcapng->interface_data = g_array_new(FALSE, FALSE, sizeof(interface_data_t));
pcapng->number_of_interfaces = 0;
/* write the section header block */
wblock.type = BLOCK_TYPE_SHB;

View File

@ -71,6 +71,8 @@ struct wtap {
types */
int tsprecision; /* timestamp precision of the lower 32bits
* e.g. WTAP_FILE_TSPREC_USEC */
wtap_new_ipv4_callback_t add_new_ipv4;
wtap_new_ipv6_callback_t add_new_ipv6;
};
struct wtap_dumper;
@ -85,8 +87,8 @@ struct wtap_dumper {
int file_type;
int snaplen;
int encap;
gboolean compressed;
gint64 bytes_dumped;
gboolean compressed;
gint64 bytes_dumped;
void *priv;
@ -95,10 +97,14 @@ struct wtap_dumper {
int tsprecision; /* timestamp precision of the lower 32bits
* e.g. WTAP_FILE_TSPREC_USEC */
struct addrinfo *addrinfo_list;
};
extern gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf,
size_t bufsize, int *err);
extern gint64 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err);
extern gint64 wtap_dump_file_tell(wtap_dumper *wdh);
extern gint wtap_num_file_types;
@ -327,3 +333,16 @@ extern gint wtap_num_file_types;
#endif
#endif /* __WTAP_INT_H__ */
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* ex: set shiftwidth=8 tabstop=8 noexpandtab
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -40,7 +40,6 @@
#endif
#include "wtap-int.h"
#include "wtap.h"
#include "file_wrappers.h"
#include <wsutil/file_util.h>
@ -671,6 +670,16 @@ wtap_cleareof(wtap *wth _U_) {
#endif
}
void wtap_set_cb_new_ipv4(wtap *wth, wtap_new_ipv4_callback_t add_new_ipv4) {
if (wth)
wth->add_new_ipv4 = add_new_ipv4;
}
void wtap_set_cb_new_ipv6(wtap *wth, wtap_new_ipv6_callback_t add_new_ipv6) {
if (wth)
wth->add_new_ipv6 = add_new_ipv6;
}
gboolean
wtap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{

View File

@ -30,6 +30,7 @@ wtap_dump_close
wtap_dump_fdopen
wtap_dump_flush
wtap_dump_open
wtap_dump_set_addrinfo_list
wtap_encap_short_string
wtap_encap_string
wtap_file_encap
@ -55,6 +56,8 @@ wtap_register_open_routine
wtap_seek_read
wtap_sequential_close
wtap_set_bytes_dumped
wtap_set_cb_new_ipv4
wtap_set_cb_new_ipv6
wtap_short_string_to_encap
wtap_short_string_to_file_type
wtap_snapshot_length

View File

@ -822,6 +822,7 @@ struct wtap_dumper;
typedef struct wtap wtap;
typedef struct wtap_dumper wtap_dumper;
/* XXX Should this be moved to wtap-int.h? It appears to be internal to wtap.c. */
struct file_type_info {
/* the file type name */
/* should be NULL for all "pseudo" types that are only internally used and not read/writeable */
@ -842,8 +843,12 @@ struct file_type_info {
/* can this type be compressed with gzip? */
gboolean can_compress;
/* does this type support name resolution records? */
/* should be NULL is this file type doesn't have write support */
gboolean has_name_resolution;
/* can this type write this encapsulation format? */
/* should be NULL is this file type don't have write support */
/* should be NULL is this file type doesn't have write support */
int (*can_write_encap)(int);
/* the function to open the capture file for writing */
@ -872,6 +877,16 @@ struct wtap* wtap_open_offline(const char *filename, int *err,
*/
void wtap_cleareof(wtap *wth);
/*
* Set callback functions to add new hostnames. Currently pcapng-only.
* MUST match add_ipv4_name and add_ipv6_name in addr_resolv.c.
*/
typedef void (*wtap_new_ipv4_callback_t) (const guint addr, const gchar *name);
void wtap_set_cb_new_ipv4(wtap *wth, wtap_new_ipv4_callback_t add_new_ipv4);
typedef void (*wtap_new_ipv6_callback_t) (const void *addrp, const gchar *name);
void wtap_set_cb_new_ipv6(wtap *wth, wtap_new_ipv6_callback_t add_new_ipv6);
/* Returns TRUE if read was successful. FALSE if failure. data_offset is
* set to the offset in the file where the data for the read packet is
* located. */
@ -915,6 +930,8 @@ gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *,
void wtap_dump_flush(wtap_dumper *);
gint64 wtap_get_bytes_dumped(wtap_dumper *);
void wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped);
struct addrinfo;
gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, struct addrinfo *addrinfo_list);
gboolean wtap_dump_close(wtap_dumper *, int *);
/*** various string converter functions ***/