From 92e14077297fb28fdb39b18953268a4e61b5444e Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Mon, 1 Jul 2019 09:36:14 +0200 Subject: [PATCH] checksumming part finish --- bin/checksum_delta_diff_test.py | 90 +++++++++++++++++++++++++++++---- doc/plan.org | 33 ++++++++++++ 2 files changed, 112 insertions(+), 11 deletions(-) diff --git a/bin/checksum_delta_diff_test.py b/bin/checksum_delta_diff_test.py index b885889..1e8d4e9 100644 --- a/bin/checksum_delta_diff_test.py +++ b/bin/checksum_delta_diff_test.py @@ -1,7 +1,77 @@ #!/usr/bin/python3 #from __future__ import unicode_literals +import ipaddress from scapy.all import * +import array +import struct + +# stolen from scapy (little endian system) +def checksum_scapy(pkt): + if len(pkt) % 2 == 1: + pkt += b"\0" + s = sum(array.array("H", pkt)) + s = (s >> 16) + (s & 0xffff) + s += s >> 16 + s = ~s + return (((s>>8)&0xff)|s<<8) & 0xffff + + +# 1. convert to array of "bytes" +# 2. import into an array +# 3. sum everything up + + +def sum_for_udp(packet): + sums = "" + sums += struct.pack("H", packet[UDP].sport) + sums += struct.pack("H", packet[UDP].dport) + sums += struct.pack("H", packet[UDP].len) + + return sums + +def sum_for_v6(packet): + # hdr.ipv6.src_addr, /* 128 */ + # hdr.ipv6.dst_addr, /* 128 */ + # meta.length_without_ip_header, /* 32 */ + # 24w0, /* 24 */ + # hdr.ipv6.next_header, /* 8 */ + # /* total: 324 */ + + # // UDP header + # hdr.udp.src_port, /* 16 */ + # hdr.udp.dst_port, /* 16 */ + # hdr.udp.payload_length /* 16 */ + # /* all: 372 */ + + # order does not matter! + sums = "" + + sums += ipaddress.IPv6Address(packet[IPv6].src.decode("utf-8")).packed + sums += ipaddress.IPv6Address(packet[IPv6].dst.decode("utf-8")).packed + sums += struct.pack("H", packet[IPv6].plen) + sums += struct.pack("B", packet[IPv6].nh) + + print("{} - {} - {}".format(len(sums), sums, checksum_scapy(sums))) + + return sums + +def sum_for_v4(packet): + # Get diffs -- for UDP + # udp_v4 = + # hdr.ipv4.src_addr, + # hdr.ipv4.dst_addr, + # 8w0, + # hdr.ipv4.protocol, + # meta.length_without_ip_header, + sums = "" + + sums += ipaddress.IPv4Address(packet[IP].src.decode("utf-8")).packed + sums += ipaddress.IPv4Address(packet[IP].dst.decode("utf-8")).packed + sums += struct.pack("H", packet[IP].len - 20) # -20 for ip header + sums += struct.pack("H", packet[IP].proto) # udp / tcp + + return sums if __name__ == '__main__': p = [] @@ -41,18 +111,16 @@ if __name__ == '__main__': chk_new = packet_rebuild[UDP].chksum print("chk1 = {} chk2={}".format(chk_old, chk_new)) - # Get diffs -- for UDP - # udp_v4 = - # hdr.ipv4.src_addr, - # hdr.ipv4.dst_addr, - # 8w0, - # hdr.ipv4.protocol, - # meta.length_without_ip_header, + sums = "" - # // UDP header - # hdr.udp.src_port, - # hdr.udp.dst_port, - # hdr.udp.payload_length + if IP in packet: + sums += sum_for_v4(packet_rebuild) + if IPv6 in packet: + sums += sum_for_v6(packet_rebuild) +# if UDP in packet: +# sums += sum_for_udp(packet_rebuild) + + print("Checksum-parts {} for {}".format(checksum_scapy(sums), packet_rebuild.__repr__())) # Checksums: diff --git a/doc/plan.org b/doc/plan.org index b1efe5c..fd24e5d 100644 --- a/doc/plan.org +++ b/doc/plan.org @@ -384,6 +384,12 @@ | 2019-06-27 | | | | | Target Hardware: code running | | | | | | +| 2019-07-01 | | | +| | Meeting Laurent | | +| | | | +| | - Diff'ing in python | | +| | - Phasing in netpfga code | | +| | | | | 2019-07-11 | | | | | Integrated org-documentation into latex / export working | | | | https://bastibe.de/2014-09-23-org-cite.html | | @@ -4893,6 +4899,33 @@ actual (tlast, tkeep, tdata) = (0, ffffffff, 000000000000000080fe403b0a0000000 *** 2019-06-24: find out how the expected/actual packet lines are generated - afair: indirectly by running gen_testdata.py -> replace script with port1 +*** 2019-07-01: verify checksumming +#+BEGIN_CENTER +if struct.pack("H",1) == b"\x00\x01": # big endian + def checksum(pkt): + if len(pkt) % 2 == 1: + pkt += b"\0" + s = sum(array.array("H", pkt)) + s = (s >> 16) + (s & 0xffff) + s += s >> 16 + s = ~s + return s & 0xffff +else: + def checksum(pkt): + if len(pkt) % 2 == 1: + pkt += b"\0" + s = sum(array.array("H", pkt)) + s = (s >> 16) + (s & 0xffff) + s += s >> 16 + s = ~s + return (((s>>8)&0xff)|s<<8) & 0xffff + +#+END_CENTER +*** 2019-07-01: 128 bit ipv6 struct -> no conversion! + - https://docs.python.org/2.7/library/struct.html + - .packed of ipaddress works +*** 2019-07-01: finish sum, use scapy checksum +*** 2019-07-01: meeting Laurent ** References / Follow up *** RFC 791 IPv4 https://tools.ietf.org/html/rfc791 *** RFC 792 ICMP https://tools.ietf.org/html/rfc792