refactor handleZIP
This commit is contained in:
parent
faa7002c15
commit
2870bc512e
1 changed files with 68 additions and 63 deletions
131
main.go
131
main.go
|
@ -37,6 +37,7 @@ import (
|
||||||
"gitea.drjosh.dev/josh/jrouter/atalk/zip"
|
"gitea.drjosh.dev/josh/jrouter/atalk/zip"
|
||||||
"gitea.drjosh.dev/josh/jrouter/aurp"
|
"gitea.drjosh.dev/josh/jrouter/aurp"
|
||||||
"github.com/google/gopacket/pcap"
|
"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"
|
||||||
|
@ -303,69 +304,8 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 6: // The ZIS (zone information socket / ZIP socket)
|
case 6: // The ZIS (zone information socket / ZIP socket)
|
||||||
switch ddpkt.Proto {
|
if err := handleZIP(pcapHandle, ethFrame.Src, myHWAddr, myAddr, cfg, ddpkt); err != nil {
|
||||||
case 3: // ATP
|
log.Printf("ZIP: couldn't handle: %v", err)
|
||||||
log.Print("ZIP: TODO implement ATP-based ZIP requests")
|
|
||||||
continue
|
|
||||||
|
|
||||||
case 6: // ZIP
|
|
||||||
zipkt, err := zip.UnmarshalPacket(ddpkt.Data)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ZIP: invalid packet: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch zipkt := zipkt.(type) {
|
|
||||||
case *zip.GetNetInfoPacket:
|
|
||||||
// Only running a network with one zone for now.
|
|
||||||
resp := &zip.GetNetInfoReplyPacket{
|
|
||||||
ZoneInvalid: zipkt.ZoneName != cfg.EtherTalk.ZoneName,
|
|
||||||
UseBroadcast: true, // TODO: add multicast addr computation
|
|
||||||
OnlyOneZone: true,
|
|
||||||
NetStart: cfg.EtherTalk.NetStart,
|
|
||||||
NetEnd: cfg.EtherTalk.NetEnd,
|
|
||||||
ZoneName: zipkt.ZoneName, // has to match request
|
|
||||||
MulticastAddr: ethertalk.AppleTalkBroadcast,
|
|
||||||
DefaultZoneName: cfg.EtherTalk.ZoneName,
|
|
||||||
}
|
|
||||||
respRaw, err := resp.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ZIP: couldn't marshal GetNetInfoReplyPacket: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix
|
|
||||||
// "In cases where a node's provisional address is
|
|
||||||
// invalid, routers will not be able to respond to
|
|
||||||
// the node in a directed manner. An address is
|
|
||||||
// invalid if the network number is neither in the
|
|
||||||
// startup range nor in the network number range
|
|
||||||
// assigned to the node's network. In these cases,
|
|
||||||
// if the request was sent via a broadcast, the
|
|
||||||
// routers should respond with a broadcast."
|
|
||||||
ddpkt.DstNet, ddpkt.DstNode, ddpkt.DstSocket = 0x0000, 0xFF, ddpkt.SrcSocket
|
|
||||||
ddpkt.SrcNet = myAddr.Proto.Network
|
|
||||||
ddpkt.SrcNode = myAddr.Proto.Node
|
|
||||||
ddpkt.SrcSocket = 6
|
|
||||||
ddpkt.Data = respRaw
|
|
||||||
outFrame, err := ethertalk.AppleTalk(myHWAddr, *ddpkt)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ZIP: couldn't create EtherTalk frame: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
outFrame.Dst = ethFrame.Src
|
|
||||||
outFrameRaw, err := ethertalk.Marshal(*outFrame)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ZIP: couldn't marshal EtherTalk frame: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := pcapHandle.WritePacketData(outFrameRaw); err != nil {
|
|
||||||
log.Printf("ZIP: couldn't write packet data: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Printf("ZIP: invalid DDP type %d on socket 6", ddpkt.Proto)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -510,6 +450,71 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleZIP(pcapHandle *pcap.Handle, srcHWAddr, myHWAddr ethernet.Addr, myAddr aarp.AddrPair, cfg *config, ddpkt *ddp.ExtPacket) error {
|
||||||
|
switch ddpkt.Proto {
|
||||||
|
case 3: // ATP
|
||||||
|
return errors.New("TODO implement ATP-based ZIP requests")
|
||||||
|
|
||||||
|
case 6: // ZIP
|
||||||
|
zipkt, err := zip.UnmarshalPacket(ddpkt.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch zipkt := zipkt.(type) {
|
||||||
|
case *zip.GetNetInfoPacket:
|
||||||
|
// Only running a network with one zone for now.
|
||||||
|
resp := &zip.GetNetInfoReplyPacket{
|
||||||
|
ZoneInvalid: zipkt.ZoneName != cfg.EtherTalk.ZoneName,
|
||||||
|
UseBroadcast: true, // TODO: add multicast addr computation
|
||||||
|
OnlyOneZone: true,
|
||||||
|
NetStart: cfg.EtherTalk.NetStart,
|
||||||
|
NetEnd: cfg.EtherTalk.NetEnd,
|
||||||
|
ZoneName: zipkt.ZoneName, // has to match request
|
||||||
|
MulticastAddr: ethertalk.AppleTalkBroadcast,
|
||||||
|
DefaultZoneName: cfg.EtherTalk.ZoneName,
|
||||||
|
}
|
||||||
|
respRaw, err := resp.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't marshal GetNetInfoReplyPacket: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix
|
||||||
|
// "In cases where a node's provisional address is
|
||||||
|
// invalid, routers will not be able to respond to
|
||||||
|
// the node in a directed manner. An address is
|
||||||
|
// invalid if the network number is neither in the
|
||||||
|
// startup range nor in the network number range
|
||||||
|
// assigned to the node's network. In these cases,
|
||||||
|
// if the request was sent via a broadcast, the
|
||||||
|
// routers should respond with a broadcast."
|
||||||
|
ddpkt.DstNet, ddpkt.DstNode, ddpkt.DstSocket = 0x0000, 0xFF, ddpkt.SrcSocket
|
||||||
|
ddpkt.SrcNet = myAddr.Proto.Network
|
||||||
|
ddpkt.SrcNode = myAddr.Proto.Node
|
||||||
|
ddpkt.SrcSocket = 6
|
||||||
|
ddpkt.Data = respRaw
|
||||||
|
outFrame, err := ethertalk.AppleTalk(myHWAddr, *ddpkt)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't create EtherTalk frame: %w", err)
|
||||||
|
}
|
||||||
|
outFrame.Dst = srcHWAddr
|
||||||
|
outFrameRaw, err := ethertalk.Marshal(*outFrame)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't marshal EtherTalk frame: %w", err)
|
||||||
|
}
|
||||||
|
if err := pcapHandle.WritePacketData(outFrameRaw); err != nil {
|
||||||
|
return fmt.Errorf("couldn't write packet data: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("TODO: handle type %T", zipkt)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid DDP type %d on socket 6", ddpkt.Proto)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleNBPInAURP(pcapHandle *pcap.Handle, myHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) error {
|
func handleNBPInAURP(pcapHandle *pcap.Handle, myHWAddr 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)
|
||||||
|
|
Loading…
Reference in a new issue