mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
pcapparse: also support extracting tcp data
This commit is contained in:
parent
04f0b55609
commit
93af6831e2
1 changed files with 42 additions and 21 deletions
|
@ -20,8 +20,8 @@
|
||||||
/**
|
/**
|
||||||
* SECTION:element-pcapparse
|
* SECTION:element-pcapparse
|
||||||
*
|
*
|
||||||
* Extracts payloads from Ethernet-encapsulated IP packets, currently limited
|
* Extracts payloads from Ethernet-encapsulated IP packets.
|
||||||
* to UDP. Use #GstPcapParse:src-ip, #GstPcapParse:dst-ip,
|
* Use #GstPcapParse:src-ip, #GstPcapParse:dst-ip,
|
||||||
* #GstPcapParse:src-port and #GstPcapParse:dst-port to restrict which packets
|
* #GstPcapParse:src-port and #GstPcapParse:dst-port to restrict which packets
|
||||||
* should be included.
|
* should be included.
|
||||||
*
|
*
|
||||||
|
@ -324,6 +324,8 @@ gst_pcap_parse_read_uint32 (GstPcapParse * self, const guint8 * p)
|
||||||
#define UDP_HEADER_LEN 8
|
#define UDP_HEADER_LEN 8
|
||||||
|
|
||||||
#define IP_PROTO_UDP 17
|
#define IP_PROTO_UDP 17
|
||||||
|
#define IP_PROTO_TCP 6
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pcap_parse_scan_frame (GstPcapParse * self,
|
gst_pcap_parse_scan_frame (GstPcapParse * self,
|
||||||
|
@ -331,16 +333,16 @@ gst_pcap_parse_scan_frame (GstPcapParse * self,
|
||||||
gint buf_size, const guint8 ** payload, gint * payload_size)
|
gint buf_size, const guint8 ** payload, gint * payload_size)
|
||||||
{
|
{
|
||||||
const guint8 *buf_ip = 0;
|
const guint8 *buf_ip = 0;
|
||||||
const guint8 *buf_udp;
|
const guint8 *buf_proto;
|
||||||
guint16 eth_type;
|
guint16 eth_type;
|
||||||
guint8 b;
|
guint8 b;
|
||||||
guint8 ip_header_size;
|
guint8 ip_header_size;
|
||||||
guint8 ip_protocol;
|
guint8 ip_protocol;
|
||||||
guint32 ip_src_addr;
|
guint32 ip_src_addr;
|
||||||
guint32 ip_dst_addr;
|
guint32 ip_dst_addr;
|
||||||
guint16 udp_src_port;
|
guint16 src_port;
|
||||||
guint16 udp_dst_port;
|
guint16 dst_port;
|
||||||
guint16 udp_len;
|
guint16 len;
|
||||||
|
|
||||||
switch (self->linktype) {
|
switch (self->linktype) {
|
||||||
case DLT_ETHER:
|
case DLT_ETHER:
|
||||||
|
@ -375,34 +377,53 @@ gst_pcap_parse_scan_frame (GstPcapParse * self,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ip_protocol = *(buf_ip + 9);
|
ip_protocol = *(buf_ip + 9);
|
||||||
if (ip_protocol != IP_PROTO_UDP)
|
GST_LOG_OBJECT (self, "ip proto %d", (gint) ip_protocol);
|
||||||
|
|
||||||
|
if (ip_protocol != IP_PROTO_UDP && ip_protocol != IP_PROTO_TCP)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* ip info */
|
||||||
ip_src_addr = *((guint32 *) (buf_ip + 12));
|
ip_src_addr = *((guint32 *) (buf_ip + 12));
|
||||||
|
ip_dst_addr = *((guint32 *) (buf_ip + 16));
|
||||||
|
buf_proto = buf_ip + ip_header_size;
|
||||||
|
|
||||||
|
/* ok for tcp and udp */
|
||||||
|
src_port = GUINT16_FROM_BE (*((guint16 *) (buf_proto + 0)));
|
||||||
|
dst_port = GUINT16_FROM_BE (*((guint16 *) (buf_proto + 2)));
|
||||||
|
|
||||||
|
/* extract some params and data according to protocol */
|
||||||
|
if (ip_protocol == IP_PROTO_UDP) {
|
||||||
|
len = GUINT16_FROM_BE (*((guint16 *) (buf_proto + 4)));
|
||||||
|
if (len < UDP_HEADER_LEN || buf_proto + len > buf + buf_size)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*payload = buf_proto + UDP_HEADER_LEN;
|
||||||
|
*payload_size = len - UDP_HEADER_LEN;
|
||||||
|
} else {
|
||||||
|
if (buf_proto + 12 >= buf + buf_size)
|
||||||
|
return FALSE;
|
||||||
|
len = (buf_proto[12] >> 4) * 4;
|
||||||
|
if (buf_proto + len > buf + buf_size)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* all remaining data following tcp header is payload */
|
||||||
|
*payload = buf_proto + len;
|
||||||
|
*payload_size = self->cur_packet_size - (buf_proto - buf) - len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* but still filter as configured */
|
||||||
if (self->src_ip >= 0 && ip_src_addr != self->src_ip)
|
if (self->src_ip >= 0 && ip_src_addr != self->src_ip)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ip_dst_addr = *((guint32 *) (buf_ip + 16));
|
|
||||||
if (self->dst_ip >= 0 && ip_dst_addr != self->dst_ip)
|
if (self->dst_ip >= 0 && ip_dst_addr != self->dst_ip)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
buf_udp = buf_ip + ip_header_size;
|
if (self->src_port >= 0 && src_port != self->src_port)
|
||||||
|
|
||||||
udp_src_port = GUINT16_FROM_BE (*((guint16 *) (buf_udp + 0)));
|
|
||||||
if (self->src_port >= 0 && udp_src_port != self->src_port)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
udp_dst_port = GUINT16_FROM_BE (*((guint16 *) (buf_udp + 2)));
|
if (self->dst_port >= 0 && dst_port != self->dst_port)
|
||||||
if (self->dst_port >= 0 && udp_dst_port != self->dst_port)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
udp_len = GUINT16_FROM_BE (*((guint16 *) (buf_udp + 4)));
|
|
||||||
if (udp_len < UDP_HEADER_LEN || buf_udp + udp_len > buf + buf_size)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
*payload = buf_udp + UDP_HEADER_LEN;
|
|
||||||
*payload_size = udp_len - UDP_HEADER_LEN;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue