when forwarding frames, send icmp 3.4 packets back to the source
...instead of injecting them on the local interface. fixes #2
This commit is contained in:
1 parent
bbafba4fe8
commit
7a09d97cf5
2 files changed
+22
-15
No files matched your search
+9
-11
@@ -18,19 +18,17 @@ func (dec *EthernetDecoder) DecodeLayers(data []byte) error {
|
||||
return dec.parser.DecodeLayers(data, &dec.decoded)
|
||||
}
|
||||
|
||||
func (dec *EthernetDecoder) CheckFrameTooBigFunc(po PacketSink) func(error) error {
|
||||
return func(err error) error {
|
||||
if ftbe, ok := err.(FrameTooBigError); ok {
|
||||
// we know: 1. ip is valid, 2. it was ip and DF was set
|
||||
icmpFrame, err := dec.formICMPMTUPacket(ftbe.PMTU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Injecting ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, ftbe.PMTU)
|
||||
return po.WritePacket(icmpFrame)
|
||||
} else {
|
||||
func (dec *EthernetDecoder) CheckFrameTooBig(err error, sendFrame func([]byte) error) error {
|
||||
if ftbe, ok := err.(FrameTooBigError); ok {
|
||||
// we know: 1. ip is valid, 2. it was ip and DF was set
|
||||
icmpFrame, err := dec.formICMPMTUPacket(ftbe.PMTU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, ftbe.PMTU)
|
||||
return sendFrame(icmpFrame)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ func (router *Router) sniff(pio PacketSourceSink) {
|
||||
log.Println("Sniffing traffic on", router.Iface)
|
||||
|
||||
dec := NewEthernetDecoder()
|
||||
checkFrameTooBig := dec.CheckFrameTooBigFunc(pio)
|
||||
injectFrame := func(frame []byte) error { return pio.WritePacket(frame) }
|
||||
checkFrameTooBig := func(err error) error { return dec.CheckFrameTooBig(err, injectFrame) }
|
||||
mac := router.Iface.HardwareAddr
|
||||
if router.Macs.Enter(mac, router.Ourself) {
|
||||
log.Println("Discovered our MAC", mac)
|
||||
@@ -202,7 +203,15 @@ func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
|
||||
}
|
||||
|
||||
func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) FrameConsumer {
|
||||
checkFrameTooBig := dec.CheckFrameTooBigFunc(po)
|
||||
checkFrameTooBig := func(err error, srcPeer *Peer) error {
|
||||
if err == nil { // optimisation: avoid closure creation in common case
|
||||
return nil
|
||||
}
|
||||
return dec.CheckFrameTooBig(err,
|
||||
func(icmpFrame []byte) error {
|
||||
return router.Ourself.Forward(srcPeer, false, icmpFrame, nil)
|
||||
})
|
||||
}
|
||||
|
||||
return func(relayConn *LocalConnection, sender *net.UDPAddr, srcNameByte, dstNameByte []byte, frameLen uint16, frame []byte) error {
|
||||
srcName := PeerNameFromBin(srcNameByte)
|
||||
@@ -234,7 +243,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
} else {
|
||||
router.LogFrame("Relaying", frame, &dec.eth)
|
||||
}
|
||||
return checkFrameTooBig(router.Ourself.Relay(srcPeer, dstPeer, df, frame, dec))
|
||||
return checkFrameTooBig(router.Ourself.Relay(srcPeer, dstPeer, df, frame, dec), srcPeer)
|
||||
}
|
||||
|
||||
if relayConn.Remote().Name == srcPeer.Name {
|
||||
@@ -268,7 +277,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
dstPeer, found = router.Macs.Lookup(dec.eth.DstMAC)
|
||||
if !found || dec.BroadcastFrame() || dstPeer != router.Ourself {
|
||||
df := decodedLen == 2 && (dec.ip.Flags&layers.IPv4DontFragment != 0)
|
||||
checkFrameTooBig(router.Ourself.RelayBroadcast(srcPeer, df, frame, dec))
|
||||
checkFrameTooBig(router.Ourself.RelayBroadcast(srcPeer, df, frame, dec), srcPeer)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user