5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-22 10:40:27 +00:00

Fix checksums and packet buffers, sends ICMPv6 Packet Too Big messages successfully now

This commit is contained in:
Neil Alexander 2018-02-15 13:38:54 +00:00
parent 37e4492b86
commit 1c59338f01
2 changed files with 21 additions and 26 deletions

View File

@ -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)

View File

@ -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
}