From: Marvin Liu <yong.liu@intel.com>
To: dts@dpdk.org
Cc: Marvin Liu <yong.liu@intel.com>
Subject: [dts] [PATCH 1/2] framework packet: support packet filter in sniff command
Date: Tue, 24 Jan 2017 16:24:50 +0800 [thread overview]
Message-ID: <1485246291-6496-1-git-send-email-yong.liu@intel.com> (raw)
This function can be helpful for filter out those unexpected packets.
Filter will be translated to bpf format and append into tcpdump command
line.
Signed-off-by: Marvin Liu <yong.liu@intel.com>
diff --git a/framework/packet.py b/framework/packet.py
index 05a3d1f..52b0821 100755
--- a/framework/packet.py
+++ b/framework/packet.py
@@ -41,6 +41,7 @@ import re
import signal
import random
import subprocess
+import shlex # separate command line for pipe
from uuid import uuid4
from settings import FOLDERS
@@ -95,6 +96,9 @@ SNIFF_PIDS = {}
# used in pktgen or tgen
PKTGEN_PIDS = {}
+# default filter for LLDP packet
+LLDP_FILTER = {'layer': 'ether', 'config': {'type': 'not lldp'}}
+
class scapy(object):
SCAPY_LAYERS = {
@@ -165,7 +169,7 @@ class scapy(object):
def vlan(self, pkt_layer, vlan, prio=0, type=None):
if pkt_layer.name != "802.1Q":
- return
+ return
pkt_layer.vlan = int(vlan)
pkt_layer.prio = prio
if type is not None:
@@ -183,7 +187,7 @@ class scapy(object):
def etag(self, pkt_layer, ECIDbase=0, prio=0, type=None):
if pkt_layer.name != "802.1BR":
- return
+ return
pkt_layer.ECIDbase = int(ECIDbase)
pkt_layer.prio = prio
if type is not None:
@@ -224,6 +228,8 @@ class scapy(object):
value = layer.src
elif element == 'dst':
value = layer.dst
+ else:
+ value = layer.getfieldval(element)
return value
@@ -237,6 +243,8 @@ class scapy(object):
value = layer.sport
elif element == 'dst':
value = layer.dport
+ else:
+ value = layer.getfieldval(element)
return value
@@ -303,7 +311,7 @@ class scapy(object):
if payload is not None:
pkt_layer.load = ''
for hex1, hex2 in payload:
- pkt_layer.load += struct.pack("=B", int('%s%s' %(hex1, hex2), 16))
+ pkt_layer.load += struct.pack("=B", int('%s%s' % (hex1, hex2), 16))
def gre(self, pkt_layer, proto=None):
if proto is not None:
@@ -499,11 +507,11 @@ class Packet(object):
'VLAN': 'vlan',
'ETAG': 'etag',
'IP': 'ipv4',
- 'IPv4-TUNNEL':'inner_ipv4',
+ 'IPv4-TUNNEL': 'inner_ipv4',
'IPihl': 'ipv4ihl',
'IPFRAG': 'ipv4_ext',
'IPv6': 'ipv6',
- 'IPv6-TUNNEL':'inner_ipv6',
+ 'IPv6-TUNNEL': 'inner_ipv6',
'IPv6FRAG': 'ipv6_frag',
'IPv6EXT': 'ipv6_ext',
'IPv6EXT2': 'ipv6_ext2',
@@ -706,14 +714,68 @@ def save_packets(pkts=None, filename=None):
pass
-def sniff_packets(intf, count=0, timeout=5):
+def get_ether_type(eth_type=""):
+ # need add more types later
+ if eth_type.lower() == "lldp":
+ return '0x88cc'
+ elif eth_type.lower() == "ip":
+ return '0x0800'
+ elif eth_type.lower() == "ipv6":
+ return '0x86dd'
+
+ return 'not support'
+
+
+def get_filter_cmd(filters=[]):
+ """
+ Return bpd formated filter string, only support ether layer now
+ """
+ filter_sep = " and "
+ filter_cmds = ""
+ for pktfilter in filters:
+ filter_cmd = ""
+ if pktfilter['layer'] == 'ether':
+ if pktfilter['config'].keys()[0] == 'dst':
+ dmac = pktfilter['config']['dst']
+ filter_cmd = "ether dst %s" % dmac
+ elif pktfilter['config'].keys()[0] == 'src':
+ smac = pktfilter['config']['src']
+ filter_cmd = "ether src %s" % smac
+ elif pktfilter['config'].keys()[0] == 'type':
+ eth_type = pktfilter['config']['type']
+ eth_format = r"(\w+) (\w+)"
+ m = re.match(eth_format, eth_type)
+ if m:
+ type_hex = get_ether_type(m.group(2))
+ if type_hex == 'not support':
+ continue
+ if m.group(1) == 'is':
+ filter_cmd = 'ether[12:2] = %s' % type_hex
+ elif m.group(1) == 'not':
+ filter_cmd = 'ether[12:2] != %s' % type_hex
+
+ if len(filter_cmds):
+ if len(filter_cmd):
+ filter_cmds += filter_sep
+ filter_cmds += filter_cmd
+ else:
+ filter_cmds = filter_cmd
+
+ if len(filter_cmds):
+ return ' \'' + filter_cmds + '\' '
+ else:
+ return ""
+
+
+def sniff_packets(intf, count=0, timeout=5, filters=[]):
"""
sniff all packets for certain port in certain seconds
"""
param = ""
direct_param = r"(\s+)\[ -(\w) in\|out\|inout \]"
tcpdump_help = subprocess.check_output("tcpdump -h; echo 0",
- stderr=subprocess.STDOUT, shell=True)
+ stderr=subprocess.STDOUT,
+ shell=True)
for line in tcpdump_help.split('\n'):
m = re.match(direct_param, line)
if m:
@@ -722,16 +784,23 @@ def sniff_packets(intf, count=0, timeout=5):
if len(param) == 0:
print "tcpdump not support direction chioce!!!"
- sniff_cmd = 'tcpdump -i %(INTF)s %(IN_PARAM)s -w %(FILE)s'
+ if LLDP_FILTER not in filters:
+ filters.append(LLDP_FILTER)
+
+ filter_cmd = get_filter_cmd(filters)
+
+ sniff_cmd = 'tcpdump -i %(INTF)s %(FILTER)s %(IN_PARAM)s -w %(FILE)s'
options = {'INTF': intf, 'COUNT': count, 'IN_PARAM': param,
- 'FILE': '/tmp/sniff_%s.pcap' % intf}
+ 'FILE': '/tmp/sniff_%s.pcap' % intf,
+ 'FILTER': filter_cmd}
if count:
sniff_cmd += ' -c %(COUNT)d'
cmd = sniff_cmd % options
else:
cmd = sniff_cmd % options
- args = cmd.split()
+ args = shlex.split(cmd)
+
pipe = subprocess.Popen(args)
index = str(time.time())
SNIFF_PIDS[index] = (pipe, intf, timeout)
@@ -807,6 +876,7 @@ def compare_pktload(pkt1=None, pkt2=None, layer="L2"):
else:
return False
+
def strip_pktload(pkt=None, layer="L2"):
if layer == "L2":
l_idx = 0
@@ -827,6 +897,8 @@ def strip_pktload(pkt=None, layer="L2"):
###############################################################################
###############################################################################
if __name__ == "__main__":
+ inst = sniff_packets("lo", timeout=5, filters=[{'layer': 'ether',
+ 'config': {'dst': 'FF:FF:FF:FF:FF:FF'}}])
inst = sniff_packets("lo", timeout=5)
pkt = Packet(pkt_type='UDP')
pkt.send_pkt(tx_port='lo')
@@ -858,6 +930,6 @@ if __name__ == "__main__":
'vxlan', 'inner_mac', 'inner_ipv4', 'inner_udp', 'raw'])
# config packet
pkt.config_layers([('ether', {'dst': '00:11:22:33:44:55'}), ('ipv4', {'dst': '1.1.1.1'}),
- ('vxlan', {'vni': 2}), ('raw', {'payload': ['01'] * 18})])
+ ('vxlan', {'vni': 2}), ('raw', {'payload': ['01'] * 18})])
pkt.send_pkt(tx_port='lo')
--
1.9.1
next reply other threads:[~2017-01-24 8:23 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-24 8:24 Marvin Liu [this message]
2017-01-24 8:24 ` [dts] [PATCH 2/2] tests ipfrag: fix fragmented packet check incorrectly Marvin Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1485246291-6496-1-git-send-email-yong.liu@intel.com \
--to=yong.liu@intel.com \
--cc=dts@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).