summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-11-03 18:34:28 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-11-03 18:50:51 -0400
commit7ad651c3ffd4779c5d4e7cbf1f03ede56b1e440d (patch)
treea0d423c73d4126b7e355804e3d6b832cbe3c38a7 /gst
parent16ec12371aa3a0cdb3701f7526adf6f41705806b (diff)
downloadgstreamer-plugins-bad-7ad651c3ffd4779c5d4e7cbf1f03ede56b1e440d.tar.gz
pcapparse: Add support for Linux Cooked Capture (SLL) frames
Diffstat (limited to 'gst')
-rw-r--r--gst/pcapparse/gstpcapparse.c34
-rw-r--r--gst/pcapparse/gstpcapparse.h7
2 files changed, 33 insertions, 8 deletions
diff --git a/gst/pcapparse/gstpcapparse.c b/gst/pcapparse/gstpcapparse.c
index 925551fd0..640bbe36c 100644
--- a/gst/pcapparse/gstpcapparse.c
+++ b/gst/pcapparse/gstpcapparse.c
@@ -319,6 +319,7 @@ gst_pcap_parse_read_uint32 (GstPcapParse * self, const guint8 * p)
}
#define ETH_HEADER_LEN 14
+#define SLL_HEADER_LEN 16
#define IP_HEADER_MIN_LEN 20
#define UDP_HEADER_LEN 8
@@ -341,14 +342,29 @@ gst_pcap_parse_scan_frame (GstPcapParse * self,
guint16 udp_dst_port;
guint16 udp_len;
- if (buf_size < ETH_HEADER_LEN + IP_HEADER_MIN_LEN + UDP_HEADER_LEN)
- return FALSE;
+ switch (self->linktype) {
+ case DLT_ETHER:
+ if (buf_size < ETH_HEADER_LEN + IP_HEADER_MIN_LEN + UDP_HEADER_LEN)
+ return FALSE;
- eth_type = GUINT16_FROM_BE (*((guint16 *) (buf + 12)));
- if (eth_type != 0x800)
- return FALSE;
+ eth_type = GUINT16_FROM_BE (*((guint16 *) (buf + 12)));
+ if (eth_type != 0x800)
+ return FALSE;
+
+ buf_ip = buf + ETH_HEADER_LEN;
+ break;
+ case DLT_SLL:
+ if (buf_size < SLL_HEADER_LEN + IP_HEADER_MIN_LEN + UDP_HEADER_LEN)
+ return FALSE;
+
+ eth_type = GUINT16_FROM_BE (*((guint16 *) (buf + 2)));
- buf_ip = buf + ETH_HEADER_LEN;
+ if (eth_type != 1)
+ return FALSE;
+
+ buf_ip = buf + SLL_HEADER_LEN;
+ break;
+ }
b = *buf_ip;
if (((b >> 4) & 0x0f) != 4)
@@ -501,14 +517,16 @@ gst_pcap_parse_chain (GstPad * pad, GstBuffer * buffer)
linktype = gst_pcap_parse_read_uint32 (self, data + 20);
- if (linktype != 1) {
+ if (linktype != DLT_ETHER && linktype != DLT_SLL) {
GST_ELEMENT_ERROR (self, STREAM, WRONG_TYPE, (NULL),
- ("Only Ethernet packets of type 1 understood,"
+ ("Only dumps of type Ethernet or Linux Coooked (SLL) understood,"
" type %d unknown", linktype));
ret = GST_FLOW_ERROR;
goto out;
}
+ self->linktype = linktype;
+
gst_adapter_flush (self->adapter, 24);
self->initialized = TRUE;
}
diff --git a/gst/pcapparse/gstpcapparse.h b/gst/pcapparse/gstpcapparse.h
index 78fe1abfb..35742394e 100644
--- a/gst/pcapparse/gstpcapparse.h
+++ b/gst/pcapparse/gstpcapparse.h
@@ -45,6 +45,12 @@ typedef enum
PCAP_PARSE_STATE_PARSING,
} GstPcapParseState;
+typedef enum
+{
+ DLT_ETHER = 1,
+ DLT_SLL = 113
+} GstPcapParseLinktype;
+
/**
* GstPcapParse:
*
@@ -72,6 +78,7 @@ struct _GstPcapParse
gboolean swap_endian;
gint64 cur_packet_size;
GstClockTime cur_ts;
+ GstPcapParseLinktype linktype;
gboolean newsegment_sent;