diff --git a/atalk/strings.go b/atalk/strings.go index 2e2e1a8..cc8b535 100644 --- a/atalk/strings.go +++ b/atalk/strings.go @@ -20,6 +20,7 @@ import ( "math/bits" "github.com/sfiera/multitalk/pkg/ethernet" + "github.com/sfiera/multitalk/pkg/ethertalk" ) // Inside AppleTalk, appendix D @@ -96,6 +97,10 @@ func ToUpper(s string) string { } func MulticastAddr(zone string) ethernet.Addr { + if zone == "" || zone == "*" { + return ethertalk.AppleTalkBroadcast + } + // Inside AppleTalk, pp 3-10 and pp 8-18 h := Checksum(ToUpper(zone)) return ethernet.Addr{0x09, 0x00, 0x07, 0x00, 0x00, byte(h % 0xFD)} diff --git a/main.go b/main.go index 394bd93..a9e9989 100644 --- a/main.go +++ b/main.go @@ -341,7 +341,7 @@ func main() { } 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) } @@ -474,13 +474,7 @@ func main() { } // Note: resolving AARP can block - dstEth, err := aarpMachine.Resolve(ctx, ddp.Addr{Network: ddpkt.DstNet, Node: ddpkt.DstNode}) - 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 { + if err := rooter.SendEtherTalkDDP(ctx, ddpkt); err != nil { log.Printf("DDP/AURP: couldn't send Ethertalk out: %v", err) } continue diff --git a/router/aep.go b/router/aep.go index b45edfd..40c692a 100644 --- a/router/aep.go +++ b/router/aep.go @@ -47,7 +47,7 @@ func (rtr *Router) HandleAEP(src ethernet.Addr, ddpkt *ddp.ExtPacket) error { ddpkt.DstSocket, ddpkt.SrcSocket = ddpkt.SrcSocket, ddpkt.DstSocket ddpkt.Data[0] = byte(aep.EchoReply) - return rtr.SendEtherTalkDDP(src, ddpkt) + return rtr.sendEtherTalkDDP(src, ddpkt) default: return fmt.Errorf("invalid AEP function %d", ep.Function) diff --git a/router/nbp.go b/router/nbp.go index 80ab7e7..573117f 100644 --- a/router/nbp.go +++ b/router/nbp.go @@ -47,7 +47,7 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro return err } log.Print("NBP: Replying to LkUp with LkUp-Reply for myself") - return rtr.SendEtherTalkDDP(srcHWAddr, outDDP) + return rtr.sendEtherTalkDDP(srcHWAddr, outDDP) case nbp.FunctionBrRq: // There must be 1! @@ -80,7 +80,7 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro outDDP.DstNode = 0xFF // Broadcast node address within the dest network outDDP.Data = nbpRaw - if err := rtr.SendEtherTalkDDP(ethDst, &outDDP); err != nil { + if err := rtr.sendEtherTalkDDP(ethDst, &outDDP); err != nil { return err } @@ -93,7 +93,7 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro continue } 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 } diff --git a/router/nbp_aurp.go b/router/nbp_aurp.go index b0b90c5..fbf9f2a 100644 --- a/router/nbp_aurp.go +++ b/router/nbp_aurp.go @@ -20,10 +20,8 @@ import ( "fmt" "log" - "gitea.drjosh.dev/josh/jrouter/atalk" "gitea.drjosh.dev/josh/jrouter/atalk/nbp" "github.com/sfiera/multitalk/pkg/ddp" - "github.com/sfiera/multitalk/pkg/ethertalk" ) 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.Data = nbpRaw - dstEth := ethertalk.AppleTalkBroadcast - if tuple.Zone != "*" && tuple.Zone != "" { - dstEth = atalk.MulticastAddr(tuple.Zone) - } - if err := rtr.SendEtherTalkDDP(dstEth, ddpkt); err != nil { + if err := rtr.ZoneMulticastEtherTalkDDP(tuple.Zone, ddpkt); err != nil { return err } diff --git a/router/router.go b/router/router.go index e622f72..916e3a7 100644 --- a/router/router.go +++ b/router/router.go @@ -17,6 +17,9 @@ package router import ( + "context" + + "gitea.drjosh.dev/josh/jrouter/atalk" "github.com/google/gopacket/pcap" "github.com/sfiera/multitalk/pkg/ddp" "github.com/sfiera/multitalk/pkg/ethernet" @@ -24,15 +27,36 @@ import ( ) type Router struct { - Config *Config - PcapHandle *pcap.Handle - MyHWAddr ethernet.Addr - MyDDPAddr ddp.Addr - RouteTable *RoutingTable - ZoneTable *ZoneTable + Config *Config + PcapHandle *pcap.Handle + MyHWAddr ethernet.Addr + MyDDPAddr ddp.Addr + AARPMachine *AARPMachine + 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) if err != nil { return err diff --git a/router/zip.go b/router/zip.go index 5e59943..ded821f 100644 --- a/router/zip.go +++ b/router/zip.go @@ -17,6 +17,7 @@ package router import ( + "context" "fmt" "log" @@ -28,7 +29,7 @@ import ( "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 { case ddp.ProtoATP: atpkt, err := atp.UnmarshalPacket(ddpkt.Data) @@ -106,7 +107,7 @@ func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro }, Data: ddpBody, } - return rtr.SendEtherTalkDDP(srcHWAddr, respDDP) + return rtr.sendEtherTalkDDP(srcHWAddr, respDDP) case *atp.TResp: 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, } - return rtr.SendEtherTalkDDP(srcHWAddr, outDDP) + return rtr.sendEtherTalkDDP(srcHWAddr, outDDP) } // Inside AppleTalk SE, pp 8-11: @@ -272,7 +273,7 @@ func (rtr *Router) HandleZIP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro dstEth = srcHWAddr } - return rtr.SendEtherTalkDDP(dstEth, outDDP) + return rtr.sendEtherTalkDDP(dstEth, outDDP) default: return fmt.Errorf("TODO: handle type %T", zipkt)