Fix BrRq-LkUp translation poisoning AARP
This commit is contained in:
parent
60d1837ee8
commit
5866f091ed
1 changed files with 48 additions and 48 deletions
|
@ -27,51 +27,6 @@ import (
|
||||||
"github.com/sfiera/multitalk/pkg/ddp"
|
"github.com/sfiera/multitalk/pkg/ddp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rtr *Router) handleNBPFwdReq(ctx context.Context, ddpkt *ddp.ExtPacket, nbpkt *nbp.Packet) error {
|
|
||||||
// A FwdReq was addressed to us. That means a remote router thinks the
|
|
||||||
// zone is available on one or more of our local networks.
|
|
||||||
|
|
||||||
// There must be 1!
|
|
||||||
tuple := &nbpkt.Tuples[0]
|
|
||||||
|
|
||||||
for _, outPort := range rtr.Ports {
|
|
||||||
if !slices.Contains(outPort.AvailableZones, tuple.Zone) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Printf("NBP: Converting FwdReq to LkUp (%v)", tuple)
|
|
||||||
|
|
||||||
// Convert it to a LkUp and broadcast on the corresponding port
|
|
||||||
nbpkt.Function = nbp.FunctionLkUp
|
|
||||||
nbpRaw, err := nbpkt.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("couldn't marshal LkUp: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inside AppleTalk SE, pp 8-20:
|
|
||||||
// "If the destination network is extended, however, the router must also
|
|
||||||
// change the destination network number to $0000, so that the packet is
|
|
||||||
// received by all nodes on the network (within the correct zone multicast
|
|
||||||
// address)."
|
|
||||||
ddpkt.DstNet = 0x0000
|
|
||||||
ddpkt.DstNode = 0xFF // Broadcast node address within the dest network
|
|
||||||
ddpkt.Data = nbpRaw
|
|
||||||
|
|
||||||
if err := outPort.ZoneMulticast(tuple.Zone, ddpkt); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// But also... if it matches us, reply directly with a LkUp-Reply of our own
|
|
||||||
outDDP, err := outPort.helloWorldThisIsMe(nbpkt.NBPID, tuple)
|
|
||||||
if err != nil || outDDP == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := rtr.Output(ctx, outDDP); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (port *EtherTalkPort) HandleNBP(ctx context.Context, ddpkt *ddp.ExtPacket) error {
|
func (port *EtherTalkPort) HandleNBP(ctx context.Context, 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)
|
||||||
|
@ -141,9 +96,9 @@ func (port *EtherTalkPort) handleNBPBrRq(ctx context.Context, ddpkt *ddp.ExtPack
|
||||||
ExtHeader: ddp.ExtHeader{
|
ExtHeader: ddp.ExtHeader{
|
||||||
Size: atalk.DDPExtHeaderSize + uint16(len(nbpRaw)),
|
Size: atalk.DDPExtHeaderSize + uint16(len(nbpRaw)),
|
||||||
Cksum: 0,
|
Cksum: 0,
|
||||||
SrcNet: ddpkt.SrcNet,
|
SrcNet: port.MyAddr.Network,
|
||||||
SrcNode: ddpkt.SrcNode,
|
SrcNode: port.MyAddr.Node,
|
||||||
SrcSocket: ddpkt.SrcSocket,
|
SrcSocket: 2,
|
||||||
DstNet: 0x0000, // Local network broadcast
|
DstNet: 0x0000, // Local network broadcast
|
||||||
DstNode: 0xFF, // Broadcast node address within the dest network
|
DstNode: 0xFF, // Broadcast node address within the dest network
|
||||||
DstSocket: 2,
|
DstSocket: 2,
|
||||||
|
@ -207,6 +162,51 @@ func (port *EtherTalkPort) handleNBPBrRq(ctx context.Context, ddpkt *ddp.ExtPack
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rtr *Router) handleNBPFwdReq(ctx context.Context, ddpkt *ddp.ExtPacket, nbpkt *nbp.Packet) error {
|
||||||
|
// A FwdReq was addressed to us. That means a remote router thinks the
|
||||||
|
// zone is available on one or more of our local networks.
|
||||||
|
|
||||||
|
// There must be 1!
|
||||||
|
tuple := &nbpkt.Tuples[0]
|
||||||
|
|
||||||
|
for _, outPort := range rtr.Ports {
|
||||||
|
if !slices.Contains(outPort.AvailableZones, tuple.Zone) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Printf("NBP: Converting FwdReq to LkUp (%v)", tuple)
|
||||||
|
|
||||||
|
// Convert it to a LkUp and broadcast on the corresponding port
|
||||||
|
nbpkt.Function = nbp.FunctionLkUp
|
||||||
|
nbpRaw, err := nbpkt.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't marshal LkUp: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inside AppleTalk SE, pp 8-20:
|
||||||
|
// "If the destination network is extended, however, the router must also
|
||||||
|
// change the destination network number to $0000, so that the packet is
|
||||||
|
// received by all nodes on the network (within the correct zone multicast
|
||||||
|
// address)."
|
||||||
|
ddpkt.DstNet = 0x0000
|
||||||
|
ddpkt.DstNode = 0xFF // Broadcast node address within the dest network
|
||||||
|
ddpkt.Data = nbpRaw
|
||||||
|
|
||||||
|
if err := outPort.ZoneMulticast(tuple.Zone, ddpkt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// But also... if it matches us, reply directly with a LkUp-Reply of our own
|
||||||
|
outDDP, err := outPort.helloWorldThisIsMe(nbpkt.NBPID, tuple)
|
||||||
|
if err != nil || outDDP == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rtr.Output(ctx, outDDP); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Returns an NBP LkUp-Reply for the router itself, with the address from this port.
|
// Returns an NBP LkUp-Reply for the router itself, with the address from this port.
|
||||||
func (port *EtherTalkPort) helloWorldThisIsMe(nbpID uint8, tuple *nbp.Tuple) (*ddp.ExtPacket, error) {
|
func (port *EtherTalkPort) helloWorldThisIsMe(nbpID uint8, tuple *nbp.Tuple) (*ddp.ExtPacket, error) {
|
||||||
if tuple.Object != "jrouter" && tuple.Object != "=" {
|
if tuple.Object != "jrouter" && tuple.Object != "=" {
|
||||||
|
|
Loading…
Reference in a new issue