diff options
author | Guy Harris <guy@alum.mit.edu> | 2013-06-01 02:58:58 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2013-06-01 02:58:58 +0000 |
commit | 6e336d74a1f30f23de88886478d22ba05cb7de60 (patch) | |
tree | ada1bc0312a8de454775a85247c8a830041cd38e /wiretap | |
parent | 15a0d1f945958ab4f56c5e886c71827886b6c12e (diff) |
Move the record header processing code into a common routine, and read
that header in both the read and seek-read routines.
svn path=/trunk/; revision=49671
Diffstat (limited to 'wiretap')
-rw-r--r-- | wiretap/netmon.c | 224 |
1 files changed, 123 insertions, 101 deletions
diff --git a/wiretap/netmon.c b/wiretap/netmon.c index b026ae385f..aa97cf6195 100644 --- a/wiretap/netmon.c +++ b/wiretap/netmon.c @@ -466,54 +466,22 @@ netmon_set_pseudo_header_info(int pkt_encap, } } -/* Read the next packet */ -static gboolean netmon_read(wtap *wth, int *err, gchar **err_info, - gint64 *data_offset) +static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh, + struct wtap_pkthdr *phdr, int *err, gchar **err_info) { netmon_t *netmon = (netmon_t *)wth->priv; - guint32 packet_size = 0; - guint32 orig_size = 0; - int bytes_read; + int hdr_size = 0; union { struct netmonrec_1_x_hdr hdr_1_x; struct netmonrec_2_x_hdr hdr_2_x; } hdr; - int hdr_size = 0; - int trlr_size; - gint64 rec_offset; - guint8 *data_ptr; + int bytes_read; gint64 delta = 0; /* signed - frame times can be before the nominal start */ gint64 t; time_t secs; guint32 nsecs; - -again: - /* 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; - free it. */ - g_free(netmon->frame_table); - netmon->frame_table = NULL; - *err = 0; /* it's just an EOF, not an error */ - return FALSE; - } - - /* Seek to the beginning of the current record, if we're - not there already (seeking to the current position - may still cause a seek and a read of the underlying file, - so we don't want to do it unconditionally). - - Yes, the current record could be before the previous - record. At least some captures put the trailer record - with statistics as the first physical record in the - file, but set the frame table up so it's the last - record in sequence. */ - rec_offset = netmon->frame_table[netmon->current_frame]; - if (file_tell(wth->fh) != rec_offset) { - if (file_seek(wth->fh, rec_offset, SEEK_SET, err) == -1) - return FALSE; - } - netmon->current_frame++; + guint32 packet_size = 0; + guint32 orig_size = 0; /* Read record header. */ switch (netmon->version_major) { @@ -528,9 +496,9 @@ again: } errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&hdr, hdr_size, wth->fh); + bytes_read = file_read(&hdr, hdr_size, fh); if (bytes_read != hdr_size) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } @@ -560,8 +528,6 @@ again: return FALSE; } - *data_offset = file_tell(wth->fh); - /* * If this is an ATM packet, the first * "sizeof (struct netmon_atm_hdr)" bytes have destination and @@ -582,7 +548,7 @@ again: packet_size); return FALSE; } - if (!netmon_read_atm_pseudoheader(wth->fh, &wth->phdr.pseudo_header, + if (!netmon_read_atm_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return FALSE; /* Read error */ @@ -597,12 +563,6 @@ again: break; } - buffer_assure_space(wth->frame_buffer, packet_size); - data_ptr = buffer_start_ptr(wth->frame_buffer); - if (!netmon_read_rec_data(wth->fh, data_ptr, packet_size, err, - err_info)) - return FALSE; /* Read error */ - switch (netmon->version_major) { case 1: @@ -670,34 +630,109 @@ again: } secs += (time_t)(t/1000000000); nsecs = (guint32)(t%1000000000); - wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; - wth->phdr.ts.secs = netmon->start_secs + secs; - wth->phdr.ts.nsecs = nsecs; - wth->phdr.caplen = packet_size; - wth->phdr.len = orig_size; + 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; + +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; - /* - * For version 2.1 and later, there's additional information - * after the frame data. - */ trlr_size = (int)netmon_trailer_size(netmon); if (trlr_size != 0) { /* * I haz a trailer. */ - wth->phdr.pkt_encap = netmon_read_rec_trailer(wth->fh, + phdr->pkt_encap = netmon_read_rec_trailer(fh, trlr_size, err, err_info); - if (wth->phdr.pkt_encap == -1) - return FALSE; /* error */ - if (wth->phdr.pkt_encap == 0) - goto again; - netmon_set_pseudo_header_info(wth->phdr.pkt_encap, - &wth->phdr.pseudo_header, data_ptr, packet_size); - } else { - netmon_set_pseudo_header_info(wth->file_encap, - &wth->phdr.pseudo_header, data_ptr, packet_size); + if (phdr->pkt_encap == -1) + return FAILURE; /* error */ + if (phdr->pkt_encap == 0) + return RETRY; } + return SUCCESS; +} + +/* Read the next packet */ +static gboolean netmon_read(wtap *wth, int *err, gchar **err_info, + gint64 *data_offset) +{ + netmon_t *netmon = (netmon_t *)wth->priv; + gint64 rec_offset; + guint8 *data_ptr; + +again: + /* 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; + free it. */ + g_free(netmon->frame_table); + netmon->frame_table = NULL; + *err = 0; /* it's just an EOF, not an error */ + return FALSE; + } + + /* Seek to the beginning of the current record, if we're + not there already (seeking to the current position + may still cause a seek and a read of the underlying file, + so we don't want to do it unconditionally). + + Yes, the current record could be before the previous + record. At least some captures put the trailer record + with statistics as the first physical record in the + file, but set the frame table up so it's the last + record in sequence. */ + rec_offset = netmon->frame_table[netmon->current_frame]; + if (file_tell(wth->fh) != rec_offset) { + if (file_seek(wth->fh, rec_offset, SEEK_SET, err) == -1) + return FALSE; + } + netmon->current_frame++; + + *data_offset = file_tell(wth->fh); + + if (!netmon_process_rec_header(wth, wth->fh, &wth->phdr, + err, err_info)) + return FALSE; + + buffer_assure_space(wth->frame_buffer, wth->phdr.caplen); + data_ptr = buffer_start_ptr(wth->frame_buffer); + if (!netmon_read_rec_data(wth->fh, data_ptr, 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)) { + + case RETRY: + goto again; + + case SUCCESS: + break; + + case FAILURE: + return FALSE; + } + + netmon_set_pseudo_header_info(wth->phdr.pkt_encap, + &wth->phdr.pseudo_header, data_ptr, wth->phdr.caplen); return TRUE; } @@ -706,24 +741,14 @@ netmon_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, guint8 *pd, int length, int *err, gchar **err_info) { - union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; netmon_t *netmon = (netmon_t *)wth->priv; - int trlr_size; - int pkt_encap; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; - switch (wth->file_encap) { - - case WTAP_ENCAP_ATM_PDUS: - if (!netmon_read_atm_pseudoheader(wth->random_fh, pseudo_header, - err, err_info)) { - /* Read error */ - return FALSE; - } - break; - } + if (!netmon_process_rec_header(wth, wth->random_fh, phdr, + err, err_info)) + return FALSE; /* * Read the packet data. @@ -735,30 +760,27 @@ netmon_seek_read(wtap *wth, gint64 seek_off, * For version 2.1 and later, there's additional information * after the frame data. */ - trlr_size = (int)netmon_trailer_size(netmon); - if (trlr_size != 0) { + switch (netmon_process_rec_trailer(netmon, wth->random_fh, phdr, + err, err_info)) { + + case RETRY: /* - * I haz a trailer. + * This should not happen. */ - pkt_encap = netmon_read_rec_trailer(wth->random_fh, - trlr_size, err, err_info); - if (pkt_encap == -1) - return FALSE; /* error */ - if (pkt_encap == 0) { - /* - * This should not happen. - */ - *err = WTAP_ERR_BAD_FILE; - *err_info = g_strdup("netmon: saw metadata in netmon_seek_read"); - return FALSE; - } - netmon_set_pseudo_header_info(pkt_encap, pseudo_header, - pd, length); - } else { - netmon_set_pseudo_header_info(wth->file_encap, pseudo_header, - pd, length); + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("netmon: saw metadata in netmon_seek_read"); + return FALSE; + + case SUCCESS: + break; + + case FAILURE: + return FALSE; } + netmon_set_pseudo_header_info(phdr->pkt_encap, + &phdr->pseudo_header, pd, phdr->caplen); + return TRUE; } |