Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/scapy/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,8 @@ The ``data`` argument is bytes and the ``metadata`` argument is a dictionary whi
- ``metadata.get("tcp_psh", False)``: will be present if the PUSH flag is set
- ``metadata.get("tcp_end", False)``: will be present if the END or RESET flag is set

If ``tcp_reassemble`` **returns any padding**, it will be kept for the next payload.

Filters
-------

Expand Down
26 changes: 22 additions & 4 deletions scapy/contrib/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,17 @@ def dispatch_hook(cls, _pkt=None, *args, **kargs):

return _bgp_dispatcher(_pkt)

@classmethod
def tcp_reassemble(cls, data, *args, **kwargs):
if len(data) < 18:
return None
if data[:16] == _BGP_HEADER_MARKER:
length = struct.unpack("!H", data[16:18])[0]
if len(data) >= length:
return cls(data[:length]) / conf.padding_layer(data[length:])
else:
return cls(data)

def post_build(self, p, pay):
if self.len is None:
length = len(p)
Expand Down Expand Up @@ -520,6 +531,8 @@ def dispatch_hook(cls, _pkt=None, *args, **kargs):

return _bgp_dispatcher(_pkt)

tcp_reassemble = BGPHeader.tcp_reassemble

def guess_payload_class(self, p):
cls = None
if len(p) > 15 and p[:16] == _BGP_HEADER_MARKER:
Expand Down Expand Up @@ -755,7 +768,8 @@ class ORFTuple(Packet):
"entries",
[],
ORFTuple,
count_from=lambda p: p.orf_number
count_from=lambda p: p.orf_number,
max_count=20000,
)
]

Expand Down Expand Up @@ -811,7 +825,8 @@ class BGPCapORF(BGPCapability):
"orf",
[],
BGPCapORFBlock,
length_from=lambda p: p.length
length_from=lambda p: p.length,
max_count=20000,
)
]

Expand Down Expand Up @@ -1910,7 +1925,8 @@ class BGPPAMPReachNLRI(Packet):
ConditionalField(IP6Field("nh_v6_link_local", "::"),
lambda x: x.afi == 2 and x.nh_addr_len == 32),
ByteField("reserved", 0),
MPReachNLRIPacketListField("nlri", [], BGPNLRI_IPv6)]
MPReachNLRIPacketListField("nlri", [], BGPNLRI_IPv6,
max_count=20000)]

def post_build(self, p, pay):
if self.nlri is None:
Expand Down Expand Up @@ -2216,7 +2232,8 @@ class BGPUpdate(BGP):
BGPPathAttr,
length_from=lambda p: p.path_attr_len
),
BGPNLRIPacketListField("nlri", [], "IPv4")
BGPNLRIPacketListField("nlri", [], "IPv4",
max_count=20000)
]

def post_build(self, p, pay):
Expand Down Expand Up @@ -2574,6 +2591,7 @@ class BGPORF(Packet):
[],
Packet,
length_from=lambda p: p.orf_len,
max_count=20000,
)
]

Expand Down
7 changes: 7 additions & 0 deletions test/contrib/bgp.uts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ h = BGP(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x
assert h.type == BGP.OPEN_TYPE
assert h.len == 19

= BGP - Test TCP reassembly
pkts = sniff(offline=scapy_path("/test/pcaps/bgp_fragmented.pcap.gz"), session=TCPSession)
assert len(pkts) == 1
assert BGPUpdate in pkts[0]
assert len(pkts[0].nlri) == 512
assert pkts[0].nlri[511].prefix == '91.0.177.0/24'

############################### BGPKeepAlive #################################
+ BGPKeepAlive class tests

Expand Down
Binary file added test/pcaps/bgp_fragmented.pcap.gz
Binary file not shown.