From 1c59338f01c89b9bdd823602f2ee1c861d1579e8 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 15 Feb 2018 13:38:54 +0000 Subject: [PATCH] Fix checksums and packet buffers, sends ICMPv6 Packet Too Big messages successfully now --- src/yggdrasil/icmpv6.go | 42 ++++++++++++++++++++--------------------- src/yggdrasil/router.go | 5 +---- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/yggdrasil/icmpv6.go b/src/yggdrasil/icmpv6.go index 85a6bbb..da62111 100644 --- a/src/yggdrasil/icmpv6.go +++ b/src/yggdrasil/icmpv6.go @@ -8,6 +8,7 @@ import "net" import "golang.org/x/net/ipv6" import "golang.org/x/net/icmp" import "encoding/binary" +import "errors" type macAddress [6]byte @@ -130,14 +131,11 @@ func (i *icmpv6) parse_packet_tun(datain []byte) ([]byte, error) { if err == nil { // Create our ICMPv6 response responsePacket, err := i.create_icmpv6_tun(ipv6Header.Src, ipv6.ICMPTypeNeighborAdvertisement, 0, - &icmp.DefaultMessageBody{ Data: response }) + &icmp.DefaultMessageBody{Data: response}) if err != nil { return nil, err } - // Fix the checksum because I don't even know why, net/icmp is stupid - responsePacket[17] ^= 0x4 - // Send it back return responsePacket, nil } else { @@ -146,7 +144,7 @@ func (i *icmpv6) parse_packet_tun(datain []byte) ([]byte, error) { } } - return nil, nil + return nil, errors.New("ICMPv6 type not matched") } func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICMPType, mcode int, mbody icmp.MessageBody) ([]byte, error) { @@ -157,7 +155,7 @@ func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICM } // Create the response buffer - dataout := make([]byte, ETHER+ipv6.HeaderLen+mbody.Len(0)) + dataout := make([]byte, ETHER+len(ipv6packet)) // Populate the response ethernet headers copy(dataout[:6], dstmac[:6]) @@ -170,16 +168,6 @@ func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICM } func (i *icmpv6) create_icmpv6_tun(dst net.IP, mtype ipv6.ICMPType, mcode int, mbody icmp.MessageBody) ([]byte, error) { - // Create the IPv6 header - ipv6Header := ipv6.Header{ - Version: ipv6.Version, - NextHeader: 58, - PayloadLen: mbody.Len(0), - HopLimit: 255, - Src: i.mylladdr, - Dst: dst, - } - // Create the ICMPv6 message icmpMessage := icmp.Message{ Type: mtype, @@ -187,14 +175,24 @@ func (i *icmpv6) create_icmpv6_tun(dst net.IP, mtype ipv6.ICMPType, mcode int, m Body: mbody, } - // Convert the IPv6 header into []byte - ipv6HeaderBuf, err := ipv6Header_Marshal(&ipv6Header) + // Convert the ICMPv6 message into []byte + icmpMessageBuf, err := icmpMessage.Marshal(icmp.IPv6PseudoHeader(i.mylladdr, dst)) if err != nil { return nil, err } - // Convert the ICMPv6 message into []byte - icmpMessageBuf, err := icmpMessage.Marshal(icmp.IPv6PseudoHeader(ipv6Header.Dst, ipv6Header.Src)) + // Create the IPv6 header + ipv6Header := ipv6.Header{ + Version: ipv6.Version, + NextHeader: 58, + PayloadLen: len(icmpMessageBuf), + HopLimit: 255, + Src: i.mylladdr, + Dst: dst, + } + + // Convert the IPv6 header into []byte + ipv6HeaderBuf, err := ipv6Header_Marshal(&ipv6Header) if err != nil { return nil, err } @@ -211,11 +209,11 @@ func (i *icmpv6) create_icmpv6_tun(dst net.IP, mtype ipv6.ICMPType, mcode int, m func (i *icmpv6) handle_ndp(in []byte) ([]byte, error) { // Ignore NDP requests for anything outside of fd00::/8 if in[8] != 0xFD { - return nil, nil + return nil, errors.New("Not an NDP for fd00::/8") } // Create our NDP message body response - body := make([]byte, 32) + body := make([]byte, 28) binary.BigEndian.PutUint32(body[:4], uint32(0x20000000)) copy(body[4:20], in[8:24]) // Target address body[20] = uint8(2) diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index abd51c4..8ca5d2b 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -149,8 +149,6 @@ func (r *router) sendPacket(bs []byte) { default: // Generate an ICMPv6 Packet Too Big for packets larger than session MTU if len(bs) > int(sinfo.getMTU()) { - sinfo.core.log.Printf("Packet length %d exceeds session MTU %d", len(bs), sinfo.getMTU()) - // Get the size of the oversized payload, up to a max of 900 bytes window := 900 if int(sinfo.getMTU()) < window { @@ -159,14 +157,13 @@ func (r *router) sendPacket(bs []byte) { // Create the Packet Too Big response ptb := &icmp.PacketTooBig{ - MTU: int(sinfo.getMTU()), + MTU: int(sinfo.getMTU()), Data: bs[:window], } // Create the ICMPv6 response from it icmpv6Buf, err := r.core.tun.icmpv6.create_icmpv6_tun(bs[8:24], ipv6.ICMPTypePacketTooBig, 0, ptb) if err == nil { - sinfo.core.log.Printf("Sending ICMPv6 Message Too Big") r.recv <- icmpv6Buf }