Author: lwalter
Date: 2007-08-09 23:42:49 +0200 (Thu, 09 Aug 2007)
New Revision: 531
Modified:
ofw/inetv6/attr-ipv6.fth
ofw/inetv6/ethernet.fth
ofw/inetv6/icmpinfo.fth
ofw/inetv6/icmpv6.fth
ofw/inetv6/ipfrv6.fth
ofw/inetv6/ippkg.fth
ofw/inetv6/ipv6.fth
ofw/inetv6/neighdis.fth
ofw/inetv6/supportv6.fth
ofw/inetv6/tcpv6.fth
Log:
DAD, Router Discovery, route global IPv6 packets via router discovered
Modified: ofw/inetv6/attr-ipv6.fth
===================================================================
--- ofw/inetv6/attr-ipv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/attr-ipv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -23,10 +23,11 @@
: (setup-ipv6-attr) ( -- ) \ set tftp ip addresses
(setup-ip-attr)
- my-ipv6-addr /ipv6 " client-ipv6" set-chosen-property
- his-ipv6-addr /ipv6 " server-ipv6" set-chosen-property
- router-ipv6-addr /ipv6 " gateway-ipv6" set-chosen-property
- my-mc-ipv6-addr /ipv6 " multicast-ipv6" set-chosen-property
+ my-prefix /ipv6 " ipv6-prefix" set-chosen-property
+ my-ipv6-addr-link-local /ipv6 " client-ipv6-local" set-chosen-property
+ my-ipv6-addr-global /ipv6 " client-ipv6-global" set-chosen-property
+ his-ipv6-addr /ipv6 " server-ipv6" set-chosen-property
+ router-ipv6-addr /ipv6 " gateway-ipv6" set-chosen-property
;
['] (setup-ipv6-attr) is setup-ip-attr
Modified: ofw/inetv6/ethernet.fth
===================================================================
--- ofw/inetv6/ethernet.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/ethernet.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -39,13 +39,19 @@
/e buffer: my-en-addr
/e buffer: his-en-addr
+/e buffer: routerv6-en-addr
+/e buffer: mc-en-addr
: .my-link-addr ( -- ) ." My MAC: " my-en-addr .enaddr ;
: .his-link-addr ( -- ) ." His MAC: " his-en-addr .enaddr ;
+: .routerv6-en-addr ( -- ) ." IPv6 router MAC: " routerv6-en-addr .enaddr ;
-create multicast-en-addr h# 33 c, 33 c, h# ff c, 0 c, 0 c, 0 c,
-create broadcast-en-addr h# ff c, ff c, h# ff c, h# ff c, h# ff c, h# ff c,
+create mc-en-addr-all-nodes h# 33 c, h# 33 c, h# 00 c, 0 c, 0 c, 1 c,
+create multicast-en-addr h# 33 c, h# 33 c, h# ff c, 0 c, 0 c, 0 c,
+create broadcast-en-addr h# ff c, h# ff c, h# ff c, h# ff c, h# ff c, h# ff c,
+: unknown-en-addr? ( 'en -- flag ) dup l@ 0= swap w@ 0= and ;
+
decimal
struct ( ether-header )
@@ -54,14 +60,22 @@
2 sfield en-type
constant /ether-header
+: (set-mc-hash) ( 'mc-en-adr -- err? )
+ /e " $crc" evaluate invert
+ " set-hash" ['] $call-parent catch if 3drop true else false then
+;
+
: set-mc-hash ( -- err? )
- my-ipv6-addr /ipv6 + 3 - multicast-en-addr 3 + 3 move
+ \ XXX Make buffer of all multicast addresses for "set-multicast"
+ my-en-addr 3 + multicast-en-addr 3 + 3 move
multicast-en-addr /e " set-multicast" ['] $call-parent catch 0= if false exit then
4drop
- multicast-en-addr /e " $crc" evaluate invert
- " set-hash" ['] $call-parent catch if 3drop true else false then
+ multicast-en-addr (set-mc-hash)
+ mc-en-addr-all-nodes (set-mc-hash) or
;
+: multicast-en-addr? ( adr -- flag ) w@ h# 3333 = ;
+
: select-ethernet-header ( -- ) packet-buffer set-struct ;
: max-link-payload ( -- n ) link-mtu /ether-header - ;
Modified: ofw/inetv6/icmpinfo.fth
===================================================================
--- ofw/inetv6/icmpinfo.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/icmpinfo.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -11,32 +11,46 @@
: handle-router-sol ( adr len -- ) 2drop ; \ Router solicitation
: handle-router-ad ( adr len -- ) 2drop ; \ Router advertisement
+: send-router-sol ( -- )
+ 8 allocate-icmpv6 set-struct \ Option: source link-layer addr
+ d# 133 icmp-type xc!
+ 0 icmp-code xc!
+ 0 icmp-flags xl!
+ h# 101 icmp-data xw! \ Option type 1 (source mac addr)
+ my-en-addr icmp-data 2 + copy-en-addr
+
+ hop-limit >r h# ff to hop-limit
+ the-struct 8 2dup send-icmpv6-packet
+ free-icmpv6
+ r> to hop-limit
+;
+
: handle-mc-router-ad ( adr len -- ) 2drop ; \ Multicast router advertisement
: handle-mc-router-sol ( adr len -- ) 2drop ; \ Multicast router solicitation
: handle-mc-router-term ( adr len -- ) 2drop ; \ Multicast router termination
-: send-neigh-sol ( -- )
+: send-neigh-sol ( 'ipv6 -- )
d# 24 allocate-icmpv6 set-struct \ Dest IPv6 + one option
d# 135 icmp-type xc!
0 icmp-code xc!
0 icmp-flags xl!
- his-ipv6-addr icmp-data copy-ipv6-addr
+ ( 'ipv6 ) icmp-data copy-ipv6-addr
h# 101 icmp-data /ipv6 + xw! \ Option type 1 (source mac addr)
\ Length (in 8 octels)
- my-en-addr icmp-data /ipv6 + 2 + copy-ipv6-addr
+ my-en-addr icmp-data /ipv6 + 2 + copy-en-addr
hop-limit >r h# ff to hop-limit \ Save and change hop-limit
- the-struct d# 24 2dup send-mc-icmpv6-packet
+ the-struct d# 24 2dup send-icmpv6-packet
free-icmpv6
r> to hop-limit \ Restore hop-limit
;
-: send-neigh-ad ( solicited? -- )
+: send-neigh-ad ( 'ip solicited? -- )
d# 24 allocate-icmpv6 set-struct \ Dest IPv6 + one option
d# 136 icmp-type xc!
0 icmp-code xc!
h# 40 and h# 20 or icmp-flags xl! \ Flags = (un)solicited, override
- my-ipv6-addr icmp-data copy-ipv6-addr
+ ( 'ip ) icmp-data copy-ipv6-addr
h# 201 icmp-data /ipv6 + xw! \ Option type 2 (target mac addr)
\ Length (in 8 octels)
my-en-addr icmp-data /ipv6 + 2 + copy-ipv6-addr
@@ -47,16 +61,31 @@
r> to hop-limit \ Restore hop-limit
;
+/ipv6 buffer: his-ipv6-addr-save
+/ipv6 buffer: my-ipv6-addr-save
: handle-neigh-sol ( adr len -- ) \ Neighbor solicitation
\ XXX Verify hop limit is 255.
dup d# 24 < if 2drop exit then
bootnet-debug if
." Neighbor solicitation from MAC: " over d# 26 + .enaddr cr
then
- over /icmp-header + my-ipv6-addr ipv6= not if ." Not for me" cr 2drop exit then
- 2drop
+ over /icmp-header + my-ipv6-addr ipv6= not if
+ bootnet-debug if ." Not for me" cr then
+ 2drop exit
+ then
+
\ XXX Send Neighbor Advertisement
- true send-neigh-ad
+ drop ( adr )
+ his-ipv6-addr his-ipv6-addr-save copy-ipv6-addr \ Save his-ipv6-addr
+ my-ipv6-addr my-ipv6-addr-save copy-ipv6-addr
+ ipv6-dest-addr c@ dup h# ff = swap h# fe = or if
+ my-ipv6-addr-link-local else my-ipv6-addr-global
+ then
+ my-ipv6-addr copy-ipv6-addr
+ ipv6-source-addr his-ipv6-addr copy-ipv6-addr \ Use the solicitor's IPv6 addr as dst
+ /icmp-header + true send-neigh-ad
+ his-ipv6-addr-save his-ipv6-addr copy-ipv6-addr \ Restore his-ipv6-addr
+ my-ipv6-addr-save my-ipv6-addr copy-ipv6-addr
;
: handle-neigh-ad ( adr len -- ) 2drop ; \ Neighbor advertisement
Modified: ofw/inetv6/icmpv6.fth
===================================================================
--- ofw/inetv6/icmpv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/icmpv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -50,7 +50,7 @@
/ipv6 buffer: his-ipv6-temp
: send-mc-icmpv6-packet ( adr len -- ) \ Send to his multicast IPv6 address
his-ipv6-addr his-ipv6-temp copy-ipv6-addr
- his-mc-ipv6-addr his-ipv6-addr copy-ipv6-addr
+ his-ipv6-addr-mc-sol-node his-ipv6-addr copy-ipv6-addr
send-icmpv6-packet
his-ipv6-temp his-ipv6-addr copy-ipv6-addr
;
Modified: ofw/inetv6/ipfrv6.fth
===================================================================
--- ofw/inetv6/ipfrv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/ipfrv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -3,32 +3,6 @@
headerless
-d# 0 constant IP_HDR_HOP \ Hop-by-hop option
-d# 1 constant IP_HDR_ICMPV4 \ Internet control message protocol - IPv4
-d# 2 constant IP_HDR_IGMPV4 \ Internet group management protocol - IPv4
-d# 4 constant IP_HDR_IPV4
-d# 6 constant IP_HDR_TCP
-d# 8 constant IP_HDR_EGP \ Exterior gateway protocol
-d# 9 constant IP_HDR_IGP \ Cisco private interior gateway
-d# 17 constant IP_HDR_UDP
-d# 41 constant IP_HDR_IPV6
-d# 43 constant IP_HDR_ROUTING \ Routing header
-d# 44 constant IP_HDR_FRAGMENT
-d# 45 constant IP_HDR_IDRP \ Interdomain routing protocol
-d# 46 constant IP_HDR_RSVP \ Resource reservation protocol
-d# 47 constant IP_HDR_GRE \ General routing encapsulation
-d# 50 constant IP_HDR_SECURE \ Encrypted security payload
-d# 51 constant IP_HDR_AUTHEN \ Authentication
-d# 58 constant IP_HDR_ICMPV6
-d# 59 constant IP_HDR_NONE \ No next header
-d# 60 constant IP_HDR_DEST \ Destination options
-d# 88 constant IP_HDR_EIGRP
-d# 89 constant IP_HDR_OSPF
-d# 108 constant IP_HDR_COMP \ IP payload compression protocol
-d# 115 constant IP_HDR_L2TP \ Layer 2 tunneling protocol
-d# 132 constant IP_HDR_SCTP \ Stream control transmission protocol
-d# 135 constant IP_HDR_MOBILITY \ Mobile IPV6
-
struct ( ipv6-frag-header )
1 sfield ipv6-fh-next-hdr
1 sfield ipv6-fh-len
@@ -48,7 +22,7 @@
constant /ipv6-frag-hdr
instance variable frag-id
-0 instance value hop-limit
+h# 40 instance value hop-limit
headers
@@ -75,7 +49,8 @@
h# 6000.0000 ipv6-version xl! \ version 6
( protocol ) ipv6-next-hdr xc! ( len )
( len ) dup ipv6-length xw! ( len )
- hop-limit ipv6-hop-limit xc! ( len )
+ his-ipv6-addr ipv6-addr-local? if hop-limit else router-hop-limit then
+ ( hop-limit ) ipv6-hop-limit xc! ( len )
my-ipv6-addr ipv6-source-addr copy-ipv6-addr ( len )
his-ipv6-addr ipv6-dest-addr copy-ipv6-addr ( len )
/ipv6-header + ( ip-len )
Modified: ofw/inetv6/ippkg.fth
===================================================================
--- ofw/inetv6/ippkg.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/ippkg.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -72,7 +72,7 @@
call-tftp: set-dest-ipv6 ( 'ip -- )
call-tftp: max-ipv6-payload ( -- n )
call-tftp: prefix-match? ( 'ip1 'ip2 -- flag )
-call-tftp: his-mc-ipv6-addr? ( 'ip -- flag )
+call-tftp: his-ipv6-addr-mc? ( 'ip -- flag )
[then]
call-tftp: set-timeout ( #milliseconds -- )
Modified: ofw/inetv6/ipv6.fth
===================================================================
--- ofw/inetv6/ipv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/ipv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -4,6 +4,14 @@
\ Internet protocol version 6 (IPv6).
+\ IPv6 refixes:
+\ ::0/8 unaligned
+\ 2000::/3 global unicast
+\ fe80::/10 link-local unicast
+\ fc00::/7 site-local IPv6 address
+\ fd00::/8 private administration
+\ ff00::/8 multicast
+
decimal
headerless
@@ -26,24 +34,60 @@
\ There maybe extension headers here.
constant /ipv6-header
+\ Values of ipv6-next-hdr
+d# 0 constant IP_HDR_HOP \ Hop-by-hop option
+d# 1 constant IP_HDR_ICMPV4 \ Internet control message protocol - IPv4
+d# 2 constant IP_HDR_IGMPV4 \ Internet group management protocol - IPv4
+d# 4 constant IP_HDR_IPV4
+d# 6 constant IP_HDR_TCP
+d# 8 constant IP_HDR_EGP \ Exterior gateway protocol
+d# 9 constant IP_HDR_IGP \ Cisco private interior gateway
+d# 17 constant IP_HDR_UDP
+d# 41 constant IP_HDR_IPV6
+d# 43 constant IP_HDR_ROUTING \ Routing header
+d# 44 constant IP_HDR_FRAGMENT
+d# 45 constant IP_HDR_IDRP \ Interdomain routing protocol
+d# 46 constant IP_HDR_RSVP \ Resource reservation protocol
+d# 47 constant IP_HDR_GRE \ General routing encapsulation
+d# 50 constant IP_HDR_SECURE \ Encrypted security payload
+d# 51 constant IP_HDR_AUTHEN \ Authentication
+d# 58 constant IP_HDR_ICMPV6
+d# 59 constant IP_HDR_NONE \ No next header
+d# 60 constant IP_HDR_DEST \ Destination options
+d# 88 constant IP_HDR_EIGRP
+d# 89 constant IP_HDR_OSPF
+d# 108 constant IP_HDR_COMP \ IP payload compression protocol
+d# 115 constant IP_HDR_L2TP \ Layer 2 tunneling protocol
+d# 132 constant IP_HDR_SCTP \ Stream control transmission protocol
+d# 135 constant IP_HDR_MOBILITY \ Mobile IPV6
+
[ifndef] include-ipv4
d# 256 buffer: 'domain-name
' 'domain-name " domain-name" chosen-string
: use-server? ( -- flag ) false ;
-: use-router? ( -- flag ) false ;
[then]
headers
-0 instance value prefix
+0 value /prefix \ Length of prefix (# of bits)
+0 value prefix-flag
+0 value prefix-lifetime
+/ipv6 buffer: my-prefix
+
/ipv6 buffer: his-ipv6-addr
+/ipv6 buffer: my-ipv6-addr-link-local
+/ipv6 buffer: my-ipv6-addr-global
+/ipv6 buffer: router-ipv6-addr
/ipv6 buffer: name-server-ipv6
headerless
\ link-local scope multicast all-nodes address
-create my-mc-ipv6-addr h# ff c, 2 c, 0 w, 0 l, 0 w, 0 c, 1 c, h# ff c, 0 c, 0 c, 0 c,
-create his-mc-ipv6-addr h# ff c, 2 c, 0 w, 0 l, 0 w, 0 c, 1 c, h# ff c, 0 c, 0 c, 0 c,
-create unknown-ipv6-addr h# 00 l, h# 00 l, h# 00 l, h# 00 l,
+create unknown-ipv6-addr 0 l, 0 l, 0 l, 0 l,
+create default-ipv6-addr h# fe c, h# 80 c, 0 w, 0 l, 0 w, 0 c, h# ff c, h# fe c, 0 c, 0 w,
+create ipv6-addr-mc-all-nodes h# ff c, 2 c, 0 w, 0 l, 0 l, 0 w, 0 c, 1 c,
+create ipv6-addr-mc-all-routers h# ff c, 2 c, 0 w, 0 l, 0 l, 0 w, 0 c, 2 c,
+create my-ipv6-addr-mc-sol-node h# ff c, 2 c, 0 w, 0 l, 0 w, 0 c, 1 c, h# ff c, 0 c, 0 w,
+create his-ipv6-addr-mc-sol-node h# ff c, 2 c, 0 w, 0 l, 0 w, 0 c, 1 c, h# ff c, 0 c, 0 w,
: ipv6= ( ip-addr1 ip-addr2 -- flag ) /ipv6 comp 0= ;
@@ -59,7 +103,7 @@
;
: prefix-match? ( ip1 ip2 -- flag )
- prefix 8 /mod 2over 2 pick ( ip1 ip2 rem quot ip1 ip2 quot )
+ /prefix 8 /mod 2over 2 pick ( ip1 ip2 rem quot ip1 ip2 quot )
comp 0= if
swap bits>mask >r ( ip1 ip2 quot ) ( R: mask )
tuck + c@ r@ and ( ip1 quot [ip2+quot]&mask ) ( R: mask )
@@ -69,26 +113,29 @@
then
;
-: set-his-mc-ipv6-addr ( -- )
- his-ipv6-addr /ipv6 + 3 - his-mc-ipv6-addr /ipv6 + 3 - 3 move
+: set-his-ipv6-addr-mc ( -- )
+ his-ipv6-addr /ipv6 + 3 - his-ipv6-addr-mc-sol-node /ipv6 + 3 - 3 move
;
-: set-my-mc-ipv6-addr ( -- )
- my-ipv6-addr /ipv6 + 3 - my-mc-ipv6-addr /ipv6 + 3 - 3 move
+: set-my-ipv6-addr-mc ( -- )
+ my-ipv6-addr-link-local /ipv6 + 3 - my-ipv6-addr-mc-sol-node /ipv6 + 3 - 3 move
;
-: his-mc-ipv6-addr? ( adr-buf -- flag )
- dup his-mc-ipv6-addr ipv6= swap unknown-ipv6-addr? or
+: his-ipv6-addr-mc? ( adr-buf -- flag )
+ >r
+ r@ his-ipv6-addr-mc-sol-node ipv6= \ His solicited node address?
+ r@ ipv6-addr-mc-all-nodes ipv6= or \ Multicast all-nodes?
+ r> ipv6-addr-mc-all-routers ipv6= or \ Multicast all-routers?
;
-: my-mc-ipv6-addr? ( adr-buf -- flag )
- dup my-mc-ipv6-addr ipv6= swap unknown-ipv6-addr? or
+: my-ipv6-addr-mc? ( adr-buf -- flag )
+ >r
+ r@ my-ipv6-addr-mc-sol-node ipv6= \ My solicited node address?
+ r> ipv6-addr-mc-all-nodes ipv6= or \ Multicast all-nodes?
;
-/ipv6 buffer: router-ipv6-addr
-: use-routerv6? ( -- flag ) router-ipv6-addr knownv6? ;
-: use-router? ( -- flag )
- use-ipv6? if use-routerv6? else use-router? then
-;
+: ipv6-addr-local? ( adr-buf -- flag ) c@ h# e0 and h# 20 <> ;
+: use-routerv6? ( -- flag ) routerv6-en-addr unknown-en-addr? not ;
+
/ipv6 buffer: server-ipv6-addr
: use-serverv6? ( -- flag ) server-ipv6-addr knownv6? ;
: use-server? ( -- flag )
@@ -96,10 +143,12 @@
;
\ Generate his multicast MAC address from his IPv6 address
-: set-his-mc-en ( -- )
- his-ipv6-addr be-w@ h# fe80 =
- his-ipv6-addr d# 11 + be-w@ h# fffe = and if
- multicast-en-addr his-en-addr 3 move
+: set-his-en-addr-mc ( -- )
+ multicast-en-addr his-en-addr 2 move
+ his-ipv6-addr c@ h# ff = if
+ his-ipv6-addr d# 12 + his-en-addr 2 + 4 move
+ else
+ h# ff his-en-addr 2 + c!
his-ipv6-addr d# 13 + his-en-addr 3 + 3 move
then
;
@@ -109,8 +158,16 @@
: indent ( -- ) bootnet-debug if ." " then ;
[then]
headerless
-: .my-ipv6-addr ( -- ) ." My IP: " my-ipv6-addr .ipv6 ;
-: .his-ipv6-addr ( -- ) ." His IP: " his-ipv6-addr .ipv6 ;
+: .my-ipv6-addr-link-local ( -- )
+ ." My IPv6 (local link): " my-ipv6-addr-link-local .ipv6
+;
+: .my-ipv6-addr-global ( -- )
+ ." My IPv6 (global): " my-ipv6-addr-global .ipv6
+;
+: .his-ipv6-addr ( -- ) ." His IP: " his-ipv6-addr .ipv6 ;
+: .my-prefix ( -- )
+ ." My prefix (global): " my-prefix .ipv6 ." /" /prefix .d
+;
[ifndef] include-ipv4
0 instance value last-ip-packet
@@ -122,8 +179,15 @@
drop
else
his-ipv6-addr copy-ipv6-addr
- set-his-mc-ipv6-addr
- unlock-link-addr
+ set-his-ipv6-addr-mc
+ his-ipv6-addr ipv6-addr-local? if
+ unlock-link-addr
+ my-ipv6-addr-link-local
+ else
+ use-routerv6? if routerv6-en-addr his-en-addr copy-en-addr then
+ my-ipv6-addr-global
+ then
+ my-ipv6-addr copy-ipv6-addr
then
;
@@ -172,17 +236,17 @@
: ipv6-payload ( -- adr len ) the-struct /ipv6-header + ipv6-length xw@ ;
+\ Skip checking his-ipv6-addr if it is an ICMPv6 packet which may come from anywhere.
+: check-his-ipv6-addr? ( -- flag ) ipv6-next-hdr c@ IP_HDR_ICMPV6 <> ;
: ipv6-addr-match? ( -- flag )
- \ If we know the server's IP address (e.g. the user specified one, or
- \ we chose one from a RARP or BOOTP reply, or we locked onto one that
- \ responded to a TFTP broadcast), then we silently discard IP packets
- \ from other hosts.
- his-ipv6-addr his-mc-ipv6-addr? 0= if
- his-ipv6-addr ipv6-source-addr ipv6= 0= if false exit then
+ check-his-ipv6-addr? if
+ his-ipv6-addr his-ipv6-addr-mc? 0= if
+ his-ipv6-addr ipv6-source-addr ipv6= 0= if false exit then
+ then
then
\ Accept IP multicast packets
- ipv6-dest-addr my-mc-ipv6-addr? if true exit then
+ ipv6-dest-addr my-ipv6-addr-mc? if true exit then
\ If we don't know our own IP address yet, we accept every IP packet
my-ipv6-addr unknown-ipv6-addr? if true exit then
Modified: ofw/inetv6/neighdis.fth
===================================================================
--- ofw/inetv6/neighdis.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/neighdis.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -3,10 +3,11 @@
headerless
-" " d# 40 config-string ipv6-dns-server
-" " d# 64 config-string ipv6-domain
-" " d# 40 config-string ipv6-router
-" stateless" d# 40 config-string ipv6-address \ leave room
+d# 200 constant ND_TIMEOUT \ Neighbor discovery timeout (ms)
+d# 200 constant DAD_TIMEOUT \ Duplicate Address Detection timeout (ms)
+d# 500 constant RD_TIMEOUT \ Router Discovery timeout (ms)
+
+" stateless" d# 40 config-string ipv6-address \ leave room
\ " dhcp" ' ipv6-address set-config-string-default
[ifndef] include-ipv4
@@ -23,17 +24,22 @@
true
;
+/ipv6 buffer: his-ipv6-addr-temp
: do-neighbor-discovery ( -- )
bootnet-debug if
." ICMPv6 ND protocol: Getting MAC address for IP address: "
his-ipv6-addr .ipv6 cr
then
- set-his-mc-en \ Set his multicast link address
- send-neigh-sol \ Neighbor solicitation
+ his-ipv6-addr his-ipv6-addr-temp copy-ipv6-addr
+ set-his-en-addr-mc \ Set his multicast link address
+ set-his-ipv6-addr-mc
+ his-ipv6-addr-mc-sol-node his-ipv6-addr copy-ipv6-addr
+ his-ipv6-addr-temp send-neigh-sol \ Neighbor solicitation
+ his-ipv6-addr-temp his-ipv6-addr copy-ipv6-addr
current-timeout >r
- timeout-msecs @ set-timeout
+ ND_TIMEOUT set-timeout
begin
IP_HDR_ICMPV6 receive-ip-packet ?dup 0= if got-nd-ad? then
until
@@ -42,11 +48,6 @@
bootnet-debug if ." Got MAC address: " his-en-addr .enaddr cr then
;
-: do-discovery ( -- )
- \ XXX need to do DHCPv6 discovery
- his-ipv6-addr be-w@ h# fe80 = if do-neighbor-discovery then
-;
-
: (resolve-en-addrv6) ( 'dest-adr type -- 'en-adr type )
dup IP_TYPE = if ( 'ip-adr ip-type )
[ifdef] include-ipv4
@@ -63,7 +64,7 @@
else ( 'dest-adr type )
dup IPV6_TYPE = if
swap his-ipv6-addr copy-ipv6-addr
- his-en-addr broadcast-en-addr en= if do-discovery then
+ his-en-addr broadcast-en-addr en= if do-neighbor-discovery then
his-en-addr swap exit
then
then
@@ -73,44 +74,113 @@
: s-all-ipv6 ( -- ) \ See discovery info
bootnet-debug if
- ." Initial configuration: (fixed) " cr
- indent .my-ipv6-addr cr
+ ." My IPv6 configuration (stateless autoconfiguration): " cr
+ indent .my-ipv6-addr-link-local cr
+ my-ipv6-addr-global unknown-ipv6-addr? not if
+ indent .my-ipv6-addr-global cr
+ indent .my-prefix cr
+ then
indent .my-link-addr cr
+ use-routerv6? if indent .routerv6-en-addr cr then
then
;
-create default-ipv6-addr h# fe c, h# 80 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c,
- 0 c, 0 c, 0 c, h# ff c, h# fe c, 0 c, 0 c, 0 c,
-: set-my-ipv6-addr ( -- )
- default-ipv6-addr my-ipv6-addr copy-ipv6-addr
- my-en-addr c@ 2 xor my-ipv6-addr 8 + c!
- my-en-addr 1+ my-ipv6-addr 9 + 2 move
- my-en-addr 3 + my-ipv6-addr d# 13 + 3 move
+: detect-dad ( -- )
+ DAD_TIMEOUT set-timeout
+ begin
+ IP_HDR_ICMPV6 receive-ip-packet
+ dup 0= if got-nd-ad? abort" Duplicate IPv6 address detected" then
+ until
;
+: set-my-ipv6-addr-link-local ( -- )
+ \ Duplicate Address Discovery
+ unknown-ipv6-addr my-ipv6-addr copy-ipv6-addr
-: configure-ipv6 ( -- ) \ Get discovery info
+ default-ipv6-addr my-ipv6-addr-link-local copy-ipv6-addr
+ my-en-addr c@ 2 xor my-ipv6-addr-link-local 8 + c!
+ my-en-addr 1+ my-ipv6-addr-link-local 9 + 2 move
+ my-en-addr 3 + my-ipv6-addr-link-local d# 13 + 3 move
+
+ set-my-ipv6-addr-mc
+
+ ipv6-addr-mc-all-nodes his-ipv6-addr copy-ipv6-addr
+ set-his-en-addr-mc
+ my-ipv6-addr-link-local send-neigh-sol
+ detect-dad
+
+ my-ipv6-addr-link-local my-ipv6-addr copy-ipv6-addr
+;
+
+: process-rd-options ( adr len -- )
+ begin dup 0> while
+ over c@ case
+ 1 of over 2 + routerv6-en-addr copy-en-addr endof \ Source link-layer address option
+ 3 of over 2 + c@ to /prefix \ Prefix option
+ over 3 + c@ to prefix-flag
+ over 8 + be-l@ to prefix-lifetime \ XXX lifetime
+ over d# 16 + my-prefix copy-ipv6-addr \ Prefix
+ endof
+ 5 of over 4 + be-l@ to (link-mtu) endof \ MTU option
+ endcase
+ over 1+ c@ 8 * /string
+ repeat 2drop
+;
+: process-rd? ( adr len -- router-ad? )
+ over c@ d# 134 <> if drop false exit then \ Router advertisement?
+ over 4 + c@ to router-hop-limit
+ over 5 + c@ to router-flags \ XXX What to do with stateful config?
+ over 6 + be-w@ to router-lifetime
+ over 8 + be-l@ to router-reachable-time
+ over d# 12 + be-l@ to router-retrans-time
+ d# 16 /string ( opt-adr,len )
+ process-rd-options ( )
+ true
+;
+: auto-cfg-global? ( -- flag )
+ my-prefix unknown-ipv6-addr? if false exit then
+ prefix-flag h# 40 and 0= if false exit then
+ /prefix d# 64 = \ XXX What to do with /prefix other than 64?
+;
+: discover-router ( -- )
+ unknown-ipv6-addr my-ipv6-addr-global copy-ipv6-addr
+ ipv6-addr-mc-all-routers his-ipv6-addr copy-ipv6-addr
+ set-his-en-addr-mc
+ send-router-sol
+
+ RD_TIMEOUT set-timeout
+ begin
+ IP_HDR_ICMPV6 receive-ip-packet ?dup 0= if process-rd? then
+ until
+ auto-cfg-global? not if exit then
+
+ \ DAD on the global IPv6 address
+ my-ipv6-addr-link-local my-ipv6-addr-global copy-ipv6-addr
+ my-prefix my-ipv6-addr-global /prefix 8 / move \ XXX assume prefix multiple of 8 bits
+
+ ipv6-addr-mc-all-nodes his-ipv6-addr copy-ipv6-addr
+ set-his-en-addr-mc
+ my-ipv6-addr-global send-neigh-sol
+ detect-dad
+;
+
+: configure-ipv6 ( -- ) \ Get discovery info
+ use-ipv6? \ Save IPv6 flag
+ true to use-ipv6?
+
['] 4drop to icmpv6-err-callback-xt
['] 2drop to icmpv6-info-callback-xt
- d# 64 to prefix
- set-my-ipv6-addr
- set-my-mc-ipv6-addr
+ d# 64 to /prefix
+ set-my-ipv6-addr-link-local
- \ XXX Duplicate address discovery; Router discovery
- \ ::0 => ff02::1:ffb4:0061 hop-by-hop, multicast listener report
- \ ::0 => ff02::2 router solicitation
- \ ::0 => ff02::1:ffb4:0061 DAD, neighbor solicitation with target addr
- \ Wait for router advertisement, if gotten, continue
- \ For each prefix in router advertisement, combine prefix with interface id
- \ Add address to the list of assigned addresses for the interface
- \ All addresses must be verified with DAD
- \ fe80::259:08ff:feb4:0061 => ff02::1:ffb4:0061 hop-by-hop, multicast listener report
+ discover-router
+ to use-ipv6? \ Restore IPv6 flag
;
: configure ( -- )
- use-ipv6? \ Save IPv6 flag
+ use-ipv6? \ Save IPv6 flag
false to use-ipv6? configure
- to use-ipv6? \ Restore IPv6 flag
+ to use-ipv6? \ Restore IPv6 flag
configure-ipv6
;
@@ -139,7 +209,7 @@
: open ( -- ok? )
[ifdef] include-ipv4
false to use-ipv6?
- open 0= if false exit then \ IPv4 open
+ open 0= if false exit then \ IPv4 open
[else]
open-link
parse-args
@@ -147,11 +217,11 @@
my-self to obp-tftp-ih
[then]
true to use-ipv6?
- ['] (resolve-en-addrv6) to resolve-en-addr
+ set-mc-hash if close false exit then
configure-ipv6
- set-mc-hash if close false exit then
s-all-ipv6
setup-ip-attr
+ ['] (resolve-en-addrv6) to resolve-en-addr
true
;
Modified: ofw/inetv6/supportv6.fth
===================================================================
--- ofw/inetv6/supportv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/supportv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -6,6 +6,12 @@
d# 16 constant /ipv6 \ Bytes per IP address
/ipv6 buffer: my-ipv6-addr
+0 value router-hop-limit
+0 value router-flags
+0 value router-lifetime
+0 value router-reachable-time
+0 value router-retrans-time
+
: copy-ipv6-addr ( src dst -- ) /ipv6 move ;
: .ipv6 ( buf -- )
@@ -107,7 +113,7 @@
" ::xyz"
" 123::456:xyz"
" xyz:123::456"
-" 123:::456" \ Error was not caught!
+" 123:::456"
" 123"
" 123:456"
" ::192.xy.1.102"
Modified: ofw/inetv6/tcpv6.fth
===================================================================
--- ofw/inetv6/tcpv6.fth 2007-08-08 03:14:05 UTC (rev 530)
+++ ofw/inetv6/tcpv6.fth 2007-08-09 21:42:49 UTC (rev 531)
@@ -1356,7 +1356,7 @@
th_sport w@ th_dport w@ th_sport w! th_dport w!
;
: multicast-dstv6? ( -- flag )
- ipv6-struct ihv6_dst tcpv6-struct ( adr ) " his-mc-ipv6-addr?" $call-parent
+ ipv6-struct ihv6_dst tcpv6-struct ( adr ) " his-ipv6-addr-mc?" $call-parent
;
/ipv6 buffer: tmp-ipv6
: dropwithresetv6 ( -- )