summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetimpact')
-rw-r--r--test/packetimpact/testbench/layers.go39
1 files changed, 23 insertions, 16 deletions
diff --git a/test/packetimpact/testbench/layers.go b/test/packetimpact/testbench/layers.go
index 9df072cfd..dcff4ab36 100644
--- a/test/packetimpact/testbench/layers.go
+++ b/test/packetimpact/testbench/layers.go
@@ -298,14 +298,12 @@ func (l *IPv4) ToBytes() ([]byte, error) {
// An IPv4 header is variable length depending on the size of the Options.
hdrLen := header.IPv4MinimumSize
if l.Options != nil {
- hdrLen += l.Options.SizeWithPadding()
+ if len(*l.Options)%4 != 0 {
+ return nil, fmt.Errorf("invalid header options '%x (len=%d)'; must be 32 bit aligned", *l.Options, len(*l.Options))
+ }
+ hdrLen += len(*l.Options)
if hdrLen > header.IPv4MaximumHeaderSize {
- // While ToBytes can be called on packets that were received as well
- // as packets locally generated, it is physically impossible for a
- // received packet to overflow this value so any such failure must
- // be the result of a local programming error and not remotely
- // triggered. A panic is therefore appropriate.
- panic(fmt.Sprintf("IPv4 Options %d bytes, Max %d", len(*l.Options), header.IPv4MaximumOptionsSize))
+ return nil, fmt.Errorf("IPv4 Options %d bytes, Max %d", len(*l.Options), header.IPv4MaximumOptionsSize)
}
}
b := make([]byte, hdrLen)
@@ -323,10 +321,6 @@ func (l *IPv4) ToBytes() ([]byte, error) {
DstAddr: tcpip.Address(""),
Options: nil,
}
- // Leave an empty options slice as nil.
- if hdrLen > header.IPv4MinimumSize {
- fields.Options = *l.Options
- }
if l.TOS != nil {
fields.TOS = *l.TOS
}
@@ -373,18 +367,31 @@ func (l *IPv4) ToBytes() ([]byte, error) {
if l.DstAddr != nil {
fields.DstAddr = *l.DstAddr
}
- if l.Checksum != nil {
- fields.Checksum = *l.Checksum
- }
+
h.Encode(fields)
- if l.Checksum == nil {
- h.SetChecksum(^h.CalculateChecksum())
+
+ // Put raw option bytes from test definition in header. Options as raw bytes
+ // allows us to serialize malformed options, which is not possible with
+ // the provided serialization functions.
+ if l.Options != nil {
+ h.SetHeaderLength(h.HeaderLength() + uint8(len(*l.Options)))
+ if got, want := copy(h.Options(), *l.Options), len(*l.Options); got != want {
+ return nil, fmt.Errorf("failed to copy option bytes into header, got %d want %d", got, want)
+ }
}
+
// Encode cannot set this incorrectly so we need to overwrite what it wrote
// in order to test handling of a bad IHL value.
if l.IHL != nil {
h.SetHeaderLength(*l.IHL)
}
+
+ if l.Checksum == nil {
+ h.SetChecksum(^h.CalculateChecksum())
+ } else {
+ h.SetChecksum(*l.Checksum)
+ }
+
return h, nil
}