summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2016-08-22 17:21:23 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-08-25 13:31:22 +0900
commit0255390a76479e4ecb3836dd33828fa1d59f763e (patch)
tree96797d2d54ee6b38945bdd70a5a78c792e5efc2d
parentd4b8bd609fda6ceb45d4dc9b9e0f48f3b1118ed2 (diff)
packet/bgp: Enable to parse the entire packet data
This patch fixes the TCP packet parser to return the BGP packet parser class if the TCP src or dst port is the reserved BGP port and enable to parse the entire packet data. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/lib/packet/bgp.py8
-rw-r--r--ryu/lib/packet/bmp.py10
-rw-r--r--ryu/lib/packet/tcp.py10
-rw-r--r--ryu/services/protocols/bgp/speaker.py2
-rw-r--r--ryu/tests/unit/packet/test_bgp.py27
5 files changed, 36 insertions, 21 deletions
diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index 68105a89..99da8677 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
@@ -41,6 +41,8 @@ from ryu.lib.pack_utils import msg_pack_into
reduce = six.moves.reduce
+TCP_SERVER_PORT = 179
+
BGP_MSG_OPEN = 1
BGP_MSG_UPDATE = 2
BGP_MSG_NOTIFICATION = 3
@@ -2238,7 +2240,8 @@ class BGPMessage(packet_base.PacketBase, _TypeDisp):
rest = buf[msglen:]
subcls = cls._lookup_type(type_)
kwargs = subcls.parser(binmsg)
- return subcls(marker=marker, len_=len_, type_=type_, **kwargs), rest
+ return subcls(marker=marker, len_=len_, type_=type_,
+ **kwargs), None, rest
def serialize(self, payload=None, prev=None):
# fixup
@@ -2661,4 +2664,5 @@ class StreamParser(stream_parser.StreamParser):
"""
def try_parse(self, data):
- return BGPMessage.parser(data)
+ msg, _, rest = BGPMessage.parser(data)
+ return msg, rest
diff --git a/ryu/lib/packet/bmp.py b/ryu/lib/packet/bmp.py
index c25e5749..b3a097c0 100644
--- a/ryu/lib/packet/bmp.py
+++ b/ryu/lib/packet/bmp.py
@@ -327,7 +327,7 @@ class BMPRouteMonitoring(BMPPeerMessage):
def parser(cls, buf):
kwargs, buf = super(BMPRouteMonitoring, cls).parser(buf)
- bgp_update, buf = BGPMessage.parser(buf)
+ bgp_update, _, buf = BGPMessage.parser(buf)
kwargs['bgp_update'] = bgp_update
@@ -498,11 +498,11 @@ class BMPPeerDownNotification(BMPPeerMessage):
buf = buf[struct.calcsize('!B'):]
if reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION:
- data, rest = BGPMessage.parser(buf)
+ data, _, rest = BGPMessage.parser(buf)
elif reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION:
data = struct.unpack_from('!H', six.binary_type(buf))
elif reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION:
- data, rest = BGPMessage.parser(buf)
+ data, _, rest = BGPMessage.parser(buf)
elif reason == BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION:
data = None
else:
@@ -609,8 +609,8 @@ class BMPPeerUpNotification(BMPPeerMessage):
rest = rest[cls._MIN_LEN:]
- sent_open_msg, rest = BGPMessage.parser(rest)
- received_open_msg, rest = BGPMessage.parser(rest)
+ sent_open_msg, _, rest = BGPMessage.parser(rest)
+ received_open_msg, _, rest = BGPMessage.parser(rest)
kwargs['sent_open_message'] = sent_open_msg
kwargs['received_open_message'] = received_open_msg
diff --git a/ryu/lib/packet/tcp.py b/ryu/lib/packet/tcp.py
index 1771b9a1..b61ac8cf 100644
--- a/ryu/lib/packet/tcp.py
+++ b/ryu/lib/packet/tcp.py
@@ -19,6 +19,7 @@ import logging
from . import packet_base
from . import packet_utils
+from . import bgp
from ryu.lib import stringify
@@ -108,6 +109,13 @@ class tcp(packet_base.PacketBase):
mask = sum(flags)
return (self.bits & mask) == mask
+ @staticmethod
+ def get_payload_type(src_port, dst_port):
+ if bgp.TCP_SERVER_PORT in [src_port, dst_port]:
+ return bgp.BGPMessage
+ else:
+ return None
+
@classmethod
def parser(cls, buf):
(src_port, dst_port, seq, ack, offset, bits, window_size,
@@ -132,7 +140,7 @@ class tcp(packet_base.PacketBase):
msg = cls(src_port, dst_port, seq, ack, offset, bits,
window_size, csum, urgent, option)
- return msg, None, buf[length:]
+ return msg, cls.get_payload_type(src_port, dst_port), buf[length:]
def serialize(self, payload, prev):
offset = self.offset << 4
diff --git a/ryu/services/protocols/bgp/speaker.py b/ryu/services/protocols/bgp/speaker.py
index 9c185daa..710efa71 100644
--- a/ryu/services/protocols/bgp/speaker.py
+++ b/ryu/services/protocols/bgp/speaker.py
@@ -350,7 +350,7 @@ class BgpProtocol(Protocol, Activity):
# If we have partial message we wait for rest of the message.
if len(self._recv_buff) < length:
return
- msg, rest = BGPMessage.parser(self._recv_buff)
+ msg, _, rest = BGPMessage.parser(self._recv_buff)
self._recv_buff = rest
# If we have a valid bgp message we call message handler.
diff --git a/ryu/tests/unit/packet/test_bgp.py b/ryu/tests/unit/packet/test_bgp.py
index b3c11984..d23b2592 100644
--- a/ryu/tests/unit/packet/test_bgp.py
+++ b/ryu/tests/unit/packet/test_bgp.py
@@ -22,6 +22,7 @@ import unittest
from nose.tools import eq_
from nose.tools import ok_
+from ryu.lib import pcaplib
from ryu.lib.packet import packet
from ryu.lib.packet import bgp
from ryu.lib.packet import afi
@@ -45,7 +46,7 @@ class Test_bgp(unittest.TestCase):
def test_open1(self):
msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.1')
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
eq_(len(msg), 29)
eq_(rest, b'')
@@ -67,7 +68,7 @@ class Test_bgp(unittest.TestCase):
msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2',
opt_param=opt_param)
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
ok_(len(msg) > 29)
eq_(rest, b'')
@@ -75,7 +76,7 @@ class Test_bgp(unittest.TestCase):
def test_update1(self):
msg = bgp.BGPUpdate()
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
eq_(len(msg), 23)
eq_(rest, b'')
@@ -153,7 +154,7 @@ class Test_bgp(unittest.TestCase):
path_attributes=path_attributes,
nlri=nlri)
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
ok_(len(msg) > 23)
eq_(rest, b'')
@@ -161,7 +162,7 @@ class Test_bgp(unittest.TestCase):
def test_keepalive(self):
msg = bgp.BGPKeepAlive()
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
eq_(len(msg), 19)
eq_(rest, b'')
@@ -170,7 +171,7 @@ class Test_bgp(unittest.TestCase):
data = b'hoge'
msg = bgp.BGPNotification(error_code=1, error_subcode=2, data=data)
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
eq_(len(msg), 21 + len(data))
eq_(rest, b'')
@@ -178,7 +179,7 @@ class Test_bgp(unittest.TestCase):
def test_route_refresh(self):
msg = bgp.BGPRouteRefresh(afi=afi.IP, safi=safi.MPLS_VPN)
binmsg = msg.serialize()
- msg2, rest = bgp.BGPMessage.parser(binmsg)
+ msg2, _, rest = bgp.BGPMessage.parser(binmsg)
eq_(str(msg), str(msg2))
eq_(len(msg), 23)
eq_(rest, b'')
@@ -208,11 +209,13 @@ class Test_bgp(unittest.TestCase):
]
for f in files:
- print('testing %s' % f)
- msg_buf = open(BGP4_PACKET_DATA_DIR + f + '.pcap', 'rb').read()
- pkt = packet.Packet(msg_buf)
- pkt.serialize()
- eq_(msg_buf, pkt.data)
+ print('\n*** testing %s ...' % f)
+ for _, buf in pcaplib.Reader(
+ open(BGP4_PACKET_DATA_DIR + f + '.pcap', 'rb')):
+ pkt = packet.Packet(buf)
+ print(pkt)
+ pkt.serialize()
+ eq_(buf, pkt.data)
def test_json1(self):
opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200,