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"
|
||||
|
||||
"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)}
|
||||
|
|
10
main.go
10
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"gitea.drjosh.dev/josh/jrouter/atalk/nbp"
|
||||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
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!
|
||||
tuple := &nbpkt.Tuples[0]
|
||||
|
||||
ethDst := ethertalk.AppleTalkBroadcast
|
||||
if tuple.Zone != "*" && tuple.Zone != "" {
|
||||
ethDst = atalk.MulticastAddr(tuple.Zone)
|
||||
}
|
||||
|
||||
zones := rtr.ZoneTable.LookupName(tuple.Zone)
|
||||
for _, z := range zones {
|
||||
if z.Local {
|
||||
|
@ -77,10 +71,11 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
|||
|
||||
outDDP := *ddpkt
|
||||
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
|
||||
|
||||
if err := rtr.SendEtherTalkDDP(ethDst, &outDDP); err != nil {
|
||||
if err := rtr.ZoneMulticastEtherTalkDDP(tuple.Zone, &outDDP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -93,7 +88,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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue