Dumpcap: Swap bytes only for pcap sources.

Instead of trying to byte swap all of pcapng's block types, refuse
to handle pcapng sources that have a different byte order.

Rename cap_pipe_adjust_header to cap_pipe_adjust_pcap_header.

Change-Id: I2615da57ba9d3fc365c631dc191f7767a284d460
Reviewed-on: https://code.wireshark.org/review/30235
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: James Ko <jim.list@hotmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Gerald Combs 2018-10-17 17:59:07 +00:00 committed by Michael Mann
parent 1957673703
commit aea4e4b42a
1 changed files with 30 additions and 44 deletions

View File

@ -223,8 +223,9 @@ typedef enum {
} cap_pipe_err_t;
typedef struct _pcap_pipe_info {
struct pcap_hdr hdr; /**< Pcap header when capturing from a pipe */
struct pcaprec_modified_hdr rechdr; /**< Pcap record header when capturing from a pipe */
gboolean byte_swapped; /**< TRUE if data in the pipe is byte swapped. */
struct pcap_hdr hdr; /**< Pcap header when capturing from a pipe */
struct pcaprec_modified_hdr rechdr; /**< Pcap record header when capturing from a pipe */
} pcap_pipe_info_t;
typedef struct _pcapng_pipe_info {
@ -265,7 +266,6 @@ typedef struct _capture_src {
#endif
int cap_pipe_fd; /**< the file descriptor of the capture pipe */
gboolean cap_pipe_modified; /**< TRUE if data in the pipe uses modified pcap headers */
gboolean cap_pipe_byte_swapped; /**< TRUE if data in the pipe is byte swapped */
char * cap_pipe_databuf; /**< Pointer to the data buffer we've allocated */
size_t cap_pipe_databuf_size; /**< Current size of the data buffer */
guint cap_pipe_max_pkt_size; /**< Maximum packet size allowed */
@ -1198,7 +1198,7 @@ relinquish_privs_except_capture(void)
/* Take care of byte order in the libpcap headers read from pipes.
* (function taken from wiretap/libpcap.c) */
static void
cap_pipe_adjust_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
cap_pipe_adjust_pcap_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
{
if (byte_swapped) {
/* Byte-swap the record header fields. */
@ -1802,14 +1802,14 @@ cap_pipe_open_live(char *pipename,
case PCAP_NSEC_MAGIC:
/* Host that wrote it has our byte order, and was running
a program using either standard or ss990417 libpcap. */
pcap_src->cap_pipe_byte_swapped = FALSE;
pcap_src->cap_pipe_info.pcap.byte_swapped = FALSE;
pcap_src->cap_pipe_modified = FALSE;
pcap_src->ts_nsec = magic == PCAP_NSEC_MAGIC;
break;
case PCAP_MODIFIED_MAGIC:
/* Host that wrote it has our byte order, but was running
a program using either ss990915 or ss991029 libpcap. */
pcap_src->cap_pipe_byte_swapped = FALSE;
pcap_src->cap_pipe_info.pcap.byte_swapped = FALSE;
pcap_src->cap_pipe_modified = TRUE;
break;
case PCAP_SWAPPED_MAGIC:
@ -1817,7 +1817,7 @@ cap_pipe_open_live(char *pipename,
/* Host that wrote it has a byte order opposite to ours,
and was running a program using either standard or
ss990417 libpcap. */
pcap_src->cap_pipe_byte_swapped = TRUE;
pcap_src->cap_pipe_info.pcap.byte_swapped = TRUE;
pcap_src->cap_pipe_modified = FALSE;
pcap_src->ts_nsec = magic == PCAP_SWAPPED_NSEC_MAGIC;
break;
@ -1825,7 +1825,7 @@ cap_pipe_open_live(char *pipename,
/* Host that wrote it out has a byte order opposite to
ours, and was running a program using either ss990915
or ss991029 libpcap. */
pcap_src->cap_pipe_byte_swapped = TRUE;
pcap_src->cap_pipe_info.pcap.byte_swapped = TRUE;
pcap_src->cap_pipe_modified = TRUE;
break;
case BLOCK_TYPE_SHB:
@ -1909,7 +1909,7 @@ pcap_pipe_open_live(int fd,
}
#endif
if (pcap_src->cap_pipe_byte_swapped) {
if (pcap_src->cap_pipe_info.pcap.byte_swapped) {
/* Byte-swap the header fields about which we care. */
hdr->version_major = GUINT16_SWAP_LE_BE(hdr->version_major);
hdr->version_minor = GUINT16_SWAP_LE_BE(hdr->version_minor);
@ -1955,7 +1955,6 @@ pcapng_read_shb(capture_src *pcap_src,
char *errmsg,
int errmsgl)
{
struct pcapng_block_header_s *bh = &pcap_src->cap_pipe_info.pcapng.bh;
struct pcapng_section_header_block_s *shb = &pcap_src->cap_pipe_info.pcapng.shb;
#ifdef _WIN32
@ -1991,26 +1990,30 @@ pcapng_read_shb(capture_src *pcap_src,
{
case PCAPNG_MAGIC:
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng SHB MAGIC");
pcap_src->cap_pipe_byte_swapped = FALSE;
break;
case PCAPNG_SWAPPED_MAGIC:
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng SHB SWAPPED MAGIC");
pcap_src->cap_pipe_byte_swapped = TRUE;
break;
/*
* pcapng sources can contain all sorts of block types. Rather than add a bunch of
* complexity to this code (which is often privileged), punt and tell the user to
* swap bytes elsewhere.
*/
#if G_BYTE_ORDER == G_BIG_ENDIAN
#define OUR_ENDIAN "big"
#define IFACE_ENDIAN "little"
#else
#define OUR_ENDIAN "little"
#define IFACE_ENDIAN "big"
#endif
g_snprintf(errmsg, errmsgl, "Interface %u is " IFACE_ENDIAN " endian but we're " OUR_ENDIAN " endian.",
pcap_src->interface_id);
return -1;
default:
/* Not a pcapng type we know about, or not pcapng at all. */
g_snprintf(errmsg, errmsgl, "Unrecognized pcapng format or not pcapng data.");
return -1;
}
if (pcap_src->cap_pipe_byte_swapped) {
/* Byte-swap the header fields about which we care. */
shb->version_major = GUINT16_SWAP_LE_BE(shb->version_major);
shb->version_minor = GUINT16_SWAP_LE_BE(shb->version_minor);
shb->section_length = GUINT64_SWAP_LE_BE(shb->section_length);
bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
}
pcap_src->cap_pipe_max_pkt_size = WTAP_MAX_PACKET_SIZE_STANDARD;
/* Setup state to capture any options following the section header block */
@ -2019,21 +2022,6 @@ pcapng_read_shb(capture_src *pcap_src,
return 0;
}
static int
pcapng_write_saved_block(capture_src *pcap_src, struct pcapng_block_header_s *bh)
{
guint32 length = bh->block_total_length;
if (pcap_src->cap_pipe_byte_swapped) {
length = GUINT32_SWAP_LE_BE(length);
}
return pcapng_write_block(global_ld.pdh,
(const guint8 *) bh,
length,
&global_ld.bytes_written, &global_ld.err);
}
/* Save SHB and IDB blocks to playback whenever we change output files. */
/* The list is saved in reverse order of blocks added */
static gboolean
@ -2272,7 +2260,7 @@ pcap_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int errms
case PD_REC_HDR_READ:
/* We've read the header. Take care of byte order. */
cap_pipe_adjust_header(pcap_src->cap_pipe_byte_swapped, &pcap_info->hdr,
cap_pipe_adjust_pcap_header(pcap_src->cap_pipe_info.pcap.byte_swapped, &pcap_info->hdr,
&pcap_info->rechdr.hdr);
if (pcap_info->rechdr.hdr.incl_len > pcap_src->cap_pipe_max_pkt_size) {
/*
@ -2504,12 +2492,6 @@ pcapng_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int err
return 1;
}
/* We've read the header. Take care of byte order. */
if (pcap_src->cap_pipe_byte_swapped) {
/* Byte-swap the record header fields. */
bh->block_type = GUINT32_SWAP_LE_BE(bh->block_type);
bh->block_total_length = GUINT32_SWAP_LE_BE(bh->block_total_length);
}
if (bh->block_total_length > pcap_src->cap_pipe_max_pkt_size) {
/*
* The record contains more data than the advertised/allowed in the
@ -3502,7 +3484,11 @@ do_file_switch_or_stop(capture_options *capture_opts,
GList *list = rlist;
successful = TRUE;
while (list && successful) {
successful = pcapng_write_saved_block(pcap_src, (struct pcapng_block_header_s *) list->data);
struct pcapng_block_header_s *bh = (struct pcapng_block_header_s *) list->data;
successful = pcapng_write_block(global_ld.pdh,
(const guint8 *) bh,
bh->block_total_length,
&global_ld.bytes_written, &global_ld.err);
list = g_list_next(list);
}
pcap_src->cap_pipe_info.pcapng.saved_blocks = g_list_reverse(rlist);