diff --git a/go.mod b/go.mod index 0d58244f..f0769054 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 github.com/mitchellh/mapstructure v1.1.2 github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 - github.com/yggdrasil-network/water v0.0.0-20190720101301-5db94379a5eb + github.com/yggdrasil-network/water v0.0.0-20190720145626-28ccb9101d55 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 golang.org/x/net v0.0.0-20190628185345-da137c7871d7 golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 diff --git a/go.sum b/go.sum index 4335302f..c6fc16c2 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,7 @@ github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae/go.mod h1: github.com/yggdrasil-network/water v0.0.0-20190719211521-a76871ea954b/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs= github.com/yggdrasil-network/water v0.0.0-20190719213007-b160316e362e/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs= github.com/yggdrasil-network/water v0.0.0-20190720101301-5db94379a5eb/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs= +github.com/yggdrasil-network/water v0.0.0-20190720145626-28ccb9101d55/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/src/tuntap/icmpv6.go b/src/tuntap/icmpv6.go index fe80dfbd..e601acb5 100644 --- a/src/tuntap/icmpv6.go +++ b/src/tuntap/icmpv6.go @@ -78,8 +78,9 @@ func (i *ICMPv6) Init(t *TunAdapter) { // Parses an incoming ICMPv6 packet. The packet provided may be either an // ethernet frame containing an IP packet, or the IP packet alone. This is // determined by whether the TUN/TAP adapter is running in TUN (layer 3) or -// TAP (layer 2) mode. -func (i *ICMPv6) ParsePacket(datain []byte) { +// TAP (layer 2) mode. Returns an error condition which is nil if the ICMPv6 +// module handled the packet or contains the error if not. +func (i *ICMPv6) ParsePacket(datain []byte) error { var response []byte var err error @@ -91,11 +92,12 @@ func (i *ICMPv6) ParsePacket(datain []byte) { } if err != nil { - return + return err } // Write the packet to TUN/TAP i.tun.iface.Write(response) + return nil } // Unwraps the ethernet headers of an incoming ICMPv6 packet and hands off @@ -105,7 +107,7 @@ func (i *ICMPv6) ParsePacket(datain []byte) { func (i *ICMPv6) UnmarshalPacketL2(datain []byte) ([]byte, error) { // Ignore non-IPv6 frames if binary.BigEndian.Uint16(datain[12:14]) != uint16(0x86DD) { - return nil, nil + return nil, errors.New("Ignoring non-IPv6 frame") } // Hand over to ParsePacket to interpret the IPv6 packet @@ -141,12 +143,12 @@ func (i *ICMPv6) UnmarshalPacket(datain []byte, datamac *[]byte) ([]byte, error) // Check if the packet is IPv6 if ipv6Header.Version != ipv6.Version { - return nil, err + return nil, errors.New("Ignoring non-IPv6 packet") } // Check if the packet is ICMPv6 if ipv6Header.NextHeader != 58 { - return nil, err + return nil, errors.New("Ignoring non-ICMPv6 packet") } // Parse the ICMPv6 message contents diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index 4ddaf0b9..637715d6 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -111,7 +111,7 @@ func (tun *TunAdapter) writer() error { } func (tun *TunAdapter) reader() error { - recvd := make([]byte, 65535) + recvd := make([]byte, 65535+tun_ETHER_HEADER_LENGTH) for { // Wait for a packet to be delivered to us through the TUN/TAP adapter n, err := tun.iface.Read(recvd) @@ -134,17 +134,22 @@ func (tun *TunAdapter) reader() error { if len(recvd) <= offset { continue } - // If we detect an ICMP packet then hand it to the ICMPv6 module - if recvd[offset+6] == 58 { - // Found an ICMPv6 packet - b := make([]byte, n) - copy(b, recvd) - go tun.icmpv6.ParsePacket(b) - } } // Offset the buffer from now on so that we can ignore ethernet frames if // they are present - bs := recvd[offset:] + bs := recvd[offset : offset+n] + n -= offset + // If we detect an ICMP packet then hand it to the ICMPv6 module + if bs[6] == 58 { + // Found an ICMPv6 packet - we need to make sure to give ICMPv6 the full + // Ethernet frame rather than just the IPv6 packet as this is needed for + // NDP to work correctly + if err := tun.icmpv6.ParsePacket(recvd); err == nil { + // We acted on the packet in the ICMPv6 module so don't forward or do + // anything else with it + continue + } + } // From the IP header, work out what our source and destination addresses // and node IDs are. We will need these in order to work out where to send // the packet @@ -162,7 +167,7 @@ func (tun *TunAdapter) reader() error { continue } // Check the packet size - if n != 256*int(bs[4])+int(bs[5])+offset+tun_IPv6_HEADER_LENGTH { + if n-tun_IPv6_HEADER_LENGTH != 256*int(bs[4])+int(bs[5]) { continue } // IPv6 address @@ -176,7 +181,7 @@ func (tun *TunAdapter) reader() error { continue } // Check the packet size - if n != 256*int(bs[2])+int(bs[3])+offset { + if n != 256*int(bs[2])+int(bs[3]) { continue } // IPv4 address @@ -185,6 +190,7 @@ func (tun *TunAdapter) reader() error { copy(dstAddr[:addrlen], bs[16:]) } else { // Unknown address length or protocol, so drop the packet and ignore it + tun.log.Traceln("Unknown packet type, dropping") continue } if tun.ckr.isEnabled() && !tun.ckr.isValidSource(srcAddr, addrlen) { diff --git a/src/tuntap/tun_windows.go b/src/tuntap/tun_windows.go index d46b7e5b..a826c7ad 100644 --- a/src/tuntap/tun_windows.go +++ b/src/tuntap/tun_windows.go @@ -71,6 +71,9 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int // Sets the MTU of the TAP adapter. func (tun *TunAdapter) setupMTU(mtu int) error { + if tun.iface == nil || tun.iface.Name() == "" { + return errors.New("Can't configure MTU as TAP adapter is not present") + } // Set MTU cmd := exec.Command("netsh", "interface", "ipv6", "set", "subinterface", fmt.Sprintf("interface=%s", tun.iface.Name()), @@ -88,6 +91,9 @@ func (tun *TunAdapter) setupMTU(mtu int) error { // Sets the IPv6 address of the TAP adapter. func (tun *TunAdapter) setupAddress(addr string) error { + if tun.iface == nil || tun.iface.Name() == "" { + return errors.New("Can't configure IPv6 address as TAP adapter is not present") + } // Set address cmd := exec.Command("netsh", "interface", "ipv6", "add", "address", fmt.Sprintf("interface=%s", tun.iface.Name()),