Delta checksum approach

This commit is contained in:
Nico Schottelius 2019-06-23 14:19:06 +02:00
parent e7769abe31
commit 408dd6b782
2 changed files with 117 additions and 2 deletions

View File

@ -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))

View File

@ -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 <type 'str'> 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