Compare commits
2 commits
07e4e5069f
...
f53f0233a9
Author | SHA1 | Date | |
---|---|---|---|
f53f0233a9 | |||
bb2a5dff27 |
7 changed files with 50 additions and 37 deletions
|
@ -20,6 +20,7 @@ import (
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||||
|
"github.com/sfiera/multitalk/pkg/ethertalk"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Inside AppleTalk, appendix D
|
// Inside AppleTalk, appendix D
|
||||||
|
@ -96,6 +97,10 @@ func ToUpper(s string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func MulticastAddr(zone string) ethernet.Addr {
|
func MulticastAddr(zone string) ethernet.Addr {
|
||||||
|
if zone == "" || zone == "*" {
|
||||||
|
return ethertalk.AppleTalkBroadcast
|
||||||
|
}
|
||||||
|
|
||||||
// Inside AppleTalk, pp 3-10 and pp 8-18
|
// Inside AppleTalk, pp 3-10 and pp 8-18
|
||||||
h := Checksum(ToUpper(zone))
|
h := Checksum(ToUpper(zone))
|
||||||
return ethernet.Addr{0x09, 0x00, 0x07, 0x00, 0x00, byte(h % 0xFD)}
|
return ethernet.Addr{0x09, 0x00, 0x07, 0x00, 0x00, byte(h % 0xFD)}
|
||||||
|
|
10
main.go
10
main.go
|
@ -341,7 +341,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 6: // The ZIS (zone information socket / ZIP socket)
|
case 6: // The ZIS (zone information socket / ZIP socket)
|
||||||
if err := rooter.HandleZIP(ethFrame.Src, ddpkt); err != nil {
|
if err := rooter.HandleZIP(ctx, ethFrame.Src, ddpkt); err != nil {
|
||||||
log.Printf("ZIP: couldn't handle: %v", err)
|
log.Printf("ZIP: couldn't handle: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,13 +474,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: resolving AARP can block
|
// Note: resolving AARP can block
|
||||||
dstEth, err := aarpMachine.Resolve(ctx, ddp.Addr{Network: ddpkt.DstNet, Node: ddpkt.DstNode})
|
if err := rooter.SendEtherTalkDDP(ctx, ddpkt); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.Printf("DDP/AURP: couldn't resolve DDP dest %d.%d to an Ethernet address", ddpkt.DstNet, ddpkt.DstNode)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rooter.SendEtherTalkDDP(dstEth, ddpkt); err != nil {
|
|
||||||
log.Printf("DDP/AURP: couldn't send Ethertalk out: %v", err)
|
log.Printf("DDP/AURP: couldn't send Ethertalk out: %v", err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -47,7 +47,7 @@ func (rtr *Router) HandleAEP(src ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
||||||
ddpkt.DstSocket, ddpkt.SrcSocket = ddpkt.SrcSocket, ddpkt.DstSocket
|
ddpkt.DstSocket, ddpkt.SrcSocket = ddpkt.SrcSocket, ddpkt.DstSocket
|
||||||
ddpkt.Data[0] = byte(aep.EchoReply)
|
ddpkt.Data[0] = byte(aep.EchoReply)
|
||||||
|
|
||||||
return rtr.SendEtherTalkDDP(src, ddpkt)
|
return rtr.sendEtherTalkDDP(src, ddpkt)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid AEP function %d", ep.Function)
|
return fmt.Errorf("invalid AEP function %d", ep.Function)
|
||||||
|
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"gitea.drjosh.dev/josh/jrouter/atalk/nbp"
|
"gitea.drjosh.dev/josh/jrouter/atalk/nbp"
|
||||||
"github.com/sfiera/multitalk/pkg/ddp"
|
"github.com/sfiera/multitalk/pkg/ddp"
|
||||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
||||||
|
@ -47,17 +46,12 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Print("NBP: Replying to LkUp with LkUp-Reply for myself")
|
log.Print("NBP: Replying to LkUp with LkUp-Reply for myself")
|
||||||
return rtr.SendEtherTalkDDP(srcHWAddr, outDDP)
|
return rtr.sendEtherTalkDDP(srcHWAddr, outDDP)
|
||||||
|
|
||||||
case nbp.FunctionBrRq:
|
case nbp.FunctionBrRq:
|
||||||
// There must be 1!
|
// There must be 1!
|
||||||
tuple := &nbpkt.Tuples[0]
|
tuple := &nbpkt.Tuples[0]
|
||||||
|
|
||||||
ethDst := ethertalk.AppleTalkBroadcast
|
|
||||||
if tuple.Zone != "*" && tuple.Zone != "" {
|
|
||||||
ethDst = atalk.MulticastAddr(tuple.Zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
zones := rtr.ZoneTable.LookupName(tuple.Zone)
|
zones := rtr.ZoneTable.LookupName(tuple.Zone)
|
||||||
for _, z := range zones {
|
for _, z := range zones {
|
||||||
if z.Local {
|
if z.Local {
|
||||||
|
@ -77,10 +71,11 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
|
|
||||||
outDDP := *ddpkt
|
outDDP := *ddpkt
|
||||||
outDDP.Size = uint16(len(nbpRaw)) + atalk.DDPExtHeaderSize
|
outDDP.Size = uint16(len(nbpRaw)) + atalk.DDPExtHeaderSize
|
||||||
outDDP.DstNode = 0xFF // Broadcast node address within the dest network
|
outDDP.DstNet = 0x0000 // Local network broadcast
|
||||||
|
outDDP.DstNode = 0xFF // Broadcast node address within the dest network
|
||||||
outDDP.Data = nbpRaw
|
outDDP.Data = nbpRaw
|
||||||
|
|
||||||
if err := rtr.SendEtherTalkDDP(ethDst, &outDDP); err != nil {
|
if err := rtr.ZoneMulticastEtherTalkDDP(tuple.Zone, &outDDP); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +88,7 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Print("NBP: Replying to BrRq with LkUp-Reply for myself")
|
log.Print("NBP: Replying to BrRq with LkUp-Reply for myself")
|
||||||
if err := rtr.SendEtherTalkDDP(srcHWAddr, outDDP2); err != nil {
|
if err := rtr.sendEtherTalkDDP(srcHWAddr, outDDP2); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"gitea.drjosh.dev/josh/jrouter/atalk"
|
|
||||||
"gitea.drjosh.dev/josh/jrouter/atalk/nbp"
|
"gitea.drjosh.dev/josh/jrouter/atalk/nbp"
|
||||||
"github.com/sfiera/multitalk/pkg/ddp"
|
"github.com/sfiera/multitalk/pkg/ddp"
|
||||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rtr *Router) HandleNBPInAURP(peer *Peer, ddpkt *ddp.ExtPacket) error {
|
func (rtr *Router) HandleNBPInAURP(peer *Peer, ddpkt *ddp.ExtPacket) error {
|
||||||
|
@ -67,11 +65,7 @@ func (rtr *Router) HandleNBPInAURP(peer *Peer, ddpkt *ddp.ExtPacket) error {
|
||||||
ddpkt.DstNode = 0xFF // Broadcast node address within the dest network
|
ddpkt.DstNode = 0xFF // Broadcast node address within the dest network
|
||||||
ddpkt.Data = nbpRaw
|
ddpkt.Data = nbpRaw
|
||||||
|
|
||||||
dstEth := ethertalk.AppleTalkBroadcast
|
if err := rtr.ZoneMulticastEtherTalkDDP(tuple.Zone, ddpkt); err != nil {
|
||||||
if tuple.Zone != "*" && tuple.Zone != "" {
|
|
||||||
dstEth = atalk.MulticastAddr(tuple.Zone)
|
|
||||||
}
|
|
||||||
if err := rtr.SendEtherTalkDDP(dstEth, ddpkt); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitea.drjosh.dev/josh/jrouter/atalk"
|
||||||
"github.com/google/gopacket/pcap"
|
"github.com/google/gopacket/pcap"
|
||||||
"github.com/sfiera/multitalk/pkg/ddp"
|
"github.com/sfiera/multitalk/pkg/ddp"
|
||||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||||
|
@ -24,15 +27,36 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
Config *Config
|
Config *Config
|
||||||
PcapHandle *pcap.Handle
|
PcapHandle *pcap.Handle
|
||||||
MyHWAddr ethernet.Addr
|
MyHWAddr ethernet.Addr
|
||||||
MyDDPAddr ddp.Addr
|
MyDDPAddr ddp.Addr
|
||||||
RouteTable *RoutingTable
|
AARPMachine *AARPMachine
|
||||||
ZoneTable *ZoneTable
|
RouteTable *RoutingTable
|
||||||
|
ZoneTable *ZoneTable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rtr *Router) SendEtherTalkDDP(dstEth ethernet.Addr, pkt *ddp.ExtPacket) error {
|
func (rtr *Router) SendEtherTalkDDP(ctx context.Context, pkt *ddp.ExtPacket) error {
|
||||||
|
dstEth := ethertalk.AppleTalkBroadcast
|
||||||
|
if pkt.DstNode != 0xFF {
|
||||||
|
de, err := rtr.AARPMachine.Resolve(ctx, ddp.Addr{Network: pkt.DstNet, Node: pkt.DstNode})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dstEth = de
|
||||||
|
}
|
||||||
|
return rtr.sendEtherTalkDDP(dstEth, pkt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtr *Router) BroadcastEtherTalkDDP(pkt *ddp.ExtPacket) error {
|
||||||
|
return rtr.sendEtherTalkDDP(ethertalk.AppleTalkBroadcast, pkt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtr *Router) ZoneMulticastEtherTalkDDP(zone string, pkt *ddp.ExtPacket) error {
|
||||||
|
return rtr.sendEtherTalkDDP(atalk.MulticastAddr(zone), pkt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtr *Router) sendEtherTalkDDP(dstEth ethernet.Addr, pkt *ddp.ExtPacket) error {
|
||||||
outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, *pkt)
|
outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, *pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ import (
|
||||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
"github.com/sfiera/multitalk/pkg/ethertalk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
func (rtr *Router) HandleZIP(ctx context.Context, srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
||||||
switch ddpkt.Proto {
|
switch ddpkt.Proto {
|
||||||
case ddp.ProtoATP:
|
case ddp.ProtoATP:
|
||||||
atpkt, err := atp.UnmarshalPacket(ddpkt.Data)
|
atpkt, err := atp.UnmarshalPacket(ddpkt.Data)
|
||||||
|
@ -106,7 +107,7 @@ func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
},
|
},
|
||||||
Data: ddpBody,
|
Data: ddpBody,
|
||||||
}
|
}
|
||||||
return rtr.SendEtherTalkDDP(srcHWAddr, respDDP)
|
return rtr.sendEtherTalkDDP(srcHWAddr, respDDP)
|
||||||
|
|
||||||
case *atp.TResp:
|
case *atp.TResp:
|
||||||
return fmt.Errorf("TODO: support handling ZIP ATP replies?")
|
return fmt.Errorf("TODO: support handling ZIP ATP replies?")
|
||||||
|
@ -145,7 +146,7 @@ func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
},
|
},
|
||||||
Data: respRaw,
|
Data: respRaw,
|
||||||
}
|
}
|
||||||
return rtr.SendEtherTalkDDP(srcHWAddr, outDDP)
|
return rtr.sendEtherTalkDDP(srcHWAddr, outDDP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inside AppleTalk SE, pp 8-11:
|
// Inside AppleTalk SE, pp 8-11:
|
||||||
|
@ -272,7 +273,7 @@ func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
||||||
dstEth = srcHWAddr
|
dstEth = srcHWAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtr.SendEtherTalkDDP(dstEth, outDDP)
|
return rtr.sendEtherTalkDDP(dstEth, outDDP)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("TODO: handle type %T", zipkt)
|
return fmt.Errorf("TODO: handle type %T", zipkt)
|
||||||
|
|
Loading…
Reference in a new issue