// Copyright 2015 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"
	"reflect"
	"testing"

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

func TestMarshalAndParseMultipartMessage(t *testing.T) {
	fn := func(t *testing.T, proto int, tm icmp.Message) error {
		b, err := tm.Marshal(nil)
		if err != nil {
			return err
		}
		switch tm.Type {
		case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
		default:
			switch proto {
			case iana.ProtocolICMP:
				if b[5] != 32 {
					return fmt.Errorf("got %d; want 32", b[5])
				}
			case iana.ProtocolIPv6ICMP:
				if b[4] != 16 {
					return fmt.Errorf("got %d; want 16", b[4])
				}
			default:
				return fmt.Errorf("unknown protocol: %d", proto)
			}
		}
		m, err := icmp.ParseMessage(proto, b)
		if err != nil {
			return err
		}
		if m.Type != tm.Type || m.Code != tm.Code {
			return fmt.Errorf("got %v; want %v", m, &tm)
		}
		switch m.Type {
		case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:
			got, want := m.Body.(*icmp.ExtendedEchoRequest), tm.Body.(*icmp.ExtendedEchoRequest)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
		case ipv4.ICMPTypeDestinationUnreachable:
			got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
			if len(got.Data) != 128 {
				return fmt.Errorf("got %d; want 128", len(got.Data))
			}
		case ipv4.ICMPTypeTimeExceeded:
			got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
			if len(got.Data) != 128 {
				return fmt.Errorf("got %d; want 128", len(got.Data))
			}
		case ipv4.ICMPTypeParameterProblem:
			got, want := m.Body.(*icmp.ParamProb), tm.Body.(*icmp.ParamProb)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
			if len(got.Data) != 128 {
				return fmt.Errorf("got %d; want 128", len(got.Data))
			}
		case ipv6.ICMPTypeDestinationUnreachable:
			got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
			if len(got.Data) != 128 {
				return fmt.Errorf("got %d; want 128", len(got.Data))
			}
		case ipv6.ICMPTypeTimeExceeded:
			got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded)
			if !reflect.DeepEqual(got.Extensions, want.Extensions) {
				return errors.New(dumpExtensions(got.Extensions, want.Extensions))
			}
			if len(got.Data) != 128 {
				return fmt.Errorf("got %d; want 128", len(got.Data))
			}
		default:
			return fmt.Errorf("unknown message type: %v", m.Type)
		}
		return nil
	}

	t.Run("IPv4", func(t *testing.T) {
		for i, tm := range []icmp.Message{
			{
				Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15,
				Body: &icmp.DstUnreach{
					Data: []byte("ERROR-INVOKING-PACKET"),
					Extensions: []icmp.Extension{
						&icmp.MPLSLabelStack{
							Class: 1,
							Type:  1,
							Labels: []icmp.MPLSLabel{
								{
									Label: 16014,
									TC:    0x4,
									S:     true,
									TTL:   255,
								},
							},
						},
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x0f,
							Interface: &net.Interface{
								Index: 15,
								Name:  "en101",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP: net.IPv4(192, 168, 0, 1).To4(),
							},
						},
					},
				},
			},
			{
				Type: ipv4.ICMPTypeTimeExceeded, Code: 1,
				Body: &icmp.TimeExceeded{
					Data: []byte("ERROR-INVOKING-PACKET"),
					Extensions: []icmp.Extension{
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x0f,
							Interface: &net.Interface{
								Index: 15,
								Name:  "en101",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP: net.IPv4(192, 168, 0, 1).To4(),
							},
						},
						&icmp.MPLSLabelStack{
							Class: 1,
							Type:  1,
							Labels: []icmp.MPLSLabel{
								{
									Label: 16014,
									TC:    0x4,
									S:     true,
									TTL:   255,
								},
							},
						},
					},
				},
			},
			{
				Type: ipv4.ICMPTypeParameterProblem, Code: 2,
				Body: &icmp.ParamProb{
					Pointer: 8,
					Data:    []byte("ERROR-INVOKING-PACKET"),
					Extensions: []icmp.Extension{
						&icmp.MPLSLabelStack{
							Class: 1,
							Type:  1,
							Labels: []icmp.MPLSLabel{
								{
									Label: 16014,
									TC:    0x4,
									S:     true,
									TTL:   255,
								},
							},
						},
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x0f,
							Interface: &net.Interface{
								Index: 15,
								Name:  "en101",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP: net.IPv4(192, 168, 0, 1).To4(),
							},
						},
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x2f,
							Interface: &net.Interface{
								Index: 16,
								Name:  "en102",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP: net.IPv4(192, 168, 0, 2).To4(),
							},
						},
					},
				},
			},
			{
				Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2, Local: true,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  1,
							Name:  "en101",
						},
					},
				},
			},
			{
				Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2, Local: true,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  2,
							Index: 911,
						},
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  1,
							Name:  "en101",
						},
					},
				},
			},
			{
				Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  3,
							AFI:   iana.AddrFamily48bitMAC,
							Addr:  []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab},
						},
					},
				},
			},
		} {
			if err := fn(t, iana.ProtocolICMP, tm); err != nil {
				t.Errorf("#%d: %v", i, err)
			}
		}
	})
	t.Run("IPv6", func(t *testing.T) {
		for i, tm := range []icmp.Message{
			{
				Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6,
				Body: &icmp.DstUnreach{
					Data: []byte("ERROR-INVOKING-PACKET"),
					Extensions: []icmp.Extension{
						&icmp.MPLSLabelStack{
							Class: 1,
							Type:  1,
							Labels: []icmp.MPLSLabel{
								{
									Label: 16014,
									TC:    0x4,
									S:     true,
									TTL:   255,
								},
							},
						},
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x0f,
							Interface: &net.Interface{
								Index: 15,
								Name:  "en101",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP:   net.ParseIP("fe80::1"),
								Zone: "en101",
							},
						},
					},
				},
			},
			{
				Type: ipv6.ICMPTypeTimeExceeded, Code: 1,
				Body: &icmp.TimeExceeded{
					Data: []byte("ERROR-INVOKING-PACKET"),
					Extensions: []icmp.Extension{
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x0f,
							Interface: &net.Interface{
								Index: 15,
								Name:  "en101",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP:   net.ParseIP("fe80::1"),
								Zone: "en101",
							},
						},
						&icmp.MPLSLabelStack{
							Class: 1,
							Type:  1,
							Labels: []icmp.MPLSLabel{
								{
									Label: 16014,
									TC:    0x4,
									S:     true,
									TTL:   255,
								},
							},
						},
						&icmp.InterfaceInfo{
							Class: 2,
							Type:  0x2f,
							Interface: &net.Interface{
								Index: 16,
								Name:  "en102",
								MTU:   8192,
							},
							Addr: &net.IPAddr{
								IP:   net.ParseIP("fe80::1"),
								Zone: "en102",
							},
						},
					},
				},
			},
			{
				Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2, Local: true,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  1,
							Name:  "en101",
						},
					},
				},
			},
			{
				Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2, Local: true,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  1,
							Name:  "en101",
						},
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  2,
							Index: 911,
						},
					},
				},
			},
			{
				Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
				Body: &icmp.ExtendedEchoRequest{
					ID: 1, Seq: 2,
					Extensions: []icmp.Extension{
						&icmp.InterfaceIdent{
							Class: 3,
							Type:  3,
							AFI:   iana.AddrFamilyIPv4,
							Addr:  []byte{192, 0, 2, 1},
						},
					},
				},
			},
		} {
			if err := fn(t, iana.ProtocolIPv6ICMP, tm); err != nil {
				t.Errorf("#%d: %v", i, err)
			}
		}
	})
}

func dumpExtensions(gotExts, wantExts []icmp.Extension) string {
	var s string
	for i, got := range gotExts {
		switch got := got.(type) {
		case *icmp.MPLSLabelStack:
			want := wantExts[i].(*icmp.MPLSLabelStack)
			if !reflect.DeepEqual(got, want) {
				s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
			}
		case *icmp.InterfaceInfo:
			want := wantExts[i].(*icmp.InterfaceInfo)
			if !reflect.DeepEqual(got, want) {
				s += fmt.Sprintf("#%d: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, got, got.Interface, got.Addr, want, want.Interface, want.Addr)
			}
		case *icmp.InterfaceIdent:
			want := wantExts[i].(*icmp.InterfaceIdent)
			if !reflect.DeepEqual(got, want) {
				s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want)
			}
		}
	}
	if len(s) == 0 {
		return "<nil>"
	}
	return s[:len(s)-1]
}

func TestMultipartMessageBodyLen(t *testing.T) {
	for i, tt := range []struct {
		proto int
		in    icmp.MessageBody
		out   int
	}{
		{
			iana.ProtocolICMP,
			&icmp.DstUnreach{
				Data: make([]byte, ipv4.HeaderLen),
			},
			4 + ipv4.HeaderLen, // unused and original datagram
		},
		{
			iana.ProtocolICMP,
			&icmp.TimeExceeded{
				Data: make([]byte, ipv4.HeaderLen),
			},
			4 + ipv4.HeaderLen, // unused and original datagram
		},
		{
			iana.ProtocolICMP,
			&icmp.ParamProb{
				Data: make([]byte, ipv4.HeaderLen),
			},
			4 + ipv4.HeaderLen, // [pointer, unused] and original datagram
		},

		{
			iana.ProtocolICMP,
			&icmp.ParamProb{
				Data: make([]byte, ipv4.HeaderLen),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram
		},
		{
			iana.ProtocolICMP,
			&icmp.ParamProb{
				Data: make([]byte, 128),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram
		},
		{
			iana.ProtocolICMP,
			&icmp.ParamProb{
				Data: make([]byte, 129),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram
		},

		{
			iana.ProtocolIPv6ICMP,
			&icmp.DstUnreach{
				Data: make([]byte, ipv6.HeaderLen),
			},
			4 + ipv6.HeaderLen, // unused and original datagram
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.PacketTooBig{
				Data: make([]byte, ipv6.HeaderLen),
			},
			4 + ipv6.HeaderLen, // mtu and original datagram
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.TimeExceeded{
				Data: make([]byte, ipv6.HeaderLen),
			},
			4 + ipv6.HeaderLen, // unused and original datagram
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.ParamProb{
				Data: make([]byte, ipv6.HeaderLen),
			},
			4 + ipv6.HeaderLen, // pointer and original datagram
		},

		{
			iana.ProtocolIPv6ICMP,
			&icmp.DstUnreach{
				Data: make([]byte, 127),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.DstUnreach{
				Data: make([]byte, 128),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.DstUnreach{
				Data: make([]byte, 129),
				Extensions: []icmp.Extension{
					&icmp.MPLSLabelStack{},
				},
			},
			4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram
		},

		{
			iana.ProtocolICMP,
			&icmp.ExtendedEchoRequest{},
			4, // [id, seq, l-bit]
		},
		{
			iana.ProtocolICMP,
			&icmp.ExtendedEchoRequest{
				Extensions: []icmp.Extension{
					&icmp.InterfaceIdent{},
				},
			},
			4 + 4 + 4, // [id, seq, l-bit], extension header, object header
		},
		{
			iana.ProtocolIPv6ICMP,
			&icmp.ExtendedEchoRequest{
				Extensions: []icmp.Extension{
					&icmp.InterfaceIdent{
						Type: 3,
						AFI:  iana.AddrFamilyNSAP,
						Addr: []byte{0x49, 0x00, 0x01, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0x00},
					},
				},
			},
			4 + 4 + 4 + 16, // [id, seq, l-bit], extension header, object header, object payload
		},
	} {
		if out := tt.in.Len(tt.proto); out != tt.out {
			t.Errorf("#%d: got %d; want %d", i, out, tt.out)
		}
	}
}
