pcapparse: Add support for Linux Cooked Capture (SLL) frames
authorOlivier Crête <olivier.crete@collabora.co.uk>
Wed, 3 Nov 2010 22:34:28 +0000 (18:34 -0400)
committerOlivier Crête <olivier.crete@collabora.co.uk>
Wed, 3 Nov 2010 22:50:51 +0000 (18:50 -0400)
gst/pcapparse/gstpcapparse.c
gst/pcapparse/gstpcapparse.h

index 925551fd00252df9cff26e6cf462765e6863e94c..640bbe36cdd5d2c31e2ed6dc7d51c16fbdc3a41d 100644 (file)
@@ -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;
     }
index 78fe1abfb701e7b9be12ef95b9c0604d1e26e572..35742394ef9c2f9ab91840a55a1a16819c1dc676 100644 (file)
@@ -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;