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:
1 parent
1ef941e77e
commit
9dd15f4abf
2 files changed
+8
-38
No files matched your search
+6
-30
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user