// Copyright 2014 The Go 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 icmp_test

import (
	"errors"
	"fmt"
	"net"
	"os"
	"runtime"
	"testing"
	"time"

	"golang.org/x/net/icmp"
	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/nettest"
	"golang.org/x/net/ipv4"
	"golang.org/x/net/ipv6"
)

func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) {
	const host = "www.google.com"
	ips, err := net.LookupIP(host)
	if err != nil {
		return nil, err
	}
	netaddr := func(ip net.IP) (net.Addr, error) {
		switch c.LocalAddr().(type) {
		case *net.UDPAddr:
			return &net.UDPAddr{IP: ip}, nil
		case *net.IPAddr:
			return &net.IPAddr{IP: ip}, nil
		default:
			return nil, errors.New("neither UDPAddr nor IPAddr")
		}
	}
	for _, ip := range ips {
		switch protocol {
		case iana.ProtocolICMP:
			if ip.To4() != nil {
				return netaddr(ip)
			}
		case iana.ProtocolIPv6ICMP:
			if ip.To16() != nil && ip.To4() == nil {
				return netaddr(ip)
			}
		}
	}
	return nil, errors.New("no A or AAAA record")
}

type pingTest struct {
	network, address string
	protocol         int
	mtype            icmp.Type
}

var nonPrivilegedPingTests = []pingTest{
	{"udp4", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},

	{"udp6", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
}

func TestNonPrivilegedPing(t *testing.T) {
	if testing.Short() {
		t.Skip("avoid external network")
	}
	switch runtime.GOOS {
	case "darwin":
	case "linux":
		t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state")
	default:
		t.Skipf("not supported on %s", runtime.GOOS)
	}

	for i, tt := range nonPrivilegedPingTests {
		if err := doPing(tt, i); err != nil {
			t.Error(err)
		}
	}
}

var privilegedPingTests = []pingTest{
	{"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},

	{"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
}

func TestPrivilegedPing(t *testing.T) {
	if testing.Short() {
		t.Skip("avoid external network")
	}
	if m, ok := nettest.SupportsRawIPSocket(); !ok {
		t.Skip(m)
	}

	for i, tt := range privilegedPingTests {
		if err := doPing(tt, i); err != nil {
			t.Error(err)
		}
	}
}

func doPing(tt pingTest, seq int) error {
	c, err := icmp.ListenPacket(tt.network, tt.address)
	if err != nil {
		return err
	}
	defer c.Close()

	dst, err := googleAddr(c, tt.protocol)
	if err != nil {
		return err
	}

	if tt.network != "udp6" && tt.protocol == iana.ProtocolIPv6ICMP {
		var f ipv6.ICMPFilter
		f.SetAll(true)
		f.Accept(ipv6.ICMPTypeDestinationUnreachable)
		f.Accept(ipv6.ICMPTypePacketTooBig)
		f.Accept(ipv6.ICMPTypeTimeExceeded)
		f.Accept(ipv6.ICMPTypeParameterProblem)
		f.Accept(ipv6.ICMPTypeEchoReply)
		if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil {
			return err
		}
	}

	wm := icmp.Message{
		Type: tt.mtype, Code: 0,
		Body: &icmp.Echo{
			ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq),
			Data: []byte("HELLO-R-U-THERE"),
		},
	}
	wb, err := wm.Marshal(nil)
	if err != nil {
		return err
	}
	if n, err := c.WriteTo(wb, dst); err != nil {
		return err
	} else if n != len(wb) {
		return fmt.Errorf("got %v; want %v", n, len(wb))
	}

	rb := make([]byte, 1500)
	if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
		return err
	}
	n, peer, err := c.ReadFrom(rb)
	if err != nil {
		return err
	}
	rm, err := icmp.ParseMessage(tt.protocol, rb[:n])
	if err != nil {
		return err
	}
	switch rm.Type {
	case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply:
		return nil
	default:
		return fmt.Errorf("got %+v from %v; want echo reply", rm, peer)
	}
}
