model: add real dumps and test models with it
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 29 Jan 2015 23:02:11 +0000 (00:02 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 29 Jan 2015 23:02:11 +0000 (00:02 +0100)
liteeth/test/Makefile
liteeth/test/common.py
liteeth/test/model/arp.py
liteeth/test/model/dumps.py [new file with mode: 0644]
liteeth/test/model/mac.py

index 974f1e570032e96ce0f7fa690d62a901cbbfafa4..7d2283c85059be2957ff7c514c372909ded09e3d 100644 (file)
@@ -3,6 +3,10 @@ PYTHON = python3
 
 CMD = PYTHONPATH=$(LEDIR) $(PYTHON)
 
+model_tb:
+       $(CMD) ./model/mac.py
+       $(CMD) ./model/arp.py
+
 mac_core_tb:
        $(CMD) mac_core_tb.py
 
index 684be80aae2693a82467b79e806752b22d9a1b81..496df5d8b3bb6212d6e7c52933f29992788d78ae 100644 (file)
@@ -19,15 +19,15 @@ def seed_to_data(seed, random=True):
        else:
                return seed
 
-def split_bytes(v, n):
+def split_bytes(v, n, endianness="big"):
        r = []
-       r_bytes = v.to_bytes(n, byteorder="little")
+       r_bytes = v.to_bytes(n, byteorder=endianness)
        for byte in r_bytes:
                r.append(int(byte))
        return r
 
-def merge_bytes(b):
-       return int.from_bytes(bytes(b), "little")
+def merge_bytes(b, endianness="big"):
+       return int.from_bytes(bytes(b), endianness)
 
 def get_field_data(field, datas):
        v = merge_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)])
index e0a80f2c6a153cebbd3788f6f9af3e0b8dd2da1c..ef4c27618de2c22e17706a4aad8f560da43ced86 100644 (file)
@@ -3,7 +3,6 @@ import math, binascii
 from liteeth.common import *
 from liteeth.mac.common import *
 from liteeth.test.common import *
-from liteeth.test.mac import *
 
 def print_arp(s):
        print_with_prefix(s, "[ARP]")
@@ -25,8 +24,9 @@ class ARPPacket(Packet):
        def encode(self):
                header = 0
                for k, v in sorted(arp_header.items()):
-                       header |= (getattr(self, k) << (v.byte*8+v.offset))
-               for d in reversed(split_bytes(header, arp_header_len)):
+                       value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little")
+                       header += (value << v.offset+(v.byte*8))
+               for d in split_bytes(header, arp_header_len):
                        self.insert(0, d)
 
        def __repr__(self):
@@ -84,7 +84,7 @@ class ARP(Module):
                        self.process_reply(packet)
        
        def process_request(self, request):
-               if request.destination_ip_address = self.ip_address:
+               if request.destination_ip_address == self.ip_address:
                        reply = ARPPacket([0]*(arp_packet_length-arp_header_length))
                        reply.hardware_type = arp_hwtype_ethernet
                        reply.protocol_type = arp_proto_ip
@@ -109,3 +109,37 @@ class ARP(Module):
                request.source_ip_address = self.ip_address
                request.destination_mac_address = 0xffffffffffff
                request.destination_ip_address = ip_address
+
+if __name__ == "__main__":
+       from liteeth.test.model.dumps import *
+       from liteeth.test.model.mac import *
+       errors = 0
+       # ARP request
+       packet = MACPacket(arp_request)
+       packet.decode_remove_header()
+       packet = ARPPacket(packet)
+       # check decoding
+       packet.decode()
+       #print(packet)
+       errors += verify_packet(packet, arp_request_infos)
+       # check encoding
+       packet.encode()
+       packet.decode()
+       #print(packet)
+       errors += verify_packet(packet, arp_request_infos)
+
+       # ARP Reply
+       packet = MACPacket(arp_reply)
+       packet.decode_remove_header()
+       packet = ARPPacket(packet)
+       # check decoding
+       packet.decode()
+       #print(packet)
+       errors += verify_packet(packet, arp_reply_infos)
+       # check encoding
+       packet.encode()
+       packet.decode()
+       #print(packet)
+       errors += verify_packet(packet, arp_reply_infos)
+
+       print("arp errors " + str(errors))
\ No newline at end of file
diff --git a/liteeth/test/model/dumps.py b/liteeth/test/model/dumps.py
new file mode 100644 (file)
index 0000000..64684f5
--- /dev/null
@@ -0,0 +1,76 @@
+import re
+
+def format_dump(dump):
+       return [int(s, 16) for s in re.split(r'[;,\s\n]\s*', dump) if s is not ""]
+
+def verify_packet(packet, infos):
+       errors = 0
+       for k, v in infos.items():
+               if hasattr(packet, k):
+                       if getattr(packet, k) != v:
+                               print("[Error] " + k)
+                               errors += 1
+       return errors
+
+arp_request = format_dump("""
+00 22 19 22 54 9e 00 12 3f 97 92 01 08 06 00 01
+08 00 06 04 00 01 00 12 3f 97 92 01 a9 fe ff 42
+00 22 19 22 54 9e a9 fe 64 62""")
+
+arp_request_infos = {
+       "source_mac_address"            :       0x00123f979201,
+       "destination_mac_address"       :       0x00221922549e,
+       "ethernet_type"                         :       0x806,
+       "hardware_type"                         :       0x1,
+       "operation"                                     :       0x1,
+       "protocol_address_length"       :       0x4,
+       "protocol_type"                         :       0x800,
+       "source_ip_address"                     :       0xa9feff42,
+       "destination_ip_address"        :       0xa9fe6462
+
+}
+
+arp_reply = format_dump("""
+00 12 3f 97 92 01 00 22 19 22 54 9e 08 06 00 01
+08 00 06 04 00 02 00 22 19 22 54 9e a9 fe 64 62
+00 12 3f 97 92 01 a9 fe ff 42 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00""")
+
+arp_reply_infos = {
+       "source_mac_address"            :       0x00221922549e,
+       "destination_mac_address"       :       0x00123f979201,
+       "ethernet_type"                         :       0x806,
+       "hardware_type"                         :       0x1,
+       "operation"                                     :       0x2,
+       "protocol_address_length"       :       0x4,
+       "protocol_type"                         :       0x800,
+       "source_ip_address"                     :       0xa9fe6462,
+       "destination_ip_address"        :       0xa9feff42
+}
+
+ping_request = format_dump("""
+ff 03 00 21 45 00 00 64 00 00 00 00 ff 01 a7 96
+0a 00 00 01 0a 00 00 02 08 00 d6 7f 00 00 00 00
+00 00 00 00 00 02 a7 c8 ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd""")
+
+icmp_echo = format_dump("""
+ff 03 00 21 45 00 00 64 00 00 00 00 ff 01 a7 96
+0a 00 00 02 0a 00 00 01 00 00 de 7f 00 00 00 00
+00 00 00 00 00 02 a7 c8 ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd
+ab cd ab cd ab cd ab cd""")
+
+udp = format_dump("""
+d0 7a b5 96 cd 0a 00 14 0b 33 33 27 08 00 45 00
+00 5f 31 16 00 00 80 11 87 77 c0 a8 01 65 b2 7b
+0d 78 a6 3f 69 0f 00 4b 6a 54 64 31 3a 61 64 32
+3a 69 64 32 30 3a 5a fa 29 99 3a 5e ce 19 d1 8b
+aa 9b 4e 4d f9 2e 51 52 fe ff 65 31 3a 71 34 3a
+70 69 6e 67 31 3a 74 34 3a 85 72 00 00 31 3a 76
+34 3a 55 54 7e 62 31 3a 79 31 3a 71 65""")
index 7af991be827fb9535d103139ffb73b440693795b..26e4a13ca1d8ed34614c18429633622ec7a8b8c3 100644 (file)
@@ -7,11 +7,11 @@ from liteeth.test.common import *
 def print_mac(s):
        print_with_prefix(s, "[MAC]")
 
-preamble = split_bytes(eth_preamble, 8)
+preamble = split_bytes(eth_preamble, 8, "little")
 
 def crc32(l):
        crc = []
-       crc_bytes = split_bytes(binascii.crc32(bytes(l)), 4)
+       crc_bytes = split_bytes(binascii.crc32(bytes(l)), 4, "little")
        for byte in crc_bytes:
                crc.append(int(byte))
        return crc
@@ -57,8 +57,9 @@ class MACPacket(Packet):
        def encode_header(self):
                header = 0
                for k, v in sorted(mac_header.items()):
-                       header |= (getattr(self, k) << (v.byte*8+v.offset))
-               for d in reversed(split_bytes(header, mac_header_len)):
+                       value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little")
+                       header += (value << v.offset+(v.byte*8))
+               for d in split_bytes(header, mac_header_len):
                        self.insert(0, d)
 
        def insert_crc(self):
@@ -135,3 +136,26 @@ class MAC(Module):
                        if len(self.tx_packets) != 0:
                                tx_packet = self.tx_packets.pop(0)
                                yield from self.phy.send(tx_packet)
+
+if __name__ == "__main__":
+       from liteeth.test.model.dumps import *
+       errors = 0
+       packet = MACPacket(arp_request)
+       packet.decode_remove_header()
+       #print(packet)
+       errors += verify_packet(packet, arp_request_infos)
+       packet.encode_header()
+       packet.decode_remove_header()
+       #print(packet)
+       errors += verify_packet(packet, arp_request_infos)
+
+       #print(packet)
+       packet = MACPacket(arp_reply)
+       packet.decode_remove_header()
+       errors += verify_packet(packet, arp_reply_infos)
+       packet.encode_header()
+       packet.decode_remove_header()
+       #print(packet)
+       errors += verify_packet(packet, arp_reply_infos)
+
+       print("mac errors " + str(errors))