mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-01-24 18:11:24 +01:00
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>
This commit is contained in:
parent
d4b8bd609f
commit
0255390a76
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user