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
20 changes: 19 additions & 1 deletion scapy/contrib/roce.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from scapy.fields import ByteEnumField, ByteField, XByteField, \
ShortField, XShortField, XLongField, BitField, XBitField, FCSField
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.l2 import Ether
from scapy.compat import raw
from scapy.error import warning
Expand Down Expand Up @@ -179,8 +180,25 @@ def compute_icrc(self, p):
pshdr[UDP].payload = Raw(bth + payload + icrc_placeholder)
icrc = crc32(raw(pshdr)[:-4]) & 0xffffffff
return self.pack_icrc(icrc)
elif isinstance(ip, IPv6):
# pseudo-LRH / IPv6 / UDP / BTH / payload
pshdr = Raw(b'\xff' * 8) / ip.copy()
pshdr.hlim = 0xff
pshdr.fl = 0xfffff
pshdr.tc = 0xff
pshdr[UDP].chksum = 0xffff
pshdr[BTH].fecn = 1
pshdr[BTH].becn = 1
pshdr[BTH].resv6 = 0xff
bth = pshdr[BTH].self_build()
payload = raw(pshdr[BTH].payload)
# add ICRC placeholder just to get the right IPv6.plen and
# UDP.length
icrc_placeholder = b'\xff\xff\xff\xff'
pshdr[UDP].payload = Raw(bth + payload + icrc_placeholder)
icrc = crc32(raw(pshdr)[:-4]) & 0xffffffff
return self.pack_icrc(icrc)
else:
# TODO support IPv6
warning("The underlayer protocol %s is not supported.",
ip and ip.name)
return self.pack_icrc(0)
Expand Down
21 changes: 21 additions & 0 deletions test/contrib/roce.uts
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,24 @@ assert not pkt[BTH].ackreq
assert pkt[AETH].syndrome == 0
assert pkt[AETH].msn == 5
assert pkt.icrc == 0x25f0c038

= RoCE over IPv6

# an example UC packet
pkt = Ether(dst='24:8a:07:a8:fa:22', src='24:8a:07:a8:fa:22')/ \
IPv6(nh=17,src='2022::1023', dst='2023::1024', \
version=6,hlim=255,plen=44,fl=0x1face,tc=226)/ \
UDP(sport=49152, dport=4791, len=44)/ \
BTH(opcode='UC_SEND_ONLY', migreq=1, padcount=2, pkey=0xffff, dqpn=211, psn=13571856)/ \
Raw(b'F0\x81\x8b\xe2\x895\xd9\x0e\x9a\x95PT\x01\xbe\x88^P\x00\x00')

# include ICRC placeholder
pkt = Ether(pkt.build() + b'\x00' * 4)

assert IPv6 in pkt.layers()
assert UDP in pkt.layers()
print(hex(pkt[UDP].chksum))
assert pkt[UDP].chksum == 0xe7c5
assert BTH in pkt.layers()
print(hex(pkt[BTH].icrc))
assert pkt[BTH].icrc == 0x3e5b743b