Start massive refactor

This commit is contained in:
Josh Deprez 2024-04-19 14:57:25 +10:00
parent c81c6002f8
commit 52b08a83f1
No known key found for this signature in database
12 changed files with 213 additions and 160 deletions

83
main.go
View file

@ -32,6 +32,8 @@ import (
"time" "time"
"gitea.drjosh.dev/josh/jrouter/aurp" "gitea.drjosh.dev/josh/jrouter/aurp"
"gitea.drjosh.dev/josh/jrouter/router"
"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"
@ -46,7 +48,7 @@ func main() {
flag.Parse() flag.Parse()
log.Println("jrouter") log.Println("jrouter")
cfg, err := loadConfig(*configFilePath) cfg, err := router.LoadConfig(*configFilePath)
if err != nil { if err != nil {
log.Fatalf("Couldn't load configuration file: %v", err) log.Fatalf("Couldn't load configuration file: %v", err)
} }
@ -80,7 +82,7 @@ func main() {
log.Printf("EtherTalk configuration: %+v", cfg.EtherTalk) log.Printf("EtherTalk configuration: %+v", cfg.EtherTalk)
peers := make(map[udpAddr]*peer) peers := make(map[udpAddr]*router.Peer)
var nextConnID uint16 var nextConnID uint16
for nextConnID == 0 { for nextConnID == 0 {
nextConnID = uint16(rand.IntN(0x10000)) nextConnID = uint16(rand.IntN(0x10000))
@ -131,17 +133,17 @@ func main() {
handlersWG.Wait() handlersWG.Wait()
ln.Close() ln.Close()
}() }()
goPeerHandler := func(p *peer) { goPeerHandler := func(p *router.Peer) {
handlersWG.Add(1) handlersWG.Add(1)
go func() { go func() {
defer handlersWG.Done() defer handlersWG.Done()
p.handle(ctx) p.Handle(ctx)
}() }()
} }
// -------------------------------- Tables -------------------------------- // -------------------------------- Tables --------------------------------
routing := NewRoutingTable() routing := router.NewRoutingTable()
zones := NewZoneTable() zones := router.NewZoneTable()
zones.Upsert(cfg.EtherTalk.NetStart, cfg.EtherTalk.ZoneName, true) zones.Upsert(cfg.EtherTalk.NetStart, cfg.EtherTalk.ZoneName, true)
// ------------------------- Configured peer setup ------------------------ // ------------------------- Configured peer setup ------------------------
@ -156,18 +158,18 @@ func main() {
} }
log.Printf("resolved %q to %v", peerStr, raddr) log.Printf("resolved %q to %v", peerStr, raddr)
peer := &peer{ peer := &router.Peer{
cfg: cfg, Config: cfg,
tr: &aurp.Transport{ Transport: &aurp.Transport{
LocalDI: localDI, LocalDI: localDI,
RemoteDI: aurp.IPDomainIdentifier(raddr.IP), RemoteDI: aurp.IPDomainIdentifier(raddr.IP),
LocalConnID: nextConnID, LocalConnID: nextConnID,
}, },
conn: ln, UDPConn: ln,
raddr: raddr, RemoteAddr: raddr,
recv: make(chan aurp.Packet, 1024), RecieveCh: make(chan aurp.Packet, 1024),
routingTable: routing, RoutingTable: routing,
zoneTable: zones, ZoneTable: zones,
} }
aurp.Inc(&nextConnID) aurp.Inc(&nextConnID)
peers[udpAddrFromNet(raddr)] = peer peers[udpAddrFromNet(raddr)] = peer
@ -175,20 +177,30 @@ func main() {
} }
// --------------------------------- AARP --------------------------------- // --------------------------------- AARP ---------------------------------
aarpMachine := NewAARPMachine(cfg, pcapHandle, myHWAddr) aarpMachine := router.NewAARPMachine(cfg, pcapHandle, myHWAddr)
aarpCh := make(chan *ethertalk.Packet, 1024) aarpCh := make(chan *ethertalk.Packet, 1024)
go aarpMachine.Run(ctx, aarpCh) go aarpMachine.Run(ctx, aarpCh)
// --------------------------------- RTMP --------------------------------- // --------------------------------- RTMP ---------------------------------
rtmpMachine := &RTMPMachine{ rtmpMachine := &router.RTMPMachine{
aarp: aarpMachine, AARP: aarpMachine,
cfg: cfg, Config: cfg,
pcapHandle: pcapHandle, PcapHandle: pcapHandle,
routingTable: routing, RoutingTable: routing,
} }
rtmpCh := make(chan *ddp.ExtPacket, 1024) rtmpCh := make(chan *ddp.ExtPacket, 1024)
go rtmpMachine.Run(ctx, rtmpCh) go rtmpMachine.Run(ctx, rtmpCh)
// -------------------------------- Router --------------------------------
rooter := &router.Router{
Config: cfg,
PcapHandle: pcapHandle,
MyHWAddr: myHWAddr,
// MyDDPAddr: ...,
RouteTable: routing,
ZoneTable: zones,
}
// ---------------------- Raw AppleTalk/AARP inbound ---------------------- // ---------------------- Raw AppleTalk/AARP inbound ----------------------
go func() { go func() {
for { for {
@ -249,6 +261,7 @@ func main() {
if !ok { if !ok {
continue continue
} }
rooter.MyDDPAddr = myAddr.Proto
// Our network? // Our network?
// "The network number 0 is reserved to mean unknown; by default // "The network number 0 is reserved to mean unknown; by default
@ -264,8 +277,8 @@ func main() {
} }
// Encap ethPacket.Payload into an AURP packet // Encap ethPacket.Payload into an AURP packet
log.Printf("DDP: forwarding to AURP peer %v", rt.Peer.tr.RemoteDI) log.Printf("DDP: forwarding to AURP peer %v", rt.Peer.Transport.RemoteDI)
if _, err := rt.Peer.send(rt.Peer.tr.NewAppleTalkPacket(ethFrame.Payload)); err != nil { if _, err := rt.Peer.Send(rt.Peer.Transport.NewAppleTalkPacket(ethFrame.Payload)); err != nil {
log.Printf("DDP: Couldn't forward packet to AURP peer: %v", err) log.Printf("DDP: Couldn't forward packet to AURP peer: %v", err)
} }
@ -285,17 +298,17 @@ func main() {
rtmpCh <- ddpkt rtmpCh <- ddpkt
case 2: // The NIS (name information socket / NBP socket) case 2: // The NIS (name information socket / NBP socket)
if err := handleNBP(pcapHandle, myHWAddr, ethFrame.Src, myAddr, zones, routing, cfg, ddpkt); err != nil { if err := rooter.HandleNBP(ethFrame.Src, ddpkt); err != nil {
log.Printf("NBP: Couldn't handle: %v", err) log.Printf("NBP: Couldn't handle: %v", err)
} }
case 4: // The AEP socket case 4: // The AEP socket
if err := handleAEP(pcapHandle, myHWAddr, ethFrame.Src, ddpkt); err != nil { if err := rooter.HandleAEP(ethFrame.Src, ddpkt); err != nil {
log.Printf("AEP: Couldn't handle: %v", err) log.Printf("AEP: Couldn't handle: %v", err)
} }
case 6: // The ZIS (zone information socket / ZIP socket) case 6: // The ZIS (zone information socket / ZIP socket)
if err := handleZIP(pcapHandle, ethFrame.Src, myHWAddr, myAddr, cfg, zones, ddpkt); err != nil { if err := rooter.HandleZIP(ethFrame.Src, ddpkt); err != nil {
log.Printf("ZIP: couldn't handle: %v", err) log.Printf("ZIP: couldn't handle: %v", err)
} }
@ -375,7 +388,7 @@ func main() {
continue continue
} }
// It's NBP // It's NBP
if err := handleNBPInAURP(pcapHandle, myHWAddr, ddpkt); err != nil { if err := rooter.HandleNBPInAURP(ddpkt); err != nil {
log.Printf("NBP/DDP/AURP: %v", err) log.Printf("NBP/DDP/AURP: %v", err)
} }
continue continue
@ -413,18 +426,18 @@ func main() {
pr := peers[ra] pr := peers[ra]
if pr == nil { if pr == nil {
// New peer! // New peer!
pr = &peer{ pr = &router.Peer{
cfg: cfg, Config: cfg,
tr: &aurp.Transport{ Transport: &aurp.Transport{
LocalDI: localDI, LocalDI: localDI,
RemoteDI: dh.SourceDI, // platinum rule RemoteDI: dh.SourceDI, // platinum rule
LocalConnID: nextConnID, LocalConnID: nextConnID,
}, },
conn: ln, UDPConn: ln,
raddr: raddr, RemoteAddr: raddr,
recv: make(chan aurp.Packet, 1024), RecieveCh: make(chan aurp.Packet, 1024),
routingTable: routing, RoutingTable: routing,
zoneTable: zones, ZoneTable: zones,
} }
aurp.Inc(&nextConnID) aurp.Inc(&nextConnID)
peers[ra] = pr peers[ra] = pr
@ -433,7 +446,7 @@ func main() {
// Pass the packet to the goroutine in charge of this peer. // Pass the packet to the goroutine in charge of this peer.
select { select {
case pr.recv <- pkt: case pr.RecieveCh <- pkt:
// That's it for us. // That's it for us.
case <-ctx.Done(): case <-ctx.Done():

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"context" "context"
@ -44,7 +44,7 @@ const (
type AARPMachine struct { type AARPMachine struct {
*addressMappingTable *addressMappingTable
cfg *config cfg *Config
pcapHandle *pcap.Handle pcapHandle *pcap.Handle
// The Run goroutine is responsible for all writes to myAddr.Proto and // The Run goroutine is responsible for all writes to myAddr.Proto and
@ -58,7 +58,7 @@ type AARPMachine struct {
} }
// NewAARPMachine creates a new AARPMachine. // NewAARPMachine creates a new AARPMachine.
func NewAARPMachine(cfg *config, pcapHandle *pcap.Handle, myHWAddr ethernet.Addr) *AARPMachine { func NewAARPMachine(cfg *Config, pcapHandle *pcap.Handle, myHWAddr ethernet.Addr) *AARPMachine {
return &AARPMachine{ return &AARPMachine{
addressMappingTable: new(addressMappingTable), addressMappingTable: new(addressMappingTable),
cfg: cfg, cfg: cfg,

View file

@ -14,19 +14,18 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"fmt" "fmt"
"gitea.drjosh.dev/josh/jrouter/atalk/aep" "gitea.drjosh.dev/josh/jrouter/atalk/aep"
"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"
"github.com/sfiera/multitalk/pkg/ethertalk" "github.com/sfiera/multitalk/pkg/ethertalk"
) )
func handleAEP(pcapHandle *pcap.Handle, src, dst ethernet.Addr, ddpkt *ddp.ExtPacket) error { func (rtr *Router) HandleAEP(src ethernet.Addr, ddpkt *ddp.ExtPacket) error {
if ddpkt.Proto != ddp.ProtoAEP { if ddpkt.Proto != ddp.ProtoAEP {
return fmt.Errorf("invalid DDP type %d on socket 4", ddpkt.Proto) return fmt.Errorf("invalid DDP type %d on socket 4", ddpkt.Proto)
} }
@ -49,16 +48,16 @@ func handleAEP(pcapHandle *pcap.Handle, src, dst ethernet.Addr, ddpkt *ddp.ExtPa
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)
ethFrame, err := ethertalk.AppleTalk(src, *ddpkt) ethFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, *ddpkt)
if err != nil { if err != nil {
return err return err
} }
ethFrame.Dst = dst ethFrame.Dst = src
ethFrameRaw, err := ethertalk.Marshal(*ethFrame) ethFrameRaw, err := ethertalk.Marshal(*ethFrame)
if err != nil { if err != nil {
return err return err
} }
return pcapHandle.WritePacketData(ethFrameRaw) return rtr.PcapHandle.WritePacketData(ethFrameRaw)
default: default:
return fmt.Errorf("invalid AEP function %d", ep.Function) return fmt.Errorf("invalid AEP function %d", ep.Function)

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"os" "os"
@ -23,7 +23,7 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
type config struct { type Config struct {
// Optional: default is 387. // Optional: default is 387.
ListenPort uint16 `yaml:"listen_port"` ListenPort uint16 `yaml:"listen_port"`
@ -55,14 +55,14 @@ type config struct {
Peers []string `yaml:"peers"` Peers []string `yaml:"peers"`
} }
func loadConfig(cfgPath string) (*config, error) { func LoadConfig(cfgPath string) (*Config, error) {
f, err := os.Open(cfgPath) f, err := os.Open(cfgPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer f.Close() defer f.Close()
c := new(config) c := new(Config)
if err := yaml.NewDecoder(f).Decode(c); err != nil { if err := yaml.NewDecoder(f).Decode(c); err != nil {
return nil, err return nil, err
} }

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"fmt" "fmt"
@ -22,14 +22,12 @@ import (
"gitea.drjosh.dev/josh/jrouter/atalk" "gitea.drjosh.dev/josh/jrouter/atalk"
"gitea.drjosh.dev/josh/jrouter/atalk/nbp" "gitea.drjosh.dev/josh/jrouter/atalk/nbp"
"github.com/google/gopacket/pcap"
"github.com/sfiera/multitalk/pkg/aarp"
"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" "github.com/sfiera/multitalk/pkg/ethertalk"
) )
func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAddr aarp.AddrPair, zoneTable *ZoneTable, routeTable *RoutingTable, cfg *config, ddpkt *ddp.ExtPacket) error { func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, 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)
} }
@ -51,7 +49,7 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
if tuple.Type != "AppleRouter" && tuple.Type != "=" { if tuple.Type != "AppleRouter" && tuple.Type != "=" {
return nil return nil
} }
if tuple.Zone != cfg.EtherTalk.ZoneName && tuple.Zone != "*" && tuple.Zone != "" { if tuple.Zone != rtr.Config.EtherTalk.ZoneName && tuple.Zone != "*" && tuple.Zone != "" {
return nil return nil
} }
respPkt := &nbp.Packet{ respPkt := &nbp.Packet{
@ -59,13 +57,13 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
NBPID: nbpkt.NBPID, NBPID: nbpkt.NBPID,
Tuples: []nbp.Tuple{ Tuples: []nbp.Tuple{
{ {
Network: myAddr.Proto.Network, Network: rtr.MyDDPAddr.Network,
Node: myAddr.Proto.Node, Node: rtr.MyDDPAddr.Node,
Socket: 253, Socket: 253,
Enumerator: 0, Enumerator: 0,
Object: "jrouter", Object: "jrouter",
Type: "AppleRouter", Type: "AppleRouter",
Zone: cfg.EtherTalk.ZoneName, Zone: rtr.Config.EtherTalk.ZoneName,
}, },
}, },
} }
@ -80,13 +78,13 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
DstNet: ddpkt.SrcNet, DstNet: ddpkt.SrcNet,
DstNode: ddpkt.SrcNode, DstNode: ddpkt.SrcNode,
DstSocket: ddpkt.SrcSocket, DstSocket: ddpkt.SrcSocket,
SrcNet: myAddr.Proto.Network, SrcNet: rtr.MyDDPAddr.Network,
SrcNode: myAddr.Proto.Node, SrcNode: rtr.MyDDPAddr.Node,
SrcSocket: 2, SrcSocket: 2,
}, },
Data: respRaw, Data: respRaw,
} }
outFrame, err := ethertalk.AppleTalk(myHWAddr, outDDP) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, outDDP)
if err != nil { if err != nil {
return err return err
} }
@ -95,7 +93,7 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return err return err
} }
return pcapHandle.WritePacketData(outFrameRaw) return rtr.PcapHandle.WritePacketData(outFrameRaw)
case nbp.FunctionBrRq: case nbp.FunctionBrRq:
// There must be 1! // There must be 1!
@ -105,7 +103,7 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
ethDst = atalk.MulticastAddr(tuple.Zone) ethDst = atalk.MulticastAddr(tuple.Zone)
} }
zones := zoneTable.LookupName(tuple.Zone) zones := rtr.ZoneTable.LookupName(tuple.Zone)
for _, z := range zones { for _, z := range zones {
if z.Local { 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
@ -127,7 +125,7 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
outDDP.DstNode = 0xFF // Broadcast node address within the dest network outDDP.DstNode = 0xFF // Broadcast node address within the dest network
outDDP.Data = nbpRaw outDDP.Data = nbpRaw
outFrame, err := ethertalk.AppleTalk(myHWAddr, outDDP) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, outDDP)
if err != nil { if err != nil {
return err return err
} }
@ -136,14 +134,14 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return err return err
} }
if err := pcapHandle.WritePacketData(outFrameRaw); err != nil { if err := rtr.PcapHandle.WritePacketData(outFrameRaw); err != nil {
return err return err
} }
continue continue
} }
route := routeTable.LookupRoute(z.Network) route := rtr.RouteTable.LookupRoute(z.Network)
if route == nil { if route == nil {
return fmt.Errorf("no route for network %d", z.Network) return fmt.Errorf("no route for network %d", z.Network)
} }
@ -171,7 +169,7 @@ func handleNBP(pcapHandle *pcap.Handle, myHWAddr, srcHWAddr ethernet.Addr, myAdd
return err return err
} }
if _, err := peer.send(peer.tr.NewAppleTalkPacket(outDDPRaw)); err != nil { if _, err := peer.Send(peer.Transport.NewAppleTalkPacket(outDDPRaw)); err != nil {
return fmt.Errorf("sending FwdReq on to peer: %w", err) return fmt.Errorf("sending FwdReq on to peer: %w", err)
} }
} }

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"fmt" "fmt"
@ -22,13 +22,11 @@ import (
"gitea.drjosh.dev/josh/jrouter/atalk" "gitea.drjosh.dev/josh/jrouter/atalk"
"gitea.drjosh.dev/josh/jrouter/atalk/nbp" "gitea.drjosh.dev/josh/jrouter/atalk/nbp"
"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/ethertalk" "github.com/sfiera/multitalk/pkg/ethertalk"
) )
func handleNBPInAURP(pcapHandle *pcap.Handle, myHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error { func (rtr *Router) HandleNBPInAURP(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)
} }
@ -63,7 +61,7 @@ func handleNBPInAURP(pcapHandle *pcap.Handle, myHWAddr ethernet.Addr, ddpkt *ddp
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
outFrame, err := ethertalk.AppleTalk(myHWAddr, *ddpkt) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, *ddpkt)
if err != nil { if err != nil {
return err return err
} }
@ -74,5 +72,5 @@ func handleNBPInAURP(pcapHandle *pcap.Handle, myHWAddr ethernet.Addr, ddpkt *ddp
if err != nil { if err != nil {
return err return err
} }
return pcapHandle.WritePacketData(outFrameRaw) return rtr.PcapHandle.WritePacketData(outFrameRaw)
} }

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"bytes" "bytes"
@ -75,28 +75,27 @@ func (ss senderState) String() string {
}[ss] }[ss]
} }
type peer struct { type Peer struct {
cfg *config Config *Config
tr *aurp.Transport Transport *aurp.Transport
conn *net.UDPConn UDPConn *net.UDPConn
raddr *net.UDPAddr RemoteAddr *net.UDPAddr
recv chan aurp.Packet RecieveCh chan aurp.Packet
RoutingTable *RoutingTable
routingTable *RoutingTable ZoneTable *ZoneTable
zoneTable *ZoneTable
} }
// send encodes and sends pkt to the remote host. // Send encodes and sends pkt to the remote host.
func (p *peer) send(pkt aurp.Packet) (int, error) { func (p *Peer) Send(pkt aurp.Packet) (int, error) {
var b bytes.Buffer var b bytes.Buffer
if _, err := pkt.WriteTo(&b); err != nil { if _, err := pkt.WriteTo(&b); err != nil {
return 0, err return 0, err
} }
log.Printf("Sending %T (len %d) to %v", pkt, b.Len(), p.raddr) log.Printf("Sending %T (len %d) to %v", pkt, b.Len(), p.RemoteAddr)
return p.conn.WriteToUDP(b.Bytes(), p.raddr) return p.UDPConn.WriteToUDP(b.Bytes(), p.RemoteAddr)
} }
func (p *peer) handle(ctx context.Context) error { func (p *Peer) Handle(ctx context.Context) error {
ticker := time.NewTicker(1 * time.Second) ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop() defer ticker.Stop()
@ -108,7 +107,7 @@ func (p *peer) handle(ctx context.Context) error {
sstate := ssUnconnected sstate := ssUnconnected
// Write an Open-Req packet // Write an Open-Req packet
if _, err := p.send(p.tr.NewOpenReqPacket(nil)); err != nil { if _, err := p.Send(p.Transport.NewOpenReqPacket(nil)); err != nil {
log.Printf("Couldn't send Open-Req packet: %v", err) log.Printf("Couldn't send Open-Req packet: %v", err)
return err return err
} }
@ -123,7 +122,7 @@ func (p *peer) handle(ctx context.Context) error {
return ctx.Err() return ctx.Err()
} }
// Send a best-effort Router Down before returning // Send a best-effort Router Down before returning
if _, err := p.send(p.tr.NewRDPacket(aurp.ErrCodeNormalClose)); err != nil { if _, err := p.Send(p.Transport.NewRDPacket(aurp.ErrCodeNormalClose)); err != nil {
log.Printf("Couldn't send RD packet: %v", err) log.Printf("Couldn't send RD packet: %v", err)
} }
return ctx.Err() return ctx.Err()
@ -143,7 +142,7 @@ func (p *peer) handle(ctx context.Context) error {
// Send another Open-Req // Send another Open-Req
sendRetries++ sendRetries++
lastSend = time.Now() lastSend = time.Now()
if _, err := p.send(p.tr.NewOpenReqPacket(nil)); err != nil { if _, err := p.Send(p.Transport.NewOpenReqPacket(nil)); err != nil {
log.Printf("Couldn't send Open-Req packet: %v", err) log.Printf("Couldn't send Open-Req packet: %v", err)
return err return err
} }
@ -153,7 +152,7 @@ func (p *peer) handle(ctx context.Context) error {
if time.Since(lastHeardFrom) <= lastHeardFromTimer { if time.Since(lastHeardFrom) <= lastHeardFromTimer {
break break
} }
if _, err := p.send(p.tr.NewTicklePacket()); err != nil { if _, err := p.Send(p.Transport.NewTicklePacket()); err != nil {
log.Printf("Couldn't send Tickle: %v", err) log.Printf("Couldn't send Tickle: %v", err)
return err return err
} }
@ -173,7 +172,7 @@ func (p *peer) handle(ctx context.Context) error {
sendRetries++ sendRetries++
lastSend = time.Now() lastSend = time.Now()
if _, err := p.send(p.tr.NewTicklePacket()); err != nil { if _, err := p.Send(p.Transport.NewTicklePacket()); err != nil {
log.Printf("Couldn't send Tickle: %v", err) log.Printf("Couldn't send Tickle: %v", err)
return err return err
} }
@ -185,7 +184,7 @@ func (p *peer) handle(ctx context.Context) error {
// TODO // TODO
} }
case pkt := <-p.recv: case pkt := <-p.RecieveCh:
lastHeardFrom = time.Now() lastHeardFrom = time.Now()
switch pkt := pkt.(type) { switch pkt := pkt.(type) {
@ -195,25 +194,25 @@ func (p *peer) handle(ctx context.Context) error {
} }
// The peer tells us their connection ID in Open-Req. // The peer tells us their connection ID in Open-Req.
p.tr.RemoteConnID = pkt.ConnectionID p.Transport.RemoteConnID = pkt.ConnectionID
// Formulate a response. // Formulate a response.
var orsp *aurp.OpenRspPacket var orsp *aurp.OpenRspPacket
switch { switch {
case pkt.Version != 1: case pkt.Version != 1:
// Respond with Open-Rsp with unknown version error. // Respond with Open-Rsp with unknown version error.
orsp = p.tr.NewOpenRspPacket(0, int16(aurp.ErrCodeInvalidVersion), nil) orsp = p.Transport.NewOpenRspPacket(0, int16(aurp.ErrCodeInvalidVersion), nil)
case len(pkt.Options) > 0: case len(pkt.Options) > 0:
// Options? OPTIONS? We don't accept no stinkin' _options_ // Options? OPTIONS? We don't accept no stinkin' _options_
orsp = p.tr.NewOpenRspPacket(0, int16(aurp.ErrCodeOptionNegotiation), nil) orsp = p.Transport.NewOpenRspPacket(0, int16(aurp.ErrCodeOptionNegotiation), nil)
default: default:
// Accept it I guess. // Accept it I guess.
orsp = p.tr.NewOpenRspPacket(0, 1, nil) orsp = p.Transport.NewOpenRspPacket(0, 1, nil)
} }
if _, err := p.send(orsp); err != nil { if _, err := p.Send(orsp); err != nil {
log.Printf("Couldn't send Open-Rsp: %v", err) log.Printf("Couldn't send Open-Rsp: %v", err)
return err return err
} }
@ -225,7 +224,7 @@ func (p *peer) handle(ctx context.Context) error {
if rstate == rsUnconnected { if rstate == rsUnconnected {
lastSend = time.Now() lastSend = time.Now()
sendRetries = 0 sendRetries = 0
if _, err := p.send(p.tr.NewOpenReqPacket(nil)); err != nil { if _, err := p.Send(p.Transport.NewOpenReqPacket(nil)); err != nil {
log.Printf("Couldn't send Open-Req packet: %v", err) log.Printf("Couldn't send Open-Req packet: %v", err)
return err return err
} }
@ -238,7 +237,7 @@ func (p *peer) handle(ctx context.Context) error {
} }
if pkt.RateOrErrCode < 0 { if pkt.RateOrErrCode < 0 {
// It's an error code. // It's an error code.
log.Printf("Open-Rsp error code from peer %v: %d", p.raddr.IP, pkt.RateOrErrCode) log.Printf("Open-Rsp error code from peer %v: %d", p.RemoteAddr.IP, pkt.RateOrErrCode)
rstate = rsUnconnected rstate = rsUnconnected
break break
} }
@ -246,7 +245,7 @@ func (p *peer) handle(ctx context.Context) error {
rstate = rsConnected rstate = rsConnected
// Send an RI-Req // Send an RI-Req
if _, err := p.send(p.tr.NewRIReqPacket()); err != nil { if _, err := p.Send(p.Transport.NewRIReqPacket()); err != nil {
log.Printf("Couldn't send RI-Req packet: %v", err) log.Printf("Couldn't send RI-Req packet: %v", err)
return err return err
} }
@ -260,13 +259,13 @@ func (p *peer) handle(ctx context.Context) error {
nets := aurp.NetworkTuples{ nets := aurp.NetworkTuples{
{ {
Extended: true, Extended: true,
RangeStart: uint16(p.cfg.EtherTalk.NetStart), RangeStart: uint16(p.Config.EtherTalk.NetStart),
RangeEnd: uint16(p.cfg.EtherTalk.NetEnd), RangeEnd: uint16(p.Config.EtherTalk.NetEnd),
Distance: 0, Distance: 0,
}, },
} }
p.tr.LocalSeq = 1 p.Transport.LocalSeq = 1
if _, err := p.send(p.tr.NewRIRspPacket(aurp.RoutingFlagLast, nets)); err != nil { if _, err := p.Send(p.Transport.NewRIRspPacket(aurp.RoutingFlagLast, nets)); err != nil {
log.Printf("Couldn't send RI-Rsp packet: %v", err) log.Printf("Couldn't send RI-Rsp packet: %v", err)
return err return err
} }
@ -280,7 +279,7 @@ func (p *peer) handle(ctx context.Context) error {
log.Printf("Learned about these networks: %v", pkt.Networks) log.Printf("Learned about these networks: %v", pkt.Networks)
for _, nt := range pkt.Networks { for _, nt := range pkt.Networks {
p.routingTable.UpsertRoute( p.RoutingTable.UpsertRoute(
nt.Extended, nt.Extended,
ddp.Network(nt.RangeStart), ddp.Network(nt.RangeStart),
ddp.Network(nt.RangeEnd), ddp.Network(nt.RangeEnd),
@ -291,7 +290,7 @@ func (p *peer) handle(ctx context.Context) error {
// TODO: track which networks we don't have zone info for, and // TODO: track which networks we don't have zone info for, and
// only set SZI for those ? // only set SZI for those ?
if _, err := p.send(p.tr.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, aurp.RoutingFlagSendZoneInfo)); err != nil { if _, err := p.Send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, aurp.RoutingFlagSendZoneInfo)); err != nil {
log.Printf("Couldn't send RI-Ack packet: %v", err) log.Printf("Couldn't send RI-Ack packet: %v", err)
return err return err
} }
@ -324,11 +323,11 @@ func (p *peer) handle(ctx context.Context) error {
if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 { if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 {
zones := aurp.ZoneTuples{ zones := aurp.ZoneTuples{
{ {
Network: uint16(p.cfg.EtherTalk.NetStart), Network: uint16(p.Config.EtherTalk.NetStart),
Name: p.cfg.EtherTalk.ZoneName, Name: p.Config.EtherTalk.ZoneName,
}, },
} }
if _, err := p.send(p.tr.NewZIRspPacket(zones)); err != nil { if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil {
log.Printf("Couldn't send ZI-Rsp packet: %v", err) log.Printf("Couldn't send ZI-Rsp packet: %v", err)
} }
} }
@ -346,7 +345,7 @@ func (p *peer) handle(ctx context.Context) error {
log.Printf("Router Down: error code %d %s", pkt.ErrorCode, pkt.ErrorCode) log.Printf("Router Down: error code %d %s", pkt.ErrorCode, pkt.ErrorCode)
// Respond with RI-Ack // Respond with RI-Ack
if _, err := p.send(p.tr.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, 0)); err != nil { if _, err := p.Send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, 0)); err != nil {
log.Printf("Couldn't send RI-Ack: %v", err) log.Printf("Couldn't send RI-Ack: %v", err)
return err return err
} }
@ -358,11 +357,11 @@ func (p *peer) handle(ctx context.Context) error {
// ZI-Req // ZI-Req
zones := aurp.ZoneTuples{ zones := aurp.ZoneTuples{
{ {
Network: uint16(p.cfg.EtherTalk.NetStart), Network: uint16(p.Config.EtherTalk.NetStart),
Name: p.cfg.EtherTalk.ZoneName, Name: p.Config.EtherTalk.ZoneName,
}, },
} }
if _, err := p.send(p.tr.NewZIRspPacket(zones)); err != nil { if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil {
log.Printf("Couldn't send ZI-Rsp packet: %v", err) log.Printf("Couldn't send ZI-Rsp packet: %v", err)
return err return err
} }
@ -370,11 +369,11 @@ func (p *peer) handle(ctx context.Context) error {
case *aurp.ZIRspPacket: case *aurp.ZIRspPacket:
log.Printf("Learned about these zones: %v", pkt.Zones) log.Printf("Learned about these zones: %v", pkt.Zones)
for _, zt := range pkt.Zones { for _, zt := range pkt.Zones {
p.zoneTable.Upsert(ddp.Network(zt.Network), zt.Name, false) p.ZoneTable.Upsert(ddp.Network(zt.Network), zt.Name, false)
} }
case *aurp.GDZLReqPacket: case *aurp.GDZLReqPacket:
if _, err := p.send(p.tr.NewGDZLRspPacket(-1, nil)); err != nil { if _, err := p.Send(p.Transport.NewGDZLRspPacket(-1, nil)); err != nil {
log.Printf("Couldn't send GDZL-Rsp packet: %v", err) log.Printf("Couldn't send GDZL-Rsp packet: %v", err)
return err return err
} }
@ -383,7 +382,7 @@ func (p *peer) handle(ctx context.Context) error {
log.Printf("Received a GDZL-Rsp, but I wouldn't have sent a GDZL-Req - that's weird") log.Printf("Received a GDZL-Rsp, but I wouldn't have sent a GDZL-Req - that's weird")
case *aurp.GZNReqPacket: case *aurp.GZNReqPacket:
if _, err := p.send(p.tr.NewGZNRspPacket(pkt.ZoneName, false, nil)); err != nil { if _, err := p.Send(p.Transport.NewGZNRspPacket(pkt.ZoneName, false, nil)); err != nil {
log.Printf("Couldn't send GZN-Rsp packet: %v", err) log.Printf("Couldn't send GZN-Rsp packet: %v", err)
return err return err
} }
@ -393,7 +392,7 @@ func (p *peer) handle(ctx context.Context) error {
case *aurp.TicklePacket: case *aurp.TicklePacket:
// Immediately respond with Tickle-Ack // Immediately respond with Tickle-Ack
if _, err := p.send(p.tr.NewTickleAckPacket()); err != nil { if _, err := p.Send(p.Transport.NewTickleAckPacket()); err != nil {
log.Printf("Couldn't send Tickle-Ack: %v", err) log.Printf("Couldn't send Tickle-Ack: %v", err)
return err return err
} }

View file

@ -1,4 +1,20 @@
package main /*
Copyright 2024 Josh Deprez
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package router
import ( import (
"fmt" "fmt"
@ -14,7 +30,7 @@ type Route struct {
Extended bool Extended bool
NetStart ddp.Network NetStart ddp.Network
NetEnd ddp.Network NetEnd ddp.Network
Peer *peer Peer *Peer
Distance uint8 Distance uint8
LastSeen time.Time LastSeen time.Time
} }
@ -56,7 +72,7 @@ func (rt *RoutingTable) LookupRoute(network ddp.Network) *Route {
return bestRoute return bestRoute
} }
func (rt *RoutingTable) UpsertRoute(extended bool, netStart, netEnd ddp.Network, peer *peer, metric uint8) error { func (rt *RoutingTable) UpsertRoute(extended bool, netStart, netEnd ddp.Network, peer *Peer, metric uint8) error {
if netStart > netEnd { if netStart > netEnd {
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd) return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
} }

32
router/router.go Normal file
View file

@ -0,0 +1,32 @@
/*
Copyright 2024 Josh Deprez
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package router
import (
"github.com/google/gopacket/pcap"
"github.com/sfiera/multitalk/pkg/ddp"
"github.com/sfiera/multitalk/pkg/ethernet"
)
type Router struct {
Config *Config
PcapHandle *pcap.Handle
MyHWAddr ethernet.Addr
MyDDPAddr ddp.Addr
RouteTable *RoutingTable
ZoneTable *ZoneTable
}

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"context" "context"
@ -33,17 +33,17 @@ import (
// RTMPMachine implements RTMP on an AppleTalk network attached to the router. // RTMPMachine implements RTMP on an AppleTalk network attached to the router.
type RTMPMachine struct { type RTMPMachine struct {
aarp *AARPMachine AARP *AARPMachine
cfg *config Config *Config
pcapHandle *pcap.Handle PcapHandle *pcap.Handle
routingTable *RoutingTable RoutingTable *RoutingTable
} }
// Run executes the machine. // Run executes the machine.
func (m *RTMPMachine) Run(ctx context.Context, incomingCh <-chan *ddp.ExtPacket) error { func (m *RTMPMachine) Run(ctx context.Context, incomingCh <-chan *ddp.ExtPacket) error {
// Await local address assignment before doing anything // Await local address assignment before doing anything
<-m.aarp.Assigned() <-m.AARP.Assigned()
myAddr, ok := m.aarp.Address() myAddr, ok := m.AARP.Address()
if !ok { if !ok {
return fmt.Errorf("AARP machine closed Assigned channel but Address is not valid") return fmt.Errorf("AARP machine closed Assigned channel but Address is not valid")
} }
@ -76,7 +76,7 @@ func (m *RTMPMachine) Run(ctx context.Context, incomingCh <-chan *ddp.ExtPacket)
} }
// should be in the cache... // should be in the cache...
theirHWAddr, err := m.aarp.Resolve(ctx, ddp.Addr{Network: pkt.SrcNet, Node: pkt.SrcNode}) theirHWAddr, err := m.AARP.Resolve(ctx, ddp.Addr{Network: pkt.SrcNet, Node: pkt.SrcNode})
if err != nil { if err != nil {
log.Printf("RTMP: Couldn't resolve %d.%d to a hardware address: %v", pkt.SrcNet, pkt.SrcNode, err) log.Printf("RTMP: Couldn't resolve %d.%d to a hardware address: %v", pkt.SrcNet, pkt.SrcNode, err)
continue continue
@ -88,8 +88,8 @@ func (m *RTMPMachine) Run(ctx context.Context, incomingCh <-chan *ddp.ExtPacket)
respPkt := &rtmp.ResponsePacket{ respPkt := &rtmp.ResponsePacket{
SenderAddr: myAddr.Proto, SenderAddr: myAddr.Proto,
Extended: true, Extended: true,
RangeStart: m.cfg.EtherTalk.NetStart, RangeStart: m.Config.EtherTalk.NetStart,
RangeEnd: m.cfg.EtherTalk.NetEnd, RangeEnd: m.Config.EtherTalk.NetEnd,
} }
respPktRaw, err := respPkt.Marshal() respPktRaw, err := respPkt.Marshal()
if err != nil { if err != nil {
@ -170,7 +170,7 @@ func (m *RTMPMachine) send(src, dst ethernet.Addr, ddpPkt *ddp.ExtPacket) error
if err != nil { if err != nil {
return err return err
} }
return m.pcapHandle.WritePacketData(ethFrameRaw) return m.PcapHandle.WritePacketData(ethFrameRaw)
} }
func (m *RTMPMachine) broadcastData(myAddr aarp.AddrPair) error { func (m *RTMPMachine) broadcastData(myAddr aarp.AddrPair) error {
@ -209,13 +209,13 @@ func (m *RTMPMachine) dataPacket(myAddr ddp.Addr) *rtmp.DataPacket {
// to that network." // to that network."
{ {
Extended: true, Extended: true,
RangeStart: m.cfg.EtherTalk.NetStart, RangeStart: m.Config.EtherTalk.NetStart,
RangeEnd: m.cfg.EtherTalk.NetEnd, RangeEnd: m.Config.EtherTalk.NetEnd,
Distance: 0, Distance: 0,
}, },
}, },
} }
for _, rt := range m.routingTable.ValidRoutes() { for _, rt := range m.RoutingTable.ValidRoutes() {
p.NetworkTuples = append(p.NetworkTuples, rtmp.NetworkTuple{ p.NetworkTuples = append(p.NetworkTuples, rtmp.NetworkTuple{
Extended: rt.Extended, Extended: rt.Extended,
RangeStart: rt.NetStart, RangeStart: rt.NetStart,

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"fmt" "fmt"
@ -23,14 +23,12 @@ import (
"gitea.drjosh.dev/josh/jrouter/atalk" "gitea.drjosh.dev/josh/jrouter/atalk"
"gitea.drjosh.dev/josh/jrouter/atalk/atp" "gitea.drjosh.dev/josh/jrouter/atalk/atp"
"gitea.drjosh.dev/josh/jrouter/atalk/zip" "gitea.drjosh.dev/josh/jrouter/atalk/zip"
"github.com/google/gopacket/pcap"
"github.com/sfiera/multitalk/pkg/aarp"
"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" "github.com/sfiera/multitalk/pkg/ethertalk"
) )
func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAddr aarp.AddrPair, cfg *config, zones *ZoneTable, ddpkt *ddp.ExtPacket) error { func (rtr *Router) HandleZIP(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)
@ -54,13 +52,13 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
switch gzl.Function { switch gzl.Function {
case zip.FunctionGetZoneList: case zip.FunctionGetZoneList:
resp.Zones = zones.AllNames() resp.Zones = rtr.ZoneTable.AllNames()
case zip.FunctionGetLocalZones: case zip.FunctionGetLocalZones:
resp.Zones = zones.LocalNames() resp.Zones = rtr.ZoneTable.LocalNames()
case zip.FunctionGetMyZone: case zip.FunctionGetMyZone:
resp.Zones = []string{cfg.EtherTalk.ZoneName} resp.Zones = []string{rtr.Config.EtherTalk.ZoneName}
} }
// Inside AppleTalk SE, pp 8-8 // Inside AppleTalk SE, pp 8-8
@ -101,14 +99,14 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
DstNet: ddpkt.SrcNet, DstNet: ddpkt.SrcNet,
DstNode: ddpkt.SrcNode, DstNode: ddpkt.SrcNode,
DstSocket: ddpkt.SrcSocket, DstSocket: ddpkt.SrcSocket,
SrcNet: myAddr.Proto.Network, SrcNet: rtr.MyDDPAddr.Network,
SrcNode: myAddr.Proto.Node, SrcNode: rtr.MyDDPAddr.Node,
SrcSocket: 6, SrcSocket: 6,
Proto: ddp.ProtoATP, Proto: ddp.ProtoATP,
}, },
Data: ddpBody, Data: ddpBody,
} }
outFrame, err := ethertalk.AppleTalk(myHWAddr, respDDP) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, respDDP)
if err != nil { if err != nil {
return err return err
} }
@ -117,7 +115,7 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return err return err
} }
return pcapHandle.WritePacketData(outFrameRaw) return rtr.PcapHandle.WritePacketData(outFrameRaw)
case *atp.TResp: case *atp.TResp:
return fmt.Errorf("TODO: support handling ZIP ATP replies?") return fmt.Errorf("TODO: support handling ZIP ATP replies?")
@ -135,7 +133,7 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
switch zipkt := zipkt.(type) { switch zipkt := zipkt.(type) {
case *zip.QueryPacket: case *zip.QueryPacket:
log.Printf("ZIP: Got Query for networks %v", zipkt.Networks) log.Printf("ZIP: Got Query for networks %v", zipkt.Networks)
networks := zones.Query(zipkt.Networks) networks := rtr.ZoneTable.Query(zipkt.Networks)
sendReply := func(resp *zip.ReplyPacket) error { sendReply := func(resp *zip.ReplyPacket) error {
respRaw, err := resp.Marshal() respRaw, err := resp.Marshal()
@ -149,15 +147,15 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
DstNet: ddpkt.SrcNet, DstNet: ddpkt.SrcNet,
DstNode: ddpkt.SrcNode, DstNode: ddpkt.SrcNode,
DstSocket: ddpkt.SrcSocket, DstSocket: ddpkt.SrcSocket,
SrcNet: myAddr.Proto.Network, SrcNet: rtr.MyDDPAddr.Network,
SrcNode: myAddr.Proto.Node, SrcNode: rtr.MyDDPAddr.Node,
SrcSocket: 6, SrcSocket: 6,
Proto: ddp.ProtoZIP, Proto: ddp.ProtoZIP,
}, },
Data: respRaw, Data: respRaw,
} }
outFrame, err := ethertalk.AppleTalk(myHWAddr, outDDP) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, outDDP)
if err != nil { if err != nil {
return fmt.Errorf("couldn't create EtherTalk frame: %w", err) return fmt.Errorf("couldn't create EtherTalk frame: %w", err)
} }
@ -167,7 +165,7 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return fmt.Errorf("couldn't marshal EtherTalk frame: %w", err) return fmt.Errorf("couldn't marshal EtherTalk frame: %w", err)
} }
if err := pcapHandle.WritePacketData(outFrameRaw); err != nil { if err := rtr.PcapHandle.WritePacketData(outFrameRaw); err != nil {
return fmt.Errorf("couldn't write packet data: %w", err) return fmt.Errorf("couldn't write packet data: %w", err)
} }
return nil return nil
@ -246,14 +244,14 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
// Only running a network with one zone for now. // Only running a network with one zone for now.
resp := &zip.GetNetInfoReplyPacket{ resp := &zip.GetNetInfoReplyPacket{
ZoneInvalid: zipkt.ZoneName != cfg.EtherTalk.ZoneName, ZoneInvalid: zipkt.ZoneName != rtr.Config.EtherTalk.ZoneName,
UseBroadcast: false, UseBroadcast: false,
OnlyOneZone: true, OnlyOneZone: true,
NetStart: cfg.EtherTalk.NetStart, NetStart: rtr.Config.EtherTalk.NetStart,
NetEnd: cfg.EtherTalk.NetEnd, NetEnd: rtr.Config.EtherTalk.NetEnd,
ZoneName: zipkt.ZoneName, // has to match request ZoneName: zipkt.ZoneName, // has to match request
MulticastAddr: atalk.MulticastAddr(cfg.EtherTalk.ZoneName), MulticastAddr: atalk.MulticastAddr(rtr.Config.EtherTalk.ZoneName),
DefaultZoneName: cfg.EtherTalk.ZoneName, DefaultZoneName: rtr.Config.EtherTalk.ZoneName,
} }
log.Printf("ZIP: Replying with GetNetInfo-Reply: %+v", resp) log.Printf("ZIP: Replying with GetNetInfo-Reply: %+v", resp)
@ -277,8 +275,8 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
DstNet: ddpkt.SrcNet, DstNet: ddpkt.SrcNet,
DstNode: ddpkt.SrcNode, DstNode: ddpkt.SrcNode,
DstSocket: ddpkt.SrcSocket, DstSocket: ddpkt.SrcSocket,
SrcNet: myAddr.Proto.Network, SrcNet: rtr.MyDDPAddr.Network,
SrcNode: myAddr.Proto.Node, SrcNode: rtr.MyDDPAddr.Node,
SrcSocket: 6, SrcSocket: 6,
Proto: ddp.ProtoZIP, Proto: ddp.ProtoZIP,
}, },
@ -291,7 +289,7 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
outDDP.DstNode = 0xFF outDDP.DstNode = 0xFF
} }
outFrame, err := ethertalk.AppleTalk(myHWAddr, outDDP) outFrame, err := ethertalk.AppleTalk(rtr.MyHWAddr, outDDP)
if err != nil { if err != nil {
return fmt.Errorf("couldn't create EtherTalk frame: %w", err) return fmt.Errorf("couldn't create EtherTalk frame: %w", err)
} }
@ -303,7 +301,7 @@ func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAdd
if err != nil { if err != nil {
return fmt.Errorf("couldn't marshal EtherTalk frame: %w", err) return fmt.Errorf("couldn't marshal EtherTalk frame: %w", err)
} }
if err := pcapHandle.WritePacketData(outFrameRaw); err != nil { if err := rtr.PcapHandle.WritePacketData(outFrameRaw); err != nil {
return fmt.Errorf("couldn't write packet data: %w", err) return fmt.Errorf("couldn't write packet data: %w", err)
} }
return nil return nil

View file

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
*/ */
package main package router
import ( import (
"slices" "slices"