mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Send ICMPv6 response to packets larger than session MTU (WIP: checksum wrong?)
This commit is contained in:
		
							parent
							
								
									a3a9696880
								
							
						
					
					
						commit
						37e4492b86
					
				
					 2 changed files with 32 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -129,7 +129,8 @@ func (i *icmpv6) parse_packet_tun(datain []byte) ([]byte, error) {
 | 
			
		|||
			response, err := i.handle_ndp(datain[ipv6.HeaderLen:])
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				// Create our ICMPv6 response
 | 
			
		||||
				responsePacket, err := i.create_icmpv6_tun(ipv6Header.Src, ipv6.ICMPTypeNeighborAdvertisement, 0, response)
 | 
			
		||||
				responsePacket, err := i.create_icmpv6_tun(ipv6Header.Src, ipv6.ICMPTypeNeighborAdvertisement, 0,
 | 
			
		||||
					&icmp.DefaultMessageBody{ Data: response })
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +149,7 @@ func (i *icmpv6) parse_packet_tun(datain []byte) ([]byte, error) {
 | 
			
		|||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICMPType, mcode int, mbody []byte) ([]byte, error) {
 | 
			
		||||
func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICMPType, mcode int, mbody icmp.MessageBody) ([]byte, error) {
 | 
			
		||||
	// Pass through to create_icmpv6_tun
 | 
			
		||||
	ipv6packet, err := i.create_icmpv6_tun(dst, mtype, mcode, mbody)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +157,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+len(mbody))
 | 
			
		||||
	dataout := make([]byte, ETHER+ipv6.HeaderLen+mbody.Len(0))
 | 
			
		||||
 | 
			
		||||
	// Populate the response ethernet headers
 | 
			
		||||
	copy(dataout[:6], dstmac[:6])
 | 
			
		||||
| 
						 | 
				
			
			@ -168,12 +169,12 @@ func (i *icmpv6) create_icmpv6_tap(dstmac macAddress, dst net.IP, mtype ipv6.ICM
 | 
			
		|||
	return dataout, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (i *icmpv6) create_icmpv6_tun(dst net.IP, mtype ipv6.ICMPType, mcode int, mbody []byte) ([]byte, error) {
 | 
			
		||||
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: len(mbody),
 | 
			
		||||
		PayloadLen: mbody.Len(0),
 | 
			
		||||
		HopLimit:   255,
 | 
			
		||||
		Src:        i.mylladdr,
 | 
			
		||||
		Dst:        dst,
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +184,7 @@ func (i *icmpv6) create_icmpv6_tun(dst net.IP, mtype ipv6.ICMPType, mcode int, m
 | 
			
		|||
	icmpMessage := icmp.Message{
 | 
			
		||||
		Type: mtype,
 | 
			
		||||
		Code: mcode,
 | 
			
		||||
		Body: &icmp.DefaultMessageBody{Data: mbody},
 | 
			
		||||
		Body: mbody,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Convert the IPv6 header into []byte
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,8 @@ package yggdrasil
 | 
			
		|||
//  The router then runs some sanity checks before passing it to the tun
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
import "golang.org/x/net/icmp"
 | 
			
		||||
import "golang.org/x/net/ipv6"
 | 
			
		||||
 | 
			
		||||
//import "fmt"
 | 
			
		||||
//import "net"
 | 
			
		||||
| 
						 | 
				
			
			@ -145,9 +147,31 @@ func (r *router) sendPacket(bs []byte) {
 | 
			
		|||
		fallthrough
 | 
			
		||||
	//default: go func() { sinfo.send<-bs }()
 | 
			
		||||
	default:
 | 
			
		||||
		// Generate an ICMPv6 Packet Too Big for packets larger than session MTU
 | 
			
		||||
		if len(bs) > int(sinfo.getMTU()) {
 | 
			
		||||
			// TODO: Send ICMPv6 Packet Too Big back to the TUN/TAP adapter
 | 
			
		||||
			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 {
 | 
			
		||||
				window = int(sinfo.getMTU())
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Create the Packet Too Big response
 | 
			
		||||
			ptb := &icmp.PacketTooBig{
 | 
			
		||||
				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
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Don't continue - drop the packet
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		select {
 | 
			
		||||
		case sinfo.send <- bs:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue