// 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 ( "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 TestMarshalAndParseMessage(t *testing.T) { fn := func(t *testing.T, proto int, tms []icmp.Message) { var pshs [][]byte switch proto { case iana.ProtocolICMP: pshs = [][]byte{nil} case iana.ProtocolIPv6ICMP: pshs = [][]byte{ icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")), nil, } } for i, tm := range tms { for _, psh := range pshs { b, err := tm.Marshal(psh) if err != nil { t.Fatal(err) } m, err := icmp.ParseMessage(proto, b) if err != nil { t.Fatal(err) } if m.Type != tm.Type || m.Code != tm.Code { t.Errorf("#%d: got %#v; want %#v", i, m, &tm) } if !reflect.DeepEqual(m.Body, tm.Body) { t.Errorf("#%d: got %#v; want %#v", i, m.Body, tm.Body) } } } } t.Run("IPv4", func(t *testing.T) { fn(t, iana.ProtocolICMP, []icmp.Message{ { Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, Body: &icmp.DstUnreach{ Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv4.ICMPTypeTimeExceeded, Code: 1, Body: &icmp.TimeExceeded{ Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv4.ICMPTypeParameterProblem, Code: 2, Body: &icmp.ParamProb{ Pointer: 8, Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv4.ICMPTypeEcho, Code: 0, Body: &icmp.Echo{ ID: 1, Seq: 2, Data: []byte("HELLO-R-U-THERE"), }, }, { Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, Body: &icmp.ExtendedEchoRequest{ ID: 1, Seq: 2, }, }, { Type: ipv4.ICMPTypeExtendedEchoReply, Code: 0, Body: &icmp.ExtendedEchoReply{ State: 4 /* Delay */, Active: true, IPv4: true, }, }, { Type: ipv4.ICMPTypePhoturis, Body: &icmp.DefaultMessageBody{ Data: []byte{0x80, 0x40, 0x20, 0x10}, }, }, }) }) t.Run("IPv6", func(t *testing.T) { fn(t, iana.ProtocolIPv6ICMP, []icmp.Message{ { Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, Body: &icmp.DstUnreach{ Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv6.ICMPTypePacketTooBig, Code: 0, Body: &icmp.PacketTooBig{ MTU: 1<<16 - 1, Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv6.ICMPTypeTimeExceeded, Code: 1, Body: &icmp.TimeExceeded{ Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv6.ICMPTypeParameterProblem, Code: 2, Body: &icmp.ParamProb{ Pointer: 8, Data: []byte("ERROR-INVOKING-PACKET"), }, }, { Type: ipv6.ICMPTypeEchoRequest, Code: 0, Body: &icmp.Echo{ ID: 1, Seq: 2, Data: []byte("HELLO-R-U-THERE"), }, }, { Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, Body: &icmp.ExtendedEchoRequest{ ID: 1, Seq: 2, }, }, { Type: ipv6.ICMPTypeExtendedEchoReply, Code: 0, Body: &icmp.ExtendedEchoReply{ State: 5 /* Probe */, Active: true, IPv6: true, }, }, { Type: ipv6.ICMPTypeDuplicateAddressConfirmation, Body: &icmp.DefaultMessageBody{ Data: []byte{0x80, 0x40, 0x20, 0x10}, }, }, }) }) }