|
|
@@ -5,6 +5,7 @@
|
|
|
package icmp_test
|
|
|
|
|
|
import (
|
|
|
+ "bytes"
|
|
|
"net"
|
|
|
"reflect"
|
|
|
"testing"
|
|
|
@@ -31,17 +32,19 @@ func TestMarshalAndParseMessage(t *testing.T) {
|
|
|
for _, psh := range pshs {
|
|
|
b, err := tm.Marshal(psh)
|
|
|
if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+ t.Fatalf("#%d: %v", i, err)
|
|
|
}
|
|
|
m, err := icmp.ParseMessage(proto, b)
|
|
|
if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+ t.Fatalf("#%d: %v", i, err)
|
|
|
}
|
|
|
if m.Type != tm.Type || m.Code != tm.Code {
|
|
|
t.Errorf("#%d: got %#v; want %#v", i, m, &tm)
|
|
|
+ continue
|
|
|
}
|
|
|
if !reflect.DeepEqual(m.Body, tm.Body) {
|
|
|
t.Errorf("#%d: got %#v; want %#v", i, m.Body, tm.Body)
|
|
|
+ continue
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -80,6 +83,13 @@ func TestMarshalAndParseMessage(t *testing.T) {
|
|
|
Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
|
Body: &icmp.ExtendedEchoRequest{
|
|
|
ID: 1, Seq: 2,
|
|
|
+ Extensions: []icmp.Extension{
|
|
|
+ &icmp.InterfaceIdent{
|
|
|
+ Class: 3,
|
|
|
+ Type: 1,
|
|
|
+ Name: "en101",
|
|
|
+ },
|
|
|
+ },
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
@@ -88,12 +98,6 @@ func TestMarshalAndParseMessage(t *testing.T) {
|
|
|
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) {
|
|
|
@@ -136,6 +140,13 @@ func TestMarshalAndParseMessage(t *testing.T) {
|
|
|
Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0,
|
|
|
Body: &icmp.ExtendedEchoRequest{
|
|
|
ID: 1, Seq: 2,
|
|
|
+ Extensions: []icmp.Extension{
|
|
|
+ &icmp.InterfaceIdent{
|
|
|
+ Class: 3,
|
|
|
+ Type: 2,
|
|
|
+ Index: 911,
|
|
|
+ },
|
|
|
+ },
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
@@ -144,12 +155,189 @@ func TestMarshalAndParseMessage(t *testing.T) {
|
|
|
State: 5 /* Probe */, Active: true, IPv6: true,
|
|
|
},
|
|
|
},
|
|
|
- {
|
|
|
- Type: ipv6.ICMPTypeDuplicateAddressConfirmation,
|
|
|
- Body: &icmp.DefaultMessageBody{
|
|
|
- Data: []byte{0x80, 0x40, 0x20, 0x10},
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+func TestMarshalAndParseRawMessage(t *testing.T) {
|
|
|
+ t.Run("RawBody", func(t *testing.T) {
|
|
|
+ for i, tt := range []struct {
|
|
|
+ m icmp.Message
|
|
|
+ wire []byte
|
|
|
+ parseShouldFail bool
|
|
|
+ }{
|
|
|
+ { // Nil body
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv4.ICMPTypeDestinationUnreachable, Code: 127,
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0x03, 0x7f, 0xfc, 0x80,
|
|
|
+ },
|
|
|
+ parseShouldFail: true,
|
|
|
+ },
|
|
|
+ { // Empty body
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 128,
|
|
|
+ Body: &icmp.RawBody{},
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0x01, 0x80, 0x00, 0x00,
|
|
|
+ },
|
|
|
+ parseShouldFail: true,
|
|
|
+ },
|
|
|
+ { // Crafted body
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeDuplicateAddressConfirmation, Code: 129,
|
|
|
+ Body: &icmp.RawBody{
|
|
|
+ Data: []byte{0xca, 0xfe},
|
|
|
},
|
|
|
},
|
|
|
- })
|
|
|
+ wire: []byte{
|
|
|
+ 0x9e, 0x81, 0x00, 0x00,
|
|
|
+ 0xca, 0xfe,
|
|
|
+ },
|
|
|
+ parseShouldFail: false,
|
|
|
+ },
|
|
|
+ } {
|
|
|
+ b, err := tt.m.Marshal(nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("#%d: %v", i, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if !bytes.Equal(b, tt.wire) {
|
|
|
+ t.Errorf("#%d: got %#v; want %#v", i, b, tt.wire)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ m, err := icmp.ParseMessage(tt.m.Type.Protocol(), b)
|
|
|
+ if err != nil != tt.parseShouldFail {
|
|
|
+ t.Errorf("#%d: got %v, %v", i, m, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if tt.parseShouldFail {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if m.Type != tt.m.Type || m.Code != tt.m.Code {
|
|
|
+ t.Errorf("#%d: got %v; want %v", i, m, tt.m)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if !bytes.Equal(m.Body.(*icmp.RawBody).Data, tt.m.Body.(*icmp.RawBody).Data) {
|
|
|
+ t.Errorf("#%d: got %#v; want %#v", i, m.Body, tt.m.Body)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ t.Run("RawExtension", func(t *testing.T) {
|
|
|
+ for i, tt := range []struct {
|
|
|
+ m icmp.Message
|
|
|
+ wire []byte
|
|
|
+ }{
|
|
|
+ { // Unaligned data and nil extension
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 130,
|
|
|
+ Body: &icmp.DstUnreach{
|
|
|
+ Data: []byte("ERROR-INVOKING-PACKET"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0x01, 0x82, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00,
|
|
|
+ 'E', 'R', 'R', 'O',
|
|
|
+ 'R', '-', 'I', 'N',
|
|
|
+ 'V', 'O', 'K', 'I',
|
|
|
+ 'N', 'G', '-', 'P',
|
|
|
+ 'A', 'C', 'K', 'E',
|
|
|
+ 'T',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // Unaligned data and empty extension
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeDestinationUnreachable, Code: 131,
|
|
|
+ Body: &icmp.DstUnreach{
|
|
|
+ Data: []byte("ERROR-INVOKING-PACKET"),
|
|
|
+ Extensions: []icmp.Extension{
|
|
|
+ &icmp.RawExtension{},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0x01, 0x83, 0x00, 0x00,
|
|
|
+ 0x02, 0x00, 0x00, 0x00,
|
|
|
+ 'E', 'R', 'R', 'O',
|
|
|
+ 'R', '-', 'I', 'N',
|
|
|
+ 'V', 'O', 'K', 'I',
|
|
|
+ 'N', 'G', '-', 'P',
|
|
|
+ 'A', 'C', 'K', 'E',
|
|
|
+ 'T',
|
|
|
+ 0x20, 0x00, 0xdf, 0xff,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // Nil extension
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 132,
|
|
|
+ Body: &icmp.ExtendedEchoRequest{
|
|
|
+ ID: 1, Seq: 2, Local: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0xa0, 0x84, 0x00, 0x00,
|
|
|
+ 0x00, 0x01, 0x02, 0x01,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // Empty extension
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 133,
|
|
|
+ Body: &icmp.ExtendedEchoRequest{
|
|
|
+ ID: 1, Seq: 2, Local: true,
|
|
|
+ Extensions: []icmp.Extension{
|
|
|
+ &icmp.RawExtension{},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0xa0, 0x85, 0x00, 0x00,
|
|
|
+ 0x00, 0x01, 0x02, 0x01,
|
|
|
+ 0x20, 0x00, 0xdf, 0xff,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { // Crafted extension
|
|
|
+ m: icmp.Message{
|
|
|
+ Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 134,
|
|
|
+ Body: &icmp.ExtendedEchoRequest{
|
|
|
+ ID: 1, Seq: 2, Local: true,
|
|
|
+ Extensions: []icmp.Extension{
|
|
|
+ &icmp.RawExtension{
|
|
|
+ Data: []byte("CRAFTED"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ wire: []byte{
|
|
|
+ 0xa0, 0x86, 0x00, 0x00,
|
|
|
+ 0x00, 0x01, 0x02, 0x01,
|
|
|
+ 0x20, 0x00, 0xc3, 0x21,
|
|
|
+ 'C', 'R', 'A', 'F',
|
|
|
+ 'T', 'E', 'D',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ } {
|
|
|
+ b, err := tt.m.Marshal(nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("#%d: %v", i, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if !bytes.Equal(b, tt.wire) {
|
|
|
+ t.Errorf("#%d: got %#v; want %#v", i, b, tt.wire)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ m, err := icmp.ParseMessage(tt.m.Type.Protocol(), b)
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("#%d: %v", i, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if m.Type != tt.m.Type || m.Code != tt.m.Code {
|
|
|
+ t.Errorf("#%d: got %v; want %v", i, m, tt.m)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
})
|
|
|
}
|