From 408dd6b782818af7644dfa7a034f982f5f548925 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Sun, 23 Jun 2019 14:19:06 +0200 Subject: [PATCH] Delta checksum approach --- bin/checksum_from_scapy.py | 44 ++++++++++++++++++++++ doc/plan.org | 75 +++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/bin/checksum_from_scapy.py b/bin/checksum_from_scapy.py index 90930ec..7638d3b 100644 --- a/bin/checksum_from_scapy.py +++ b/bin/checksum_from_scapy.py @@ -2,6 +2,8 @@ # Code copied from /usr/lib/python3/dist-packages/scapy/utils.py +import struct +import array if struct.pack("H",1) == b"\x00\x01": # big endian def checksum(pkt): @@ -14,10 +16,52 @@ if struct.pack("H",1) == b"\x00\x01": # big endian return s & 0xffff else: def checksum(pkt): + # padding to even length if len(pkt) % 2 == 1: pkt += b"\0" + + # create array with unsigned shorts, + # sum it up -> results in 16 bit uint (?) s = sum(array.array("H", pkt)) + + # (s & 0xffff) -> mask for 16 bit, truncate rest + # (s >> 16) right shift by 16 bits + # >>> 2**17 >> 16 + # 2 + # Basically: + # add higher 16 bits to lower 16 bits + s = (s >> 16) + (s & 0xffff) + + # Now we add the remaining possible 16 bits + # i.e. above we take bits 0..15 + 16..31 + # now we add [0..15 + 16..31] + "32..47" + # I assume this is for catching the carry + # over bits from the previous calculation s += s >> 16 + + + # according to https://stackoverflow.com/questions/8305199/the-tilde-operator-in-python + # ~ is the bitwise complement operator in python + # which essentially calculates -x - 1 + + # 2 complement s = ~s + + # (s>>8)&0xff) -> filter bits 8..15 + # | = bitwise OR + # s<<8 : left shift everything in original s + # | s<<8: ? + # & 0xffff: filter / allow only 16 bits + # Seems like the idea is to filter correctly for + # 16 bit - unclear why "s & 0xffff" does not do the job + return (((s>>8)&0xff)|s<<8) & 0xffff + + +if __name__ == '__main__': + import sys + pkt = sys.argv[1] + pkt_bytes = pkt.encode('utf-8') + print(pkt_bytes) + print(checksum(pkt_bytes)) diff --git a/doc/plan.org b/doc/plan.org index 4a93546..9e0255e 100644 --- a/doc/plan.org +++ b/doc/plan.org @@ -2946,6 +2946,62 @@ SimpleSumeSwitch( TopDeparser() ) main; **** Understand the different switch models (?) +*** TODO Find out whether delta based checksumming is feasible [in P4] +**** DONE Analysing scapy + CLOSED: [2019-06-23 Sun 14:18] +#+BEGIN_CENTER +[13:51] line:~% dpkg -L python3-scapy | grep inet +/usr/lib/python3/dist-packages/scapy/layers/inet.py +/usr/lib/python3/dist-packages/scapy/layers/inet6.py + + if self.chksum is None: + ck = checksum(p) + p = p[:10]+chb(ck>>8)+chb(ck&0xff)+p[12:] + return p+pay + +[13:55] line:~% grep checksum -r /usr/lib/python3/dist-packages/scapy/ | grep def +/usr/lib/python3/dist-packages/scapy/contrib/isis.py: def checksum_info(self, hdrlen): +/usr/lib/python3/dist-packages/scapy/contrib/isis.py: def checksum_info(self, hdrlen): +/usr/lib/python3/dist-packages/scapy/contrib/ospf.py:def ospf_lsa_checksum(lsa): +/usr/lib/python3/dist-packages/scapy/utils.py: def checksum(pkt): +/usr/lib/python3/dist-packages/scapy/utils.py: def checksum(pkt): +/usr/lib/python3/dist-packages/scapy/utils.py:def fletcher16_checksum(binbuf): +/usr/lib/python3/dist-packages/scapy/layers/sctp.py:def sctp_checksum(buf): +[13:55] line:~% + + + +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 +**** TODO Trying to create a delta diff: AAAA vs. BBAA +#+BEGIN_CENTER +[14:17] line:bin% python3 checksum_from_scapy.py AAAA +b'AAAA' +32125 +[14:18] line:bin% python3 checksum_from_scapy.py BBAA +b'BBAA' +31868 + +#+END_CENTER *** TODO Get ANY p4 program to successfully run on netpfga **** TODO mirroring ethernet ***** no packets seen on source interface @@ -3061,6 +3117,9 @@ ERROR: failed to convert p.ethernet.dstAddr of type to an integer ** Additional features queue (to be discussed) *** TODO Offset based translation (v4->v6) -> same as range (?) *** TODO IP address learning (v6/v4) for real life switch? How do hosts find it? +** Netpfga cabling +| eth2 <--> nf0 | +| eth1 <--> nf3 | * Thesis documentation ** Introduction *** Related work @@ -4685,9 +4744,21 @@ SerialException: device reports readiness to read but returned no data (device d "The checksum field is the 16 bit one's complement of the one's complement sum of all 16-bit words in the header and text." https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation +*** 2019-06-21: create table entries on new card +#+BEGIN_CENTER +>> table_cam_add_entry lookup_table send_to_port1 ff:ff:ff:ff:ff:ff => +CAM_Init_ValidateContext() - done +WROTE 0x44020050 = 0xffffffff +WROTE 0x44020054 = 0xffff +WROTE 0x44020080 = 0x0003 +READ 0x44020044 = 0x0001 +WROTE 0x44020040 = 0x0001 +READ 0x44020044 = 0x0001 +READ 0x44020044 = 0x0001 +success +>> - - +#+END_CENTER ** References / Follow up *** RFC 791 IPv4 https://tools.ietf.org/html/rfc791 *** RFC 792 ICMP https://tools.ietf.org/html/rfc792