aboutsummaryrefslogtreecommitdiffstats
path: root/dumpcap.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2018-10-17 17:59:07 +0000
committerMichael Mann <mmann78@netscape.net>2018-10-21 11:58:14 +0000
commitaea4e4b42ac3856b26d729dde7387bad37f261fc (patch)
tree3d87a0eef7610b7d351268851010f75396d79c47 /dumpcap.c
parent1957673703fb5e5865bfc4412393e20302569392 (diff)
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>
Diffstat (limited to 'dumpcap.c')
-rw-r--r--dumpcap.c74
1 files changed, 30 insertions, 44 deletions
diff --git a/dumpcap.c b/dumpcap.c
index 1991e9d0a2..5961456831 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -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);