forked from osmocom/wireshark
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:
parent
57833dc778
commit
fcf51fc73b
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/* -----------------
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
4
file.c
|
@ -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:
|
||||
|
|
35
tshark.c
35
tshark.c
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
250
wiretap/pcapng.c
250
wiretap/pcapng.c
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ***/
|
||||
|
|
Loading…
Reference in New Issue