Add BrRq-FwdReq translation

This commit is contained in:
Josh Deprez 2024-04-15 18:08:45 +10:00
parent 6b88025d19
commit d241d654d5
Signed by: josh
SSH key fingerprint: SHA256:zZji7w1Ilh2RuUpbQcqkLPrqmRwpiCSycbF2EfKm6Kw
2 changed files with 80 additions and 31 deletions

62
nbp.go
View file

@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
@ -30,7 +29,7 @@ import (
"github.com/sfiera/multitalk/pkg/ethertalk" "github.com/sfiera/multitalk/pkg/ethertalk"
) )
func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAddr aarp.AddrPair, cfg *config, ddpkt *ddp.ExtPacket) error { func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAddr aarp.AddrPair, zoneTable *ZoneTable, routeTable *RoutingTable, cfg *config, ddpkt *ddp.ExtPacket) error {
if ddpkt.Proto != ddp.ProtoNBP { if ddpkt.Proto != ddp.ProtoNBP {
return fmt.Errorf("invalid DDP type %d on socket 2", ddpkt.Proto) return fmt.Errorf("invalid DDP type %d on socket 2", ddpkt.Proto)
} }
@ -100,14 +99,11 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
case nbp.FunctionBrRq: case nbp.FunctionBrRq:
// There must be 1! // There must be 1!
tuple := nbpkt.Tuples[0] tuple := &nbpkt.Tuples[0]
if tuple.Zone != cfg.EtherTalk.ZoneName {
// TODO: Translate it into a FwdReq and route it to the
// routers with the appropriate zone(s).
return errors.New("TODO: BrRq-FwdReq translation")
}
zones := zoneTable.LookupName(tuple.Zone)
for _, z := range zones {
if z.Local {
// If it's for the local zone, translate it to a LkUp and broadcast it back // If it's for the local zone, translate it to a LkUp and broadcast it back
// out the EtherTalk port. // out the EtherTalk port.
// "Note: On an internet, nodes on extended networks performing lookups in // "Note: On an internet, nodes on extended networks performing lookups in
@ -123,10 +119,12 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
return fmt.Errorf("couldn't marshal LkUp: %v", err) return fmt.Errorf("couldn't marshal LkUp: %v", err)
} }
ddpkt.DstNode = 0xFF // Broadcast node address within the dest network outDDP := *ddpkt
ddpkt.Data = nbpRaw outDDP.Size = uint16(len(nbpRaw)) + atalk.DDPExtHeaderSize
outDDP.DstNode = 0xFF // Broadcast node address within the dest network
outDDP.Data = nbpRaw
outFrame, err := ethertalk.AppleTalk(myHWAddr, *ddpkt) outFrame, err := ethertalk.AppleTalk(myHWAddr, outDDP)
if err != nil { if err != nil {
return err return err
} }
@ -134,7 +132,45 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return err return err
} }
return pcapHandle.WritePacketData(outFrameRaw) if err := pcapHandle.WritePacketData(outFrameRaw); err != nil {
return err
}
continue
}
route := routeTable.LookupRoute(z.Network)
if route == nil {
return fmt.Errorf("no route for network %d", z.Network)
}
peer := route.Peer
if peer == nil {
return fmt.Errorf("nil peer for route for network %d", z.Network)
}
// Translate it into a FwdReq and route it to the
// routers with the appropriate zone(s).
nbpkt.Function = nbp.FunctionFwdReq
nbpRaw, err := nbpkt.Marshal()
if err != nil {
return fmt.Errorf("couldn't marshal FwdReq: %v", err)
}
outDDP := *ddpkt
outDDP.Size = uint16(len(nbpRaw)) + atalk.DDPExtHeaderSize
outDDP.DstNet = z.Network
outDDP.DstNode = 0x00 // Router node address for the dest network
outDDP.Data = nbpRaw
outDDPRaw, err := ddp.ExtMarshal(outDDP)
if err != nil {
return err
}
if _, err := peer.send(peer.tr.NewAppleTalkPacket(outDDPRaw)); err != nil {
return fmt.Errorf("sending FwdReq on to peer: %w", err)
}
}
default: default:
return fmt.Errorf("TODO: handle function %v", nbpkt.Function) return fmt.Errorf("TODO: handle function %v", nbpkt.Function)

View file

@ -85,6 +85,19 @@ func (zt *ZoneTable) Query(ns []ddp.Network) map[ddp.Network][]string {
return zs return zs
} }
func (zt *ZoneTable) LookupName(name string) []*Zone {
zt.mu.Lock()
defer zt.mu.Unlock()
var zs []*Zone
for _, z := range zt.zones {
if z.Name == name {
zs = append(zs, z)
}
}
return zs
}
func (zt *ZoneTable) LocalNames() []string { func (zt *ZoneTable) LocalNames() []string {
zt.mu.Lock() zt.mu.Lock()
seen := make(map[string]struct{}) seen := make(map[string]struct{})