mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Fix checksums and packet buffers, sends ICMPv6 Packet Too Big messages successfully now
This commit is contained in:
		
							parent
							
								
									37e4492b86
								
							
						
					
					
						commit
						1c59338f01
					
				
					 2 changed files with 21 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue