Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
use dst address as source of icmp 3.4, instead of router address
Browse files Browse the repository at this point in the history
For some reason, packets injected with a src ip that isn't in the
sub-net of the dst ip get dropped.

fixes #1
  • Loading branch information
rade committed Aug 20, 2014
1 parent 1ef941e commit 9dd15f4
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 38 deletions.
36 changes: 6 additions & 30 deletions ethernet_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,47 +19,23 @@ 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
}
}
}

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,
Expand All @@ -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{
Expand All @@ -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,
Expand Down
10 changes: 2 additions & 8 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 9dd15f4

Please sign in to comment.