Pull the record processing into netmon_process_record().

That combines more common code from the read and seek-read code
paths.

Also, separate out the individual metadata record types, with a comment
for each, to simplify the process of supporting some or all of them in
the future.

Change-Id: Ic8ded397d9550ec6013c1f5f138333b1ef5c37e5
Reviewed-on: https://code.wireshark.org/review/2869
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2014-07-05 18:13:13 -07:00
parent 0335ae339d
commit 570d52a844
1 changed files with 132 additions and 141 deletions

View File

@ -412,19 +412,16 @@ int netmon_open(wtap *wth, int *err, gchar **err_info)
}
static void
netmon_set_pseudo_header_info(int pkt_encap, struct wtap_pkthdr *phdr,
Buffer *buf)
netmon_set_pseudo_header_info(struct wtap_pkthdr *phdr, Buffer *buf)
{
guint8 *pd = buffer_start_ptr(buf);
switch (pkt_encap) {
switch (phdr->pkt_encap) {
case WTAP_ENCAP_ATM_PDUS:
/*
* Attempt to guess from the packet data, the VPI, and
* the VCI information about the type of traffic.
*/
atm_guess_traffic_type(phdr, pd);
atm_guess_traffic_type(phdr, buffer_start_ptr(buf));
break;
case WTAP_ENCAP_ETHERNET:
@ -447,8 +444,29 @@ netmon_set_pseudo_header_info(int pkt_encap, struct wtap_pkthdr *phdr,
}
}
static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh,
struct wtap_pkthdr *phdr, int *err, gchar **err_info)
typedef enum {
SUCCESS,
FAILURE,
RETRY
} process_record_retval;
/*
* Number of seconds between the UN*X epoch (January 1, 1970, 00:00:00 GMT)
* and the Windows NT epoch (January 1, 1601, 00:00:00 "GMT").
*/
#define TIME_FIXUP_CONSTANT G_GUINT64_CONSTANT(11644473600)
#ifndef TIME_T_MIN
#define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
#endif
static process_record_retval
netmon_process_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
Buffer *buf, int *err, gchar **err_info)
{
netmon_t *netmon = (netmon_t *)wth->priv;
int hdr_size = 0;
@ -460,9 +478,17 @@ static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh,
gint64 delta = 0; /* signed - frame times can be before the nominal start */
gint64 t;
time_t secs;
guint32 nsecs;
int nsecs;
guint32 packet_size = 0;
guint32 orig_size = 0;
int trlr_size;
union {
struct netmonrec_2_1_trlr trlr_2_1;
struct netmonrec_2_2_trlr trlr_2_2;
struct netmonrec_2_3_trlr trlr_2_3;
} trlr;
guint16 network;
int pkt_encap;
/* Read record header. */
switch (netmon->version_major) {
@ -612,54 +638,25 @@ static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh,
secs--;
}
secs += (time_t)(t/1000000000);
nsecs = (guint32)(t%1000000000);
nsecs = (int)(t%1000000000);
phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
phdr->ts.secs = netmon->start_secs + secs;
phdr->ts.nsecs = nsecs;
phdr->caplen = packet_size;
phdr->len = orig_size;
return TRUE;
}
typedef enum {
SUCCESS,
FAILURE,
RETRY
} process_trailer_retval;
/*
* Read the packet data.
*/
if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
return FALSE;
/*
* Number of seconds between the UN*X epoch (January 1, 1970, 00:00:00 GMT)
* and the Windows NT epoch (January 1, 1601, 00:00:00 "GMT").
* For version 2.1 and later, there's additional information
* after the frame data.
*/
#define TIME_FIXUP_CONSTANT G_GUINT64_CONSTANT(11644473600)
#ifndef TIME_T_MIN
#define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
#endif
static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_info)
{
int trlr_size;
int bytes_read;
union {
struct netmonrec_2_1_trlr trlr_2_1;
struct netmonrec_2_2_trlr trlr_2_2;
struct netmonrec_2_3_trlr trlr_2_3;
} trlr;
guint16 network;
int pkt_encap;
if ((netmon->version_major == 2 && netmon->version_minor >= 1) ||
netmon->version_major > 2) {
/*
* I haz a trailer.
*/
if (netmon->version_major > 2) {
/*
* Asssume 2.3 format, for now.
@ -689,7 +686,7 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
if (*err == 0 && bytes_read != 0) {
*err = WTAP_ERR_SHORT_READ;
}
return FAILURE; /* error */
return FAILURE;
}
network = pletoh16(trlr.trlr_2_1.network);
@ -704,7 +701,7 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
*err_info = g_strdup_printf("netmon: converted pcap network type %u unknown or unsupported",
network);
return FAILURE; /* error */
return FAILURE;
}
} else if (network < NUM_NETMON_ENCAPS) {
/*
@ -715,7 +712,7 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
network);
return FAILURE; /* error */
return FAILURE;
}
} else {
/*
@ -724,15 +721,44 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
switch (network) {
case NETMON_NET_NETEVENT:
/*
* Event Tracing event.
*
* http://msdn.microsoft.com/en-us/library/aa363759(VS.85).aspx
*/
return RETRY;
case NETMON_NET_NETWORK_INFO_EX:
/*
* List of adapters on which the capture
* was done.
*/
return RETRY;
case NETMON_NET_PAYLOAD_HEADER:
/*
* Header for a fake frame constructed
* by reassembly.
*/
return RETRY;
case NETMON_NET_NETWORK_INFO:
/*
* List of adapters on which the capture
* was done.
*/
return RETRY;
case NETMON_NET_DNS_CACHE:
/*
* List of resolved IP addresses.
*/
return RETRY;
case NETMON_NET_NETMON_FILTER:
/*
* Just ignore those record types, for
* now. Tell our caller to read the next
* record.
* NetMon capture or display filter
* string.
*/
return RETRY;
@ -740,7 +766,7 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
network);
return FAILURE; /* error */
return FAILURE;
}
}
@ -755,8 +781,7 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
* Copyright (C) Andrew Tridgell 1992-1998
*/
guint64 d;
gint64 secs;
int nsecs;
gint64 utcsecs;
/* The next two lines are a fix needed for the
broken SCO compiler. JRA. */
time_t l_time_min = TIME_T_MIN;
@ -765,16 +790,16 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
d = pletoh64(trlr.trlr_2_3.utc_timestamp);
/* Split into seconds and nanoseconds. */
secs = d / 10000000;
utcsecs = d / 10000000;
nsecs = (int)((d % 10000000)*100);
/* Now adjust the seconds. */
secs -= TIME_FIXUP_CONSTANT;
utcsecs -= TIME_FIXUP_CONSTANT;
if (!(l_time_min <= secs && secs <= l_time_max)) {
*err = WTAP_ERR_BAD_FILE;
*err_info = g_strdup_printf("netmon: time stamp outside supported range");
return FAILURE; /* can't handle this time value */
return FAILURE;
}
/*
@ -782,10 +807,12 @@ static process_trailer_retval netmon_process_rec_trailer(netmon_t *netmon,
* and overwrite the time stamp obtained
* from the record header.
*/
phdr->ts.secs = (time_t) secs;
phdr->ts.secs = (time_t) utcsecs;
phdr->ts.nsecs = nsecs;
}
}
netmon_set_pseudo_header_info(phdr, buf);
return SUCCESS;
}
@ -796,7 +823,7 @@ static gboolean netmon_read(wtap *wth, int *err, gchar **err_info,
netmon_t *netmon = (netmon_t *)wth->priv;
gint64 rec_offset;
again:
for (;;) {
/* Have we reached the end of the packet data? */
if (netmon->current_frame >= netmon->frame_table_size) {
/* Yes. We won't need the frame table any more;
@ -826,62 +853,30 @@ again:
*data_offset = file_tell(wth->fh);
if (!netmon_process_rec_header(wth, wth->fh, &wth->phdr,
err, err_info))
return FALSE;
if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer,
wth->phdr.caplen, err, err_info))
return FALSE; /* Read error */
/*
* For version 2.1 and later, there's additional information
* after the frame data.
*/
switch (netmon_process_rec_trailer(netmon, wth->fh, &wth->phdr,
err, err_info)) {
switch (netmon_process_record(wth, wth->fh, &wth->phdr,
wth->frame_buffer, err, err_info)) {
case RETRY:
goto again;
continue;
case SUCCESS:
break;
return TRUE;
case FAILURE:
return FALSE;
}
netmon_set_pseudo_header_info(wth->phdr.pkt_encap, &wth->phdr,
wth->frame_buffer);
return TRUE;
}
}
static gboolean
netmon_seek_read(wtap *wth, gint64 seek_off,
struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
netmon_t *netmon = (netmon_t *)wth->priv;
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return FALSE;
if (!netmon_process_rec_header(wth, wth->random_fh, phdr,
err, err_info))
return FALSE;
/*
* Read the packet data.
*/
if (!wtap_read_packet_bytes(wth->random_fh, buf, phdr->caplen, err,
err_info))
return FALSE;
/*
* For version 2.1 and later, there's additional information
* after the frame data.
*/
switch (netmon_process_rec_trailer(netmon, wth->random_fh, phdr,
err, err_info)) {
switch (netmon_process_record(wth, wth->random_fh, phdr, buf, err,
err_info)) {
case RETRY:
/*
@ -892,15 +887,11 @@ netmon_seek_read(wtap *wth, gint64 seek_off,
return FALSE;
case SUCCESS:
break;
return TRUE;
case FAILURE:
return FALSE;
}
netmon_set_pseudo_header_info(phdr->pkt_encap, phdr, buf);
return TRUE;
}
static gboolean