187 lines
5.3 KiB
Markdown
187 lines
5.3 KiB
Markdown
|
# Trashernet Command Processor
|
||
|
|
||
|
Commands:
|
||
|
|
||
|
* MATCH (length, matches, jump), followed by match-jump-addresses if <jump>, followed by match bytes interleaved: Match incoming data against. Set <length> to zero for unconditional jump. If no match, abort reception.
|
||
|
* FORWARD (length): Output <length> bytes of data on the output port
|
||
|
* IGNORE (length): Ignore <length> bytes
|
||
|
* OUTPUT: Output following byte on the special port
|
||
|
|
||
|
|
||
|
Command format:
|
||
|
|
||
|
2b 4b 3b 1b
|
||
|
[Opcode] [length] [matches] [jump]
|
||
|
|
||
|
|
||
|
|
||
|
Example program:
|
||
|
|
||
|
# MAC frame
|
||
|
MATCH (6, 2, false) AA.BB.CC.DD.EE.FF FF.FF.FF.FF.FF.FF
|
||
|
IGNORE (6)
|
||
|
|
||
|
# Protocol MUX
|
||
|
MATCH (
|
||
|
|
||
|
# IPv4
|
||
|
MATCH (4, 1, false) 192.168.178.1
|
||
|
|
||
|
|
||
|
|
||
|
# IDEA 2
|
||
|
Okay, I need a new idea. The problem with the first is that I almost always need access to parameters from the past. E.g. ARP requires the sender MAC address for the response. In the current design, I would've already discarded that because what do I care about it for a data packet.
|
||
|
|
||
|
So, new approach: A packet is received into a RAM ring buffer, and then the script is started with the CRC OK.
|
||
|
|
||
|
New scripting language:
|
||
|
|
||
|
* SET_CURSOR (position): Set cursor to position in received telegram
|
||
|
* MATCH[!] <address> <pattern>: Jump to address if pattern matches; else continue after pattern and reset cursor to before match (without !), or stop receiving (with !)
|
||
|
* FORWARD <length>
|
||
|
* OUTPUT <byte>
|
||
|
* DIE
|
||
|
|
||
|
COMMAND formatting:
|
||
|
|
||
|
general : [3 bit opcode]
|
||
|
MATCH : [1b deathflag] [4 bit length]
|
||
|
|
||
|
Example program:
|
||
|
|
||
|
MAC_DST: MATCH AA.BB.CC.DD.EE.FF -> ETHERTYPE
|
||
|
MAC_BCAST: MATCH! FF.FF.FF.FF.FF.FF -> ETHERTYPE
|
||
|
ETHERTYPE_ARP: MATCH 08.06 -> ARP
|
||
|
ETHERTYPE_IP: MATCH! 08.00 -> IP
|
||
|
ARP: MATCH! 00.01.08.00.06.04 -> ARP_HDR_OK
|
||
|
ARP_HDR_OK: MATCH 01 -> ARP_REQUEST
|
||
|
MATCH! 02 -> ARP_REPLY
|
||
|
ARP_REQUEST: SET_CURSOR +10
|
||
|
MATCH! AA.BB.CC.DD.EE.FF -> ARP_REQUEST_OK
|
||
|
ARP_REQUEST_OK: OUTPUT 01
|
||
|
SET_CURSOR -16
|
||
|
FORWARD 10
|
||
|
DONE
|
||
|
|
||
|
|
||
|
This program generates an interrupt for
|
||
|
* ARP (01) with 10 user bytes SHA+SPA
|
||
|
|
||
|
|
||
|
## Now, on the sender side.
|
||
|
|
||
|
* TX processor runs on shared memory with receiver, possibly even shared with the receive buffer
|
||
|
So that receiver can write "program memory" of transmitter, this is relevant for example for IP TX, which checks that some memory address is the target TX address.
|
||
|
|
||
|
|
||
|
Idea for an IP TX with ARP.
|
||
|
|
||
|
* Destination IP is written to address in memory
|
||
|
* Start IP TX program
|
||
|
* ARP_CHECK: SET_CURSOR(ARP RX address buffer)
|
||
|
* MATCH <destination address) -> FOUND_IP
|
||
|
* WRITE_MEM <ARP TX address buffer> <destination IP>
|
||
|
* SET_CURSOR(ARP TX address buffer)
|
||
|
* MATCH <destination address> -> ARP_CHECK
|
||
|
* !!! TBD: Assemble and send out ARP request
|
||
|
* JUMP ARP_CHECK
|
||
|
|
||
|
* !!! TBD: Loop until MATCH
|
||
|
* FOUND_IP: Assemble and send out IP frame
|
||
|
|
||
|
ideas for improvement:
|
||
|
* have two cursors for the TX engine
|
||
|
-> basically to select between static data and dynamic
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# Final (TM) Idea
|
||
|
|
||
|
* We build one processor. It handles both TX and RX
|
||
|
* It runs code from a shared memory space with the RX buffer
|
||
|
* It has multiple pointer registers (at least two)
|
||
|
|
||
|
Commands:
|
||
|
|
||
|
* Match <len, abort_flag,poll_flag> -> <dest>: Compare len characters from ptr1 and ptr2, jump to dest if all match, go to next instruction if not; if len=zero, it's an unconditional jump. `poll_flag` keeps looping here until the condition is met. `abort_flag` will abort command execution on mismatch.
|
||
|
* SetPtr <ptr>, <relative/absolute>
|
||
|
* Write <len>: Write <len> data from ptr2 to ptr1
|
||
|
* Output <ptr, len>: Push <len> data from <ptr> to output FIFO
|
||
|
* Input <ptr, len>: Read <len> bytes from input FIFO into <ptr>
|
||
|
* Return: TBD: Single-level return to caller (last match?)
|
||
|
* Jump <ptr1> <ptr2>: Pseudo-command, will translate to other instructions. Set location of ptr1 and ptr2 (opt.), then jump (empty match) to that address.
|
||
|
|
||
|
## Example to send an IP frame
|
||
|
|
||
|
* Write destination IP to <dest-ip>
|
||
|
* Start TX IP program
|
||
|
|
||
|
SendUDP:
|
||
|
|
||
|
CheckARP:
|
||
|
SetPtr ptr1, <arp-rx-ip-buffer>
|
||
|
SetPtr ptr2, <dest-ip>
|
||
|
Match 4 -> FOUND_ARP
|
||
|
NeedARPRequest:
|
||
|
Jump SendMAC, ptr1="FF:FF:FF:FF:FF:FF", ptr2="08:06"
|
||
|
Jump SendARP, ptr1=<dest-ip>
|
||
|
Match 4, poll -> FOUND_ARP
|
||
|
FOUND_ARP:
|
||
|
|
||
|
|
||
|
// ## SendMAC: Send MAC frame. ptr1: Destination MAC, ptr2: Ethertype
|
||
|
SendMAC:
|
||
|
Output ptr1, 6
|
||
|
SetPtr ptr1, <my-mac>
|
||
|
Output ptr1, 6
|
||
|
Output ptr2, 2
|
||
|
Return
|
||
|
|
||
|
SendARPRequest:
|
||
|
Output <ARP-header> // TODO
|
||
|
Output <my-mac> // SHA
|
||
|
Output <my-ip> // SPA
|
||
|
Output FF:FF:FF:FF:FF:FF // THA
|
||
|
Output <dest-ip> // TPA
|
||
|
Return
|
||
|
|
||
|
|
||
|
|
||
|
## Maybe change concept
|
||
|
|
||
|
Idea is: We pretty much have a template for each frame in memory. The program will assemble the data in place, and then TX the entire block
|
||
|
|
||
|
// Variables will be defined in order!
|
||
|
|
||
|
// Ethernet frame
|
||
|
Def ETH-DEST-MAC:6
|
||
|
Def ETH-SOURCE-MAC:6=00:DE:AD:BE:EF:00
|
||
|
Def ETH-ETHERTYPE:2
|
||
|
|
||
|
// ARP frame
|
||
|
Def ARP-HEADER:?=0001:0800:0604:0001
|
||
|
Def ARP-SHA:0=Ð-SOURCE-MAC
|
||
|
Def ARP-SPA:4
|
||
|
Def ARP-THA:6
|
||
|
Def ARP-TPA:4
|
||
|
|
||
|
CheckARP:
|
||
|
SetPtr ptr1, <arp-rx-ip-buffer>
|
||
|
SetPtr ptr2, <dest-ip>
|
||
|
Match 4 -> FOUND_ARP
|
||
|
NeedARPRequest:
|
||
|
// Build Ethernet header
|
||
|
Write Ð-DEST-MAC, "FF:FF:FF:FF:FF:FF"
|
||
|
Write Ð-ETHERTYPE, "0806"
|
||
|
Output Ð-DEST-MAC, 18
|
||
|
// Build ARP header
|
||
|
Write &ARP_TPA, <dest-ip>, 4
|
||
|
Output &ARP-HEADER, 8
|
||
|
Output &ARP_SHA, 6
|
||
|
Output &ARP_SPA, 4
|
||
|
Output &ARP-THA, 10 // +ARP-TPA
|
||
|
// todo: set up match
|
||
|
Match 4, poll -> FOUND_ARP
|
||
|
FOUND_ARP:
|