Wrong checksum calculation for Icmp Extension Header
Brief description
CheckSum for Icmp Extension Header does not involve payload in calculation.
Environment
- Scapy version: scapy 2.4.0
RFC 4884 defines the checksum for Icmp Extension Header " The one's complement of the one's complement sum of the data structure, with the checksum field replaced by zero for the purpose of computing the checksum."
Below attached Wireshark logs also shows the case in which packet's checksum only includes icmp extension header and not the payload ( icmp object header and mpls object in the example case ). Wireshark correctly displays it as wrong checksum in this case. When calculation of checksum involved the payload, wireshark correctly interpreted the checksum.
file : scapy/contrib/icmp_extensions.py
Current Implementation
class ICMPExtensionHeader(Packet):
name = 'ICMP Extension Header (RFC4884)'
fields_desc = [ BitField('version', 2, 4),
BitField('reserved', 0, 12),
BitField('chksum', None, 16) ]
_min_ieo_len = len(ICMPExtensionObject())
def post_build(self, p, pay):
if self.chksum is None:
ck = checksum(p)
p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
return p+pay
After Fixing Checksum Calculation
class ICMPExtensionHeader(Packet):
name = 'ICMP Extension Header (RFC4884)'
fields_desc = [ BitField('version', 2, 4),
BitField('reserved', 0, 12),
BitField('chksum', None, 16) ]
_min_ieo_len = len(ICMPExtensionObject())
def post_build(self, p, pay):
p += pay
if self.chksum is None:
ck = checksum(p)
p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
return p
Expected result
current_impl.pcap Icmp TTL exceeded packet matches with icmp extension header checksum calculation of scapy but fails with wireshark saying incorrect checksum.
expected_impl.pcap Icmp TTL exceeded packet does not match with icmp extension header checksum calculation of scapy and includes the payload in checksum calculation and passes with wireshark.
Could you provide a Scapy example that successfully build a packet with a valid checksum? I having spent a lot of time trying to come up with an unit test but did not manage to do it =/
@malayaz Any word on the crc32 thoughts or?
Could you provide a Scapy example that successfully build a packet with a valid checksum?
@guedou is this what you mean? pkt = ICMPExtensionHeader() / ICMPExtensionMPLS(stack=MPLS(label=0x2714, ttl=1))
A possible unit test of the above implementation (with chb() instead of chr()) could be: assert checksum(raw(ICMPExtensionHeader() / ICMPExtensionMPLS(stack=MPLS(label=0x2714, ttl=1)))) == 0
Or I misunderstood your request.
@mcpat do you know how to build a full valid packet starting with Ether?
This should be fixed in https://github.com/secdev/scapy/pull/4332