diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2016-08-22 17:21:23 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-08-25 13:31:22 +0900 |
commit | 0255390a76479e4ecb3836dd33828fa1d59f763e (patch) | |
tree | 96797d2d54ee6b38945bdd70a5a78c792e5efc2d | |
parent | d4b8bd609fda6ceb45d4dc9b9e0f48f3b1118ed2 (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.py | 8 | ||||
-rw-r--r-- | ryu/lib/packet/bmp.py | 10 | ||||
-rw-r--r-- | ryu/lib/packet/tcp.py | 10 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/speaker.py | 2 | ||||
-rw-r--r-- | ryu/tests/unit/packet/test_bgp.py | 27 |
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, |