diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index cb9e97cf59..9084ec6e3f 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -70,9 +70,11 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, guint8 *pd, int length, int *err, gchar **err_info); -static int libpcap_read_header(wtap *wth, int *err, gchar **err_info, +static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info, struct pcaprec_ss990915_hdr *hdr); static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr); +static gboolean libpcap_process_header(wtap *wth, FILE_T fh, + struct wtap_pkthdr *phdr, int *err, gchar **err_info); static gboolean libpcap_read_rec_data(FILE_T fh, guint8 *pd, int length, int *err, gchar **err_info); static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, @@ -516,7 +518,7 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err) /* * Attempt to read the first record's header. */ - if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) { + if (libpcap_read_header(wth, wth->fh, err, NULL, &first_rec_hdr) == -1) { if (*err == 0 || *err == WTAP_ERR_SHORT_READ) { /* * EOF or short read - assume the file is in this @@ -555,7 +557,7 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err) /* * Now attempt to read the second record's header. */ - if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) { + if (libpcap_read_header(wth, wth->fh, err, NULL, &second_rec_hdr) == -1) { if (*err == 0 || *err == WTAP_ERR_SHORT_READ) { /* * EOF or short read - assume the file is in this @@ -595,6 +597,53 @@ static libpcap_try_t libpcap_try(wtap *wth, int *err) /* Read the next packet */ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) +{ + libpcap_t *libpcap; + + *data_offset = file_tell(wth->fh); + + if (!libpcap_process_header(wth, wth->fh, &wth->phdr, err, err_info)) + return FALSE; + + buffer_assure_space(wth->frame_buffer, wth->phdr.caplen); + if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), + wth->phdr.caplen, err, err_info)) + return FALSE; /* Read error */ + + libpcap = (libpcap_t *)wth->priv; + pcap_read_post_process(wth->file_type, wth->file_encap, + &wth->phdr.pseudo_header, buffer_start_ptr(wth->frame_buffer), + wth->phdr.caplen, libpcap->byte_swapped, -1); + return TRUE; +} + +static gboolean +libpcap_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, + guint8 *pd, int length, int *err, gchar **err_info) +{ + libpcap_t *libpcap; + + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + + if (!libpcap_process_header(wth, wth->random_fh, phdr, err, err_info)) + return FALSE; + + /* + * Read the packet data. + */ + if (!libpcap_read_rec_data(wth->random_fh, pd, length, err, err_info)) + return FALSE; /* failed */ + + libpcap = (libpcap_t *)wth->priv; + pcap_read_post_process(wth->file_type, wth->file_encap, + &phdr->pseudo_header, pd, length, libpcap->byte_swapped, -1); + return TRUE; +} + +static gboolean +libpcap_process_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, + int *err, gchar **err_info) { struct pcaprec_ss990915_hdr hdr; guint packet_size; @@ -604,7 +653,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, int phdr_len; libpcap_t *libpcap; - bytes_read = libpcap_read_header(wth, err, err_info, &hdr); + bytes_read = libpcap_read_header(wth, fh, err, err_info, &hdr); if (bytes_read == -1) { /* * We failed to read the header. @@ -632,17 +681,14 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, /* * Read the padding. */ - if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err, + if (!libpcap_read_rec_data(fh, fddi_padding, 3, err, err_info)) return FALSE; /* Read error */ } - *data_offset = file_tell(wth->fh); - libpcap = (libpcap_t *)wth->priv; - phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type, - wth->file_encap, packet_size, TRUE, &wth->phdr, - &wth->phdr.pseudo_header, err, err_info); + phdr_len = pcap_process_pseudo_header(fh, wth->file_type, + wth->file_encap, packet_size, TRUE, phdr, err, err_info); if (phdr_len < 0) return FALSE; /* error */ @@ -652,68 +698,30 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, orig_size -= phdr_len; packet_size -= phdr_len; - buffer_assure_space(wth->frame_buffer, packet_size); - if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), - packet_size, err, err_info)) - return FALSE; /* Read error */ + phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; - wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; - - /* Update the Timestamp, if not already done */ + /* Update the timestamp, if not already done */ if (wth->file_encap != WTAP_ENCAP_ERF) { - wth->phdr.ts.secs = hdr.hdr.ts_sec; - if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) { - wth->phdr.ts.nsecs = hdr.hdr.ts_usec; - } else { - wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000; - } + phdr->ts.secs = hdr.hdr.ts_sec; + if (wth->tsprecision == WTAP_FILE_TSPREC_NSEC) + phdr->ts.nsecs = hdr.hdr.ts_usec; + else + phdr->ts.nsecs = hdr.hdr.ts_usec * 1000; } else { /* Set interface ID for ERF format */ wth->phdr.presence_flags |= WTAP_HAS_INTERFACE_ID; wth->phdr.interface_id = wth->phdr.pseudo_header.erf.phdr.flags & 0x03; } - wth->phdr.caplen = packet_size; - wth->phdr.len = orig_size; + phdr->caplen = packet_size; + phdr->len = orig_size; - pcap_read_post_process(wth->file_type, wth->file_encap, - &wth->phdr.pseudo_header, buffer_start_ptr(wth->frame_buffer), - wth->phdr.caplen, libpcap->byte_swapped, -1); - return TRUE; -} - -static gboolean -libpcap_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; - int phdr_len; - libpcap_t *libpcap; - - if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) - return FALSE; - - libpcap = (libpcap_t *)wth->priv; - phdr_len = pcap_process_pseudo_header(wth->random_fh, wth->file_type, - wth->file_encap, length, FALSE, NULL, pseudo_header, err, err_info); - if (phdr_len < 0) - return FALSE; /* error */ - - /* - * Read the packet data. - */ - if (!libpcap_read_rec_data(wth->random_fh, pd, length, err, err_info)) - return FALSE; /* failed */ - - pcap_read_post_process(wth->file_type, wth->file_encap, - pseudo_header, pd, length, libpcap->byte_swapped, -1); return TRUE; } /* Read the header of the next packet. Return -1 on an error, or the number of bytes of header read on success. */ -static int libpcap_read_header(wtap *wth, int *err, gchar **err_info, +static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info, struct pcaprec_ss990915_hdr *hdr) { int bytes_to_read, bytes_read; @@ -745,9 +753,9 @@ static int libpcap_read_header(wtap *wth, int *err, gchar **err_info, g_assert_not_reached(); bytes_to_read = 0; } - bytes_read = file_read(hdr, bytes_to_read, wth->fh); + bytes_read = file_read(hdr, bytes_to_read, fh); if (bytes_read != bytes_to_read) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c index 682c822a58..3fc6502441 100644 --- a/wiretap/pcap-common.c +++ b/wiretap/pcap-common.c @@ -1484,8 +1484,8 @@ pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, i int pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, - guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr, - union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) + guint packet_size, gboolean check_packet_size, + struct wtap_pkthdr *phdr, int *err, gchar **err_info) { int phdr_len = 0; guint size; @@ -1508,7 +1508,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, return -1; } if (!pcap_read_nokiaatm_pseudoheader(fh, - pseudo_header, err, err_info)) + &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = NOKIAATM_LEN; @@ -1527,7 +1527,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, return -1; } if (!pcap_read_sunatm_pseudoheader(fh, - pseudo_header, err, err_info)) + &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = SUNATM_LEN; @@ -1540,14 +1540,14 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, * Nokia IPSO. Psuedo header has already been read, but it's not considered * part of the packet size, so reread it to store the data for later (when saving) */ - if (!pcap_read_nokia_pseudoheader(fh, pseudo_header, err, err_info)) + if (!pcap_read_nokia_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ } /* * We don't know whether there's an FCS in this frame or not. */ - pseudo_header->eth.fcs_len = -1; + phdr->pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_IEEE_802_11: @@ -1559,11 +1559,11 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, * XXX - are there any OSes where the capture mechanism * supplies an FCS? */ - pseudo_header->ieee_802_11.fcs_len = -1; - pseudo_header->ieee_802_11.decrypted = FALSE; - pseudo_header->ieee_802_11.channel = 0; - pseudo_header->ieee_802_11.data_rate = 0; - pseudo_header->ieee_802_11.signal_level = 0; + phdr->pseudo_header.ieee_802_11.fcs_len = -1; + phdr->pseudo_header.ieee_802_11.decrypted = FALSE; + phdr->pseudo_header.ieee_802_11.channel = 0; + phdr->pseudo_header.ieee_802_11.data_rate = 0; + phdr->pseudo_header.ieee_802_11.signal_level = 0; break; case WTAP_ENCAP_IRDA: @@ -1577,7 +1577,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, packet_size); return -1; } - if (!pcap_read_irda_pseudoheader(fh, pseudo_header, + if (!pcap_read_irda_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ @@ -1595,7 +1595,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, packet_size); return -1; } - if (!pcap_read_mtp2_pseudoheader(fh, pseudo_header, + if (!pcap_read_mtp2_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ @@ -1613,7 +1613,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, packet_size); return -1; } - if (!pcap_read_lapd_pseudoheader(fh, pseudo_header, + if (!pcap_read_lapd_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ @@ -1631,7 +1631,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, packet_size); return -1; } - if (!pcap_read_sita_pseudoheader(fh, pseudo_header, + if (!pcap_read_sita_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ @@ -1640,7 +1640,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, case WTAP_ENCAP_BLUETOOTH_H4: /* We don't have pseudoheader, so just pretend we received everything. */ - pseudo_header->p2p.sent = FALSE; + phdr->pseudo_header.p2p.sent = FALSE; break; case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR: @@ -1656,7 +1656,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, return -1; } if (!pcap_read_bt_pseudoheader(fh, - pseudo_header, err, err_info)) + &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = (int)sizeof (struct libpcap_bt_phdr); @@ -1668,7 +1668,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, *err_info = g_strdup_printf("pcap: libpcap llcp file too short"); return -1; } - if (!pcap_read_llcp_pseudoheader(fh, pseudo_header, err, err_info)) + if (!pcap_read_llcp_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = LLCP_HEADER_LEN; break; @@ -1686,7 +1686,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, return -1; } if (!pcap_read_ppp_pseudoheader(fh, - pseudo_header, err, err_info)) + &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = (int)sizeof (struct libpcap_ppp_phdr); @@ -1705,21 +1705,21 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, return -1; } - if (!pcap_read_erf_pseudoheader(fh, phdr, pseudo_header, + if (!pcap_read_erf_pseudoheader(fh, phdr, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ phdr_len = (int)sizeof(struct erf_phdr); /* check the optional Extension header */ - if (!pcap_read_erf_exheader(fh, pseudo_header, err, err_info, + if (!pcap_read_erf_exheader(fh, &phdr->pseudo_header, err, err_info, &size)) return -1; /* Read error */ phdr_len += size; /* check the optional Multi Channel header */ - if (!pcap_read_erf_subheader(fh, pseudo_header, err, err_info, + if (!pcap_read_erf_subheader(fh, &phdr->pseudo_header, err, err_info, &size)) return -1; /* Read error */ @@ -1750,7 +1750,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, packet_size); return -1; } - if (!pcap_read_i2c_pseudoheader(fh, pseudo_header, + if (!pcap_read_i2c_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ diff --git a/wiretap/pcap-common.h b/wiretap/pcap-common.h index 4f7fb25cf2..734d81856f 100644 --- a/wiretap/pcap-common.h +++ b/wiretap/pcap-common.h @@ -32,8 +32,8 @@ #include "ws_symbol_export.h" extern int pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, - guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr, - union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info); + guint packet_size, gboolean check_packet_size, + struct wtap_pkthdr *phdr, int *err, gchar **err_info); extern void pcap_read_post_process(int file_type, int wtap_encap, union wtap_pseudo_header *pseudo_header, diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index 74f4d62015..074b2d92a9 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -368,7 +368,6 @@ typedef struct wtapng_block_s { * but, when we're writing a block, they can be const, and, * in fact, they sometimes point to const values. */ - const union wtap_pseudo_header *pseudo_header; struct wtap_pkthdr *packet_header; const guint8 *frame_buffer; int *file_encap; @@ -1067,25 +1066,24 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta pcapng_debug3("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.", int_data.wtap_encap, wtap_encap_string(int_data.wtap_encap), - pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)); + pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header.pseudo_header)); wblock->packet_header->interface_id = wblock->data.packet.interface_id; wblock->packet_header->pkt_encap = int_data.wtap_encap; - memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header)); + memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header)); pseudo_header_len = pcap_process_pseudo_header(fh, WTAP_FILE_PCAPNG, int_data.wtap_encap, wblock->data.packet.cap_len, TRUE, wblock->packet_header, - (union wtap_pseudo_header *)wblock->pseudo_header, err, err_info); if (pseudo_header_len < 0) { return FALSE; } block_read += pseudo_header_len; - if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)) { + if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) { pcapng_debug1("pcapng_read_packet_block: Could only read %d bytes for pseudo header.", pseudo_header_len); } @@ -1219,7 +1217,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta g_free(option_content); pcap_read_post_process(WTAP_FILE_PCAPNG, int_data.wtap_encap, - (union wtap_pseudo_header *)wblock->pseudo_header, + (union wtap_pseudo_header *)&wblock->packet_header->pseudo_header, (guint8 *) (wblock->frame_buffer), (int) (wblock->data.packet.cap_len - pseudo_header_len), pn->byte_swapped, fcslen); @@ -1288,7 +1286,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t * int_data = g_array_index(pn->interface_data, interface_data_t, 0); pcapng_debug1("pcapng_read_simple_packet_block: Need to read pseudo header of size %d", - pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)); + pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)); /* No time stamp in a simple packet block; no options, either */ wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID; @@ -1301,14 +1299,13 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t * wblock->packet_header->drop_count = 0; wblock->packet_header->pack_flags = 0; - memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header)); + memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header)); pseudo_header_len = pcap_process_pseudo_header(fh, WTAP_FILE_PCAPNG, int_data.wtap_encap, wblock->data.simple_packet.cap_len, TRUE, wblock->packet_header, - (union wtap_pseudo_header *)wblock->pseudo_header, err, err_info); if (pseudo_header_len < 0) { @@ -1317,12 +1314,12 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t * wblock->packet_header->caplen = wblock->data.simple_packet.cap_len - pseudo_header_len; wblock->packet_header->len = wblock->data.packet.packet_len - pseudo_header_len; block_read += pseudo_header_len; - if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)) { + if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) { pcapng_debug1("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.", pseudo_header_len); } - memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header)); + memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header)); /* "Simple Packet Block" read capture data */ errno = WTAP_ERR_CANT_READ; @@ -1349,7 +1346,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t * } pcap_read_post_process(WTAP_FILE_PCAPNG, int_data.wtap_encap, - (union wtap_pseudo_header *)wblock->pseudo_header, + (union wtap_pseudo_header *)&wblock->packet_header->pseudo_header, (guint8 *) (wblock->frame_buffer), (int) wblock->data.simple_packet.cap_len, pn->byte_swapped, pn->if_fcslen); @@ -2043,7 +2040,6 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) /* we don't expect any packet blocks yet */ wblock.frame_buffer = NULL; - wblock.pseudo_header = NULL; wblock.packet_header = NULL; wblock.file_encap = &wth->file_encap; @@ -2170,7 +2166,6 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) } wblock.frame_buffer = buffer_start_ptr(wth->frame_buffer); - wblock.pseudo_header = &wth->phdr.pseudo_header; wblock.packet_header = &wth->phdr; wblock.file_encap = &wth->file_encap; @@ -2281,7 +2276,6 @@ pcapng_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, guint8 *pd, int length _U_, int *err, gchar **err_info) { - union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; pcapng_t *pcapng = (pcapng_t *)wth->priv; guint64 bytes_read64; int bytes_read; @@ -2296,8 +2290,7 @@ pcapng_seek_read(wtap *wth, gint64 seek_off, pcapng_debug1("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off); wblock.frame_buffer = pd; - wblock.pseudo_header = pseudo_header; - wblock.packet_header = &wth->phdr; + wblock.packet_header = phdr; wblock.file_encap = &wth->file_encap; /* read the block */