summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact/tests
diff options
context:
space:
mode:
authorSam Balana <sbalana@google.com>2021-05-26 14:14:07 -0700
committergVisor bot <gvisor-bot@google.com>2021-05-26 14:16:40 -0700
commit522ae2dd1f3c0d5aea52a9883cc1319e3b1ebce4 (patch)
treed0f6681e6e6d2fd500e04360c225c6d2af198d04 /test/packetimpact/tests
parentb6f9158424c9f5b8a141e468e22fd12bc4dfc447 (diff)
Specify subsequent layers as ICMP payloads and add ICMPv6.Pointer
Moves specification of subsequent layers to the Payload field of the ICMP and ICMPv6 layers. Removes the need to manually encode type-specific ICMP or ICMPv6 headers, such as the "pointer" header of parameter problem messages, in the payload. This is necessary prework to enable matching of more type-specific headers, such as "ident" of echo requests. Fixes a bug where the "reserved" header defined by ICMPv6 RFC 4443 was being incorrectly encoded by ToBytes. This change fixes the implementation by copying the payload into Payload, instead of the MessageBody. PiperOrigin-RevId: 376026420
Diffstat (limited to 'test/packetimpact/tests')
-rw-r--r--test/packetimpact/tests/icmpv6_param_problem_test.go7
-rw-r--r--test/packetimpact/tests/ipv6_unknown_options_action_test.go20
-rw-r--r--test/packetimpact/tests/tcp_connect_icmp_error_test.go19
-rw-r--r--test/packetimpact/tests/tcp_network_unreachable_test.go57
-rw-r--r--test/packetimpact/tests/udp_icmp_error_propagation_test.go29
5 files changed, 60 insertions, 72 deletions
diff --git a/test/packetimpact/tests/icmpv6_param_problem_test.go b/test/packetimpact/tests/icmpv6_param_problem_test.go
index 1beccb6cf..fdabcf1ad 100644
--- a/test/packetimpact/tests/icmpv6_param_problem_test.go
+++ b/test/packetimpact/tests/icmpv6_param_problem_test.go
@@ -15,7 +15,6 @@
package icmpv6_param_problem_test
import (
- "encoding/binary"
"flag"
"testing"
"time"
@@ -56,13 +55,11 @@ func TestICMPv6ParamProblemTest(t *testing.T) {
t.Fatalf("can't convert %s to bytes: %s", ipv6Sent, err)
}
- // The problematic field is the NextHeader.
- b := make([]byte, 4)
- binary.BigEndian.PutUint32(b, header.IPv6NextHeaderOffset)
- expectedPayload = append(b, expectedPayload...)
expectedICMPv6 := testbench.ICMPv6{
Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
Payload: expectedPayload,
+ // The problematic field is the NextHeader.
+ Pointer: testbench.Uint32(header.IPv6NextHeaderOffset),
}
paramProblem := testbench.Layers{
diff --git a/test/packetimpact/tests/ipv6_unknown_options_action_test.go b/test/packetimpact/tests/ipv6_unknown_options_action_test.go
index f999d13d2..d762c43a7 100644
--- a/test/packetimpact/tests/ipv6_unknown_options_action_test.go
+++ b/test/packetimpact/tests/ipv6_unknown_options_action_test.go
@@ -15,7 +15,6 @@
package ipv6_unknown_options_action_test
import (
- "encoding/binary"
"flag"
"net"
"testing"
@@ -154,23 +153,22 @@ func TestIPv6UnknownOptionAction(t *testing.T) {
outgoing := conn.CreateFrame(t, outgoingOverride, tt.mkExtHdr(optionTypeFromAction(tt.action)))
conn.SendFrame(t, outgoing)
ipv6Sent := outgoing[1:]
- invokingPacket, err := ipv6Sent.ToBytes()
+ icmpv6Payload, err := ipv6Sent.ToBytes()
if err != nil {
t.Fatalf("failed to serialize the outgoing packet: %s", err)
}
- icmpv6Payload := make([]byte, 4)
- // The pointer in the ICMPv6 parameter problem message should point to
- // the option type of the unknown option. In our test case, it is the
- // first option in the extension header whose option type is 2 bytes
- // after the IPv6 header (after NextHeader and ExtHdrLen).
- binary.BigEndian.PutUint32(icmpv6Payload, header.IPv6MinimumSize+2)
- icmpv6Payload = append(icmpv6Payload, invokingPacket...)
gotICMPv6, err := conn.ExpectFrame(t, testbench.Layers{
&testbench.Ether{},
&testbench.IPv6{},
&testbench.ICMPv6{
- Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
- Code: testbench.ICMPv6Code(header.ICMPv6UnknownOption),
+ Type: testbench.ICMPv6Type(header.ICMPv6ParamProblem),
+ Code: testbench.ICMPv6Code(header.ICMPv6UnknownOption),
+ // The pointer in the ICMPv6 parameter problem message
+ // should point to the option type of the unknown option. In
+ // our test case, it is the first option in the extension
+ // header whose option type is 2 bytes after the IPv6 header
+ // (after NextHeader and ExtHdrLen).
+ Pointer: testbench.Uint32(header.IPv6MinimumSize + 2),
Payload: icmpv6Payload,
},
}, time.Second)
diff --git a/test/packetimpact/tests/tcp_connect_icmp_error_test.go b/test/packetimpact/tests/tcp_connect_icmp_error_test.go
index 79bfe9eb7..3b4c4cd63 100644
--- a/test/packetimpact/tests/tcp_connect_icmp_error_test.go
+++ b/test/packetimpact/tests/tcp_connect_icmp_error_test.go
@@ -33,17 +33,18 @@ func init() {
func sendICMPError(t *testing.T, conn *testbench.TCPIPv4, tcp *testbench.TCP) {
t.Helper()
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- ip, ok := tcp.Prev().(*testbench.IPv4)
- if !ok {
- t.Fatalf("expected %s to be IPv4", tcp.Prev())
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- icmpErr := &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable)}
- layers = append(layers, icmpErr, ip, tcp)
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv4{
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ Payload: bytes,
+ }
conn.SendFrameStateless(t, layers)
}
diff --git a/test/packetimpact/tests/tcp_network_unreachable_test.go b/test/packetimpact/tests/tcp_network_unreachable_test.go
index 5168450ad..60a2dbf3d 100644
--- a/test/packetimpact/tests/tcp_network_unreachable_test.go
+++ b/test/packetimpact/tests/tcp_network_unreachable_test.go
@@ -50,30 +50,24 @@ func TestTCPSynSentUnreachable(t *testing.T) {
}
// Get the SYN.
- tcpLayers, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, nil, time.Second)
+ tcp, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, time.Second)
if err != nil {
t.Fatalf("expected SYN: %s", err)
}
// Send a host unreachable message.
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- const ipLayer = 1
- const tcpLayer = ipLayer + 1
- ip, ok := tcpLayers[ipLayer].(*testbench.IPv4)
- if !ok {
- t.Fatalf("expected %s to be IPv4", tcpLayers[ipLayer])
- }
- tcp, ok := tcpLayers[tcpLayer].(*testbench.TCP)
- if !ok {
- t.Fatalf("expected %s to be TCP", tcpLayers[tcpLayer])
- }
- var icmpv4 testbench.ICMPv4 = testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- layers = append(layers, &icmpv4, ip, tcp)
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv4{
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4HostUnreachable),
+ Payload: bytes,
+ }
conn.SendFrameStateless(t, layers)
if err := getConnectError(t, &dut, clientFD); err != unix.EHOSTUNREACH {
@@ -104,31 +98,24 @@ func TestTCPSynSentUnreachable6(t *testing.T) {
}
// Get the SYN.
- tcpLayers, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, nil, time.Second)
+ tcp, err := conn.Expect(t, &testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagSyn)}, time.Second)
if err != nil {
t.Fatalf("expected SYN: %s", err)
}
// Send a host unreachable message.
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
- const ipLayer = 1
- const tcpLayer = ipLayer + 1
- ip, ok := tcpLayers[ipLayer].(*testbench.IPv6)
- if !ok {
- t.Fatalf("expected %s to be IPv6", tcpLayers[ipLayer])
- }
- tcp, ok := tcpLayers[tcpLayer].(*testbench.TCP)
- if !ok {
- t.Fatalf("expected %s to be TCP", tcpLayers[tcpLayer])
+ icmpPayload := testbench.Layers{tcp.Prev(), tcp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
}
- var icmpv6 testbench.ICMPv6 = testbench.ICMPv6{
- Type: testbench.ICMPv6Type(header.ICMPv6DstUnreachable),
- Code: testbench.ICMPv6Code(header.ICMPv6NetworkUnreachable),
- // Per RFC 4443 3.1, the payload contains 4 zeroed bytes.
- Payload: []byte{0, 0, 0, 0},
+
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = &testbench.ICMPv6{
+ Type: testbench.ICMPv6Type(header.ICMPv6DstUnreachable),
+ Code: testbench.ICMPv6Code(header.ICMPv6NetworkUnreachable),
+ Payload: bytes,
}
- layers = append(layers, &icmpv6, ip, tcp)
conn.SendFrameStateless(t, layers)
if err := getConnectError(t, &dut, clientFD); err != unix.ENETUNREACH {
diff --git a/test/packetimpact/tests/udp_icmp_error_propagation_test.go b/test/packetimpact/tests/udp_icmp_error_propagation_test.go
index 3159d5b89..087aeb66e 100644
--- a/test/packetimpact/tests/udp_icmp_error_propagation_test.go
+++ b/test/packetimpact/tests/udp_icmp_error_propagation_test.go
@@ -58,16 +58,20 @@ func (e icmpError) String() string {
return "Unknown ICMP error"
}
-func (e icmpError) ToICMPv4() *testbench.ICMPv4 {
+func (e icmpError) ToICMPv4(payload []byte) *testbench.ICMPv4 {
switch e {
case portUnreachable:
return &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
- Code: testbench.ICMPv4Code(header.ICMPv4PortUnreachable)}
+ Type: testbench.ICMPv4Type(header.ICMPv4DstUnreachable),
+ Code: testbench.ICMPv4Code(header.ICMPv4PortUnreachable),
+ Payload: payload,
+ }
case timeToLiveExceeded:
return &testbench.ICMPv4{
- Type: testbench.ICMPv4Type(header.ICMPv4TimeExceeded),
- Code: testbench.ICMPv4Code(header.ICMPv4TTLExceeded)}
+ Type: testbench.ICMPv4Type(header.ICMPv4TimeExceeded),
+ Code: testbench.ICMPv4Code(header.ICMPv4TTLExceeded),
+ Payload: payload,
+ }
}
return nil
}
@@ -101,8 +105,6 @@ func wantErrno(c connectionMode, icmpErr icmpError) unix.Errno {
func sendICMPError(t *testing.T, conn *testbench.UDPIPv4, icmpErr icmpError, udp *testbench.UDP) {
t.Helper()
- layers := conn.CreateFrame(t, nil)
- layers = layers[:len(layers)-1]
ip, ok := udp.Prev().(*testbench.IPv4)
if !ok {
t.Fatalf("expected %s to be IPv4", udp.Prev())
@@ -113,12 +115,15 @@ func sendICMPError(t *testing.T, conn *testbench.UDPIPv4, icmpErr icmpError, udp
// to 1.
ip.Checksum = nil
}
- // Note that the ICMP payload is valid in this case because the UDP
- // payload is empty. If the UDP payload were not empty, the packet
- // length during serialization may not be calculated correctly,
- // resulting in a mal-formed packet.
- layers = append(layers, icmpErr.ToICMPv4(), ip, udp)
+ icmpPayload := testbench.Layers{ip, udp}
+ bytes, err := icmpPayload.ToBytes()
+ if err != nil {
+ t.Fatalf("got icmpPayload.ToBytes() = (_, %s), want = (_, nil)", err)
+ }
+
+ layers := conn.CreateFrame(t, nil)
+ layers[len(layers)-1] = icmpErr.ToICMPv4(bytes)
conn.SendFrameStateless(t, layers)
}