// Copyright 2017 The Netstack Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import (
	"encoding/binary"
	"log"

	"github.com/google/netstack/tcpip"
	"github.com/google/netstack/tcpip/buffer"
	"github.com/google/netstack/tcpip/header"
	"github.com/google/netstack/tcpip/stack"
)

const (
	ndpSolicitedFlag = 1 << 6
	ndpOverrideFlag  = 1 << 5

	ndpOptSrcLinkAddr = 1
	ndpOptDstLinkAddr = 2
)

func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) {
	v := vv.First()
	if len(v) < header.ICMPv6MinimumSize {
		return
	}
	h := header.ICMPv6(v)

	switch h.Type() {
	case header.ICMPv6NeighborSolicit:
		if len(v) < header.ICMPv6NeighborSolicitMinimumSize {
			return
		}
		targetAddr := tcpip.Address(v[8 : 8+16])
		if e.linkAddrCache.CheckLocalAddress(e.nicid, targetAddr) == 0 {
			return // we have no useful answer, ignore the request
		}
		hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize)
		pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
		pkt.SetType(header.ICMPv6NeighborAdvert)
		pkt[4] = ndpSolicitedFlag | ndpOverrideFlag
		copy(pkt[8:24], v[8:])
		pkt[24] = ndpOptDstLinkAddr
		pkt[25] = 1 // address length
		copy(pkt[26:], r.LocalLinkAddress[:])
		r.LocalAddress = targetAddr
		pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))
		r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber, r.DefaultTTL())

		e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress)

	case header.ICMPv6NeighborAdvert:
		if len(v) < header.ICMPv6NeighborAdvertSize {
			return
		}
		e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress)

	case header.ICMPv6EchoRequest:
		if len(v) < header.ICMPv6EchoMinimumSize {
			return
		}
		data := v[header.ICMPv6EchoMinimumSize:]
		hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize)
		pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
		copy(pkt, h)
		pkt.SetType(header.ICMPv6EchoReply)
		pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data))
		r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber, r.DefaultTTL())
	default:
		log.Printf("got ICMPv6: type=%v, code=%v, len(v)=%d", h.Type(), h.Code(), len(v))
	}
	// TODO case header.ICMPv6EchoReply
}

var broadcastMAC = tcpip.LinkAddress([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff})

func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
	return header.IPv6ProtocolNumber
}

func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.LinkEndpoint) *tcpip.Error {
	// Solicited-Node multicast address, used for NDP. Described in RFC 4291.
	snaddr := "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" + addr[len(addr)-3:]
	r := &stack.Route{
		LocalAddress:      localAddr,
		RemoteAddress:     snaddr,
		RemoteLinkAddress: broadcastMAC,
	}
	hdr := buffer.NewPrependable(int(linkEP.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize)
	pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
	pkt.SetType(header.ICMPv6NeighborSolicit)
	copy(pkt[8:24], addr)
	pkt[24] = ndpOptSrcLinkAddr
	pkt[25] = 1 // address length
	copy(pkt[26:], linkEP.LinkAddress())
	pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))

	length := uint16(hdr.UsedLength())
	ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
	ip.Encode(&header.IPv6Fields{
		PayloadLength: length,
		NextHeader:    uint8(header.ICMPv6ProtocolNumber),
		HopLimit:      255,
		SrcAddr:       r.LocalAddress,
		DstAddr:       r.RemoteAddress,
	})

	return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber)
}

func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 {
	// Calculate the IPv6 pseudo-header upper-layer checksum.
	xsum := header.Checksum([]byte(src), 0)
	xsum = header.Checksum([]byte(dst), xsum)
	var upperLayerLength [4]byte
	binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data)))
	xsum = header.Checksum(upperLayerLength[:], xsum)
	xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum)
	xsum = header.Checksum(data, xsum)

	h2, h3 := h[2], h[3]
	h[2], h[3] = 0, 0
	xsum = ^header.Checksum(h, xsum)
	h[2], h[3] = h2, h3

	return xsum
}
