use dst address as source of icmp 3.4, instead of router address

For some reason, packets injected with a src ip that isn't in the
sub-net of the dst ip get dropped.

fixes #1
This commit is contained in:
Matthias Radestock committed 2014-08-20 09:43:59 +01:00
1 parent 1ef941e77e
commit 9dd15f4abf
2 files changed
+8 -38

No files matched your search

+6 -30
View File
@@ -19,39 +19,15 @@ func (dec *EthernetDecoder) DecodeLayers(data []byte) error {
return dec.parser.DecodeLayers(data, &dec.decoded)
}
func (dec *EthernetDecoder) CheckFrameTooBigFunc(srcMac net.HardwareAddr, localAddrs []net.Addr, handle *pcap.Handle) func(error) error {
networks := make([]LocalAddress, len(localAddrs))
idx := 0
for _, addr := range localAddrs {
ip, ipnet, err := net.ParseCIDR(addr.String())
if err == nil && ip.To4() != nil {
networks[idx] = LocalAddress{ip: ip.To4(), network: ipnet}
idx++
}
}
networks = networks[:idx]
if len(networks) == 0 {
log.Fatal("Interface has no addresses assigned. Cannot continue")
}
findIP := func(ip net.IP) net.IP {
for _, la := range networks {
if la.network.Contains(ip) {
return la.ip
}
}
// can't find anything, we'll have to rely on default gateway.
return networks[0].ip
}
func (dec *EthernetDecoder) CheckFrameTooBigFunc(handle *pcap.Handle) 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
srcIP := findIP(dec.ip.SrcIP)
icmpFrame, err := dec.formICMPMTUPacket(srcMac, srcIP, ftbe.PMTU)
icmpFrame, err := dec.formICMPMTUPacket(ftbe.PMTU)
if err != nil {
return err
}
log.Println("Injecting ICMP 3,4. PMTU:", ftbe.PMTU)
log.Printf("Injecting ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, ftbe.PMTU)
return handle.WritePacketData(icmpFrame)
} else {
return err
@@ -59,7 +35,7 @@ func (dec *EthernetDecoder) CheckFrameTooBigFunc(srcMac net.HardwareAddr, localA
}
}
func (dec *EthernetDecoder) formICMPMTUPacket(srcMac net.HardwareAddr, srcIP net.IP, mtu int) ([]byte, error) {
func (dec *EthernetDecoder) formICMPMTUPacket(mtu int) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
@@ -68,7 +44,7 @@ func (dec *EthernetDecoder) formICMPMTUPacket(srcMac net.HardwareAddr, srcIP net
payload := gopacket.Payload(dec.ip.BaseLayer.Contents[:ipHeaderSize+8])
err := gopacket.SerializeLayers(buf, opts,
&layers.Ethernet{
SrcMAC: srcMac,
SrcMAC: dec.eth.DstMAC,
DstMAC: dec.eth.SrcMAC,
EthernetType: dec.eth.EthernetType},
&layers.IPv4{
@@ -80,7 +56,7 @@ func (dec *EthernetDecoder) formICMPMTUPacket(srcMac net.HardwareAddr, srcIP net
TTL: 64,
Protocol: layers.IPProtocolICMPv4,
DstIP: dec.ip.SrcIP,
SrcIP: srcIP},
SrcIP: dec.ip.DstIP},
&layers.ICMPv4{
TypeCode: 0x304,
Id: 0,
+2 -8
View File
@@ -62,11 +62,7 @@ func (router *Router) sniff(handle *pcap.Handle) {
log.Println("Sniffing traffic on", router.Iface)
dec := NewEthernetDecoder()
localAddrs, err := router.Iface.Addrs()
checkFatal(err)
checkFrameTooBig := dec.CheckFrameTooBigFunc(router.Iface.HardwareAddr, localAddrs, handle)
checkFrameTooBig := dec.CheckFrameTooBigFunc(handle)
mac := router.Iface.HardwareAddr
if router.Macs.Enter(mac, router.Ourself) {
log.Println("Discovered our MAC", mac)
@@ -198,9 +194,7 @@ func (router *Router) udpReader(conn *net.UDPConn, handle *pcap.Handle) {
}
func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, handle *pcap.Handle) FrameConsumer {
localAddrs, err := router.Iface.Addrs()
checkFatal(err)
checkFrameTooBig := dec.CheckFrameTooBigFunc(router.Iface.HardwareAddr, localAddrs, handle)
checkFrameTooBig := dec.CheckFrameTooBigFunc(handle)
return func(relayConn *LocalConnection, sender *net.UDPAddr, srcNameByte, dstNameByte []byte, frameLen uint16, frame []byte) error {
srcName := PeerNameFromBin(srcNameByte)