summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/checker
diff options
context:
space:
mode:
authorJulian Elischer <jrelis@google.com>2020-10-05 20:41:50 -0700
committergVisor bot <gvisor-bot@google.com>2020-10-05 20:43:55 -0700
commit798cc6b04dc1206538b2cedb1af427e0d5468b46 (patch)
treec45c33e2bd35ccf9001a4b127af58cabf11c1228 /pkg/tcpip/checker
parenta1df7f2ed1be5cb170218c3e127a9b5f51a314fd (diff)
Fix IPv4 ICMP echo handler to copy options
The IPv4 RFCs are specific (though obtuse) that an echo response packet needs to contain all the options from the echo request, much as if it been routed back to the sender, though apparently with a new TTL. They suggest copying the incoming packet header to achieve this so that is what this patch does. PiperOrigin-RevId: 335559176
Diffstat (limited to 'pkg/tcpip/checker')
-rw-r--r--pkg/tcpip/checker/checker.go36
1 files changed, 28 insertions, 8 deletions
diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go
index 71b2f1bda..d4d785cca 100644
--- a/pkg/tcpip/checker/checker.go
+++ b/pkg/tcpip/checker/checker.go
@@ -178,12 +178,32 @@ func PayloadLen(payloadLength int) NetworkChecker {
}
}
+// IPv4Options returns a checker that checks the options in an IPv4 packet.
+func IPv4Options(want []byte) NetworkChecker {
+ return func(t *testing.T, h []header.Network) {
+ t.Helper()
+
+ ip, ok := h[0].(header.IPv4)
+ if !ok {
+ t.Fatalf("unexpected network header passed to checker, got = %T, want = header.IPv4", h[0])
+ }
+ options := ip.Options()
+ // cmp.Diff does not consider nil slices equal to empty slices, but we do.
+ if len(want) == 0 && len(options) == 0 {
+ return
+ }
+ if diff := cmp.Diff(want, options); diff != "" {
+ t.Errorf("options mismatch (-want +got):\n%s", diff)
+ }
+ }
+}
+
// FragmentOffset creates a checker that checks the FragmentOffset field.
func FragmentOffset(offset uint16) NetworkChecker {
return func(t *testing.T, h []header.Network) {
t.Helper()
- // We only do this of IPv4 for now.
+ // We only do this for IPv4 for now.
switch ip := h[0].(type) {
case header.IPv4:
if v := ip.FragmentOffset(); v != offset {
@@ -198,7 +218,7 @@ func FragmentFlags(flags uint8) NetworkChecker {
return func(t *testing.T, h []header.Network) {
t.Helper()
- // We only do this of IPv4 for now.
+ // We only do this for IPv4 for now.
switch ip := h[0].(type) {
case header.IPv4:
if v := ip.Flags(); v != flags {
@@ -664,8 +684,8 @@ func TCPTimestampChecker(wantTS bool, wantTSVal uint32, wantTSEcr uint32) Transp
}
}
-// TCPNoSACKBlockChecker creates a checker that verifies that the segment does not
-// contain any SACK blocks in the TCP options.
+// TCPNoSACKBlockChecker creates a checker that verifies that the segment does
+// not contain any SACK blocks in the TCP options.
func TCPNoSACKBlockChecker() TransportChecker {
return TCPSACKBlockChecker(nil)
}
@@ -739,8 +759,8 @@ func Payload(want []byte) TransportChecker {
}
}
-// ICMPv4 creates a checker that checks that the transport protocol is ICMPv4 and
-// potentially additional ICMPv4 header fields.
+// ICMPv4 creates a checker that checks that the transport protocol is ICMPv4
+// and potentially additional ICMPv4 header fields.
func ICMPv4(checkers ...TransportChecker) NetworkChecker {
return func(t *testing.T, h []header.Network) {
t.Helper()
@@ -851,8 +871,8 @@ func ICMPv4Payload(want []byte) TransportChecker {
t.Fatalf("unexpected transport header passed to checker, got = %T, want = header.ICMPv4", h)
}
payload := icmpv4.Payload()
- if diff := cmp.Diff(payload, want); diff != "" {
- t.Errorf("got ICMP payload mismatch (-want +got):\n%s", diff)
+ if diff := cmp.Diff(want, payload); diff != "" {
+ t.Errorf("ICMP payload mismatch (-want +got):\n%s", diff)
}
}
}