From a76977af62010a392c16010c367185e61e856ffe Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 30 Oct 2019 20:04:56 +0100 Subject: mv to docs --- docs/j1demo/firmware/arp.fs | 225 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 docs/j1demo/firmware/arp.fs (limited to 'docs/j1demo/firmware/arp.fs') diff --git a/docs/j1demo/firmware/arp.fs b/docs/j1demo/firmware/arp.fs new file mode 100644 index 0000000..c6b69c7 --- /dev/null +++ b/docs/j1demo/firmware/arp.fs @@ -0,0 +1,225 @@ +( ARP: Address Resolution Protocol JCB 13:12 08/24/10) +module[ arp" + +\ ARP uses a small cache of entries. Each entry has an age counter; new +\ entries have an age of 0, any entry with an age >N is old. +\ + + +d# 12 constant arp-cache-entry-size +d# 5 constant arp-cache-entries +TARGET? [IF] + meta + arp-cache-entry-size arp-cache-entries * d# 64 max + target + constant arp-size + create arp-cache arp-size allot + meta + arp-cache-entries 1- arp-cache-entry-size * arp-cache + + target + constant arp-cache-last +[ELSE] + arp-cache-entry-size arp-cache-entries * d# 64 max constant arp-size + create arp-cache arp-size allot + arp-cache-entries 1- arp-cache-entry-size * arp-cache + constant arp-cache-last +[THEN] + +: arp-foreach \ (func -- ) + arp-cache-last 2>r + begin + 2r@ swap \ ptr func + execute + r> dup arp-cache-entry-size - >r + arp-cache = + until + 2r> 2drop +; + +build-debug? [IF] +: arp-. + dup @ hex4 space \ age + dup 2+ dup @ swap d# 2 + dup @ swap d# 2 + @ ethaddr-pretty space + d# 8 + 2@ ip-pretty + cr +; + +: arp-dump + ['] arp-. arp-foreach +; +[THEN] + +: arp-del h# ff swap ! ; +: arp-reset ['] arp-del arp-foreach ; +: used? @ h# ff <> ; +: arp-age-1 dup used? d# 1 and swap +! ; +: arp-age ['] arp-age-1 arp-foreach ; +: arp-cmp ( ptr0 ptr1 -- ptr) over @ over @ > ?: ; +: arp-oldest \ return the address of the oldest ARP entry + arp-cache ['] arp-cmp arp-foreach ; + +\ ARP offsets +\ d# 28 sender ethaddr +\ d# 34 sender ip +\ d# 38 target ethaddr +\ d# 44 target ip + +d# 20 constant OFFSET_ARP_OPCODE +d# 22 constant OFFSET_ARP_SRC_ETH +d# 28 constant OFFSET_ARP_SRC_IP +d# 32 constant OFFSET_ARP_DST_ETH +d# 38 constant OFFSET_ARP_DST_IP + +: arp-is-response + OFFSET_ETH_TYPE packet@ h# 806 = + OFFSET_ARP_OPCODE packet@ d# 2 = + and +; + +\ write the current arp response into the cache, replacing the oldest entry +: !-- \ ( val ptr -- ptr-2 ) + tuck \ ptr val ptr + ! + 2- +; + +\ Current packet is an ARP response; write it to the given slot in the ARP cache, ageing all others + +: arp-cache-write \ ( ptr -- ) + arp-age \ because this new entry will have age d# 0 + d# 0 over ! \ age d# 0 + >r + + d# 3 OFFSET_ARP_SRC_ETH mac-inoffset mac@n + r@ d# 6 + !-- !-- !-- drop + d# 2 OFFSET_ARP_SRC_IP mac-inoffset mac@n + r> d# 8 + 2! + +; + +\ Comparison of IP +: arp-cmpip \ (ip01 ip23 ptr/0 ptr -- ip01 ip23 ptr) + dup used? if + dup d# 8 + 2@ d# 2 2pick d<> ?: + else + drop + then +; + +: arp-cache-find ( ip01 ip23 -- ip01 ip23 ptr ) +\ Find an IP. Zero if the IP was not found in the cache, ptr to entry otherwise + d# 0 ['] arp-cmpip arp-foreach ; + + +: arp-issue-whohas \ (ip01 ip23 -- ptr) + mac-pkt-begin + ethaddr-broadcast mac-pkt-3, + net-my-mac mac-pkt-3, + h# 806 \ frame type + d# 1 \ hard type + h# 800 \ prot type + mac-pkt-3, + h# 0604 \ hard size, prot size + d# 1 \ op (1=request) + mac-pkt-2, + net-my-mac mac-pkt-3, + net-my-ip mac-pkt-2, + ethaddr-broadcast mac-pkt-3, + mac-pkt-2, + mac-pkt-complete drop + mac-send +; + +\ Look up ethaddr for given IP. +\ If found, return pointer to the 6-byte ethaddr +\ If not found, issue an ARP request and return d# 0. + +: arp-lookup \ ( ip01 ip23 -- ptr) + 2dup + ip-router 2@ dxor ip-subnetmask 2@ dand + d0<> + if + 2drop + ip-router 2@ + then + arp-cache-find \ ip01 ip23 ptr + dup 0= if + -rot \ d# 0 ip01 ip23 + arp-issue-whohas \ d# 0 + else + nip nip 2+ \ ptr + then +; + +\ If the current packet is an ARP request for our IP, answer it +: arp-responder + \ is destination ff:ff:ff:ff:ff:ff or my mac + d# 3 OFFSET_ETH_DST mac-inoffset mac@n + and and invert 0= + + net-my-mac \ a b c + d# 2 OFFSET_ETH_DST 2+ mac-inoffset mac@n + d= swap \ F a + OFFSET_ETH_DST packet@ = and + + or + OFFSET_ETH_TYPE packet@ h# 806 = and + \ is target IP mine? + d# 2 OFFSET_ARP_DST_IP mac-inoffset mac@n net-my-ip d= and + if + mac-pkt-begin + + d# 3 OFFSET_ARP_SRC_ETH mac-pkt-src + net-my-mac mac-pkt-3, + h# 806 \ frame type + d# 1 \ hard type + h# 800 \ prot type + mac-pkt-3, + h# 0604 \ hard size, prot size + d# 2 \ op (2=reply) + mac-pkt-2, + net-my-mac mac-pkt-3, + net-my-ip mac-pkt-2, + d# 3 OFFSET_ARP_SRC_ETH mac-pkt-src + d# 2 OFFSET_ARP_SRC_IP mac-pkt-src + + mac-pkt-complete drop + mac-send + then +; + +: arp-announce + mac-pkt-begin + + ethaddr-broadcast mac-pkt-3, + net-my-mac mac-pkt-3, + h# 806 \ frame type + d# 1 \ hard type + h# 800 \ prot type + mac-pkt-3, + h# 0604 \ hard size, prot size + d# 2 \ op (2=reply) + mac-pkt-2, + net-my-mac mac-pkt-3, + net-my-ip mac-pkt-2, + ethaddr-broadcast mac-pkt-3, + net-my-ip mac-pkt-2, + + mac-pkt-complete drop + mac-send + +; + +: arp-handler + arp-responder + arp-is-response + if + d# 2 OFFSET_ARP_SRC_IP mac-inoffset mac@n + arp-cache-find nip nip + dup 0= if + drop arp-oldest + then + arp-cache-write + then +; + +]module -- cgit v1.2.3