Add BrRq-FwdReq translation
This commit is contained in:
parent
6b88025d19
commit
d241d654d5
2 changed files with 80 additions and 31 deletions
62
nbp.go
62
nbp.go
|
@ -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)
|
||||||
|
|
13
zones.go
13
zones.go
|
@ -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{})
|
||||||
|
|
Loading…
Reference in a new issue