diff options
author | Julian Elischer <jrelis@google.com> | 2020-11-09 21:57:30 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-11-09 21:59:53 -0800 |
commit | 3b353ff0ef09caf53037a68a055418c7028557e7 (patch) | |
tree | dbd10cea5850fa3135005f78408184c503257cd4 /test/packetimpact/testbench/layers.go | |
parent | b2d5b71ecdf7a7e07210b74610b5432b6f93f38d (diff) |
Additions to ICMP and IPv4 parsers
Teach ICMP.Parser/ToBytes to handle some non echo ICMP packets.
Teach IPv4.Parser that fragments only have a payload, not an upper layer.
Fix IPv4 and IPv6 reassembly tests to handle the change.
Fixes #4758
PiperOrigin-RevId: 341549665
Diffstat (limited to 'test/packetimpact/testbench/layers.go')
-rw-r--r-- | test/packetimpact/testbench/layers.go | 73 |
1 files changed, 49 insertions, 24 deletions
diff --git a/test/packetimpact/testbench/layers.go b/test/packetimpact/testbench/layers.go index af7a2ba4e..fc45d2085 100644 --- a/test/packetimpact/testbench/layers.go +++ b/test/packetimpact/testbench/layers.go @@ -402,6 +402,10 @@ func parseIPv4(b []byte) (Layer, layerParser) { DstAddr: Address(h.DestinationAddress()), } var nextParser layerParser + // If it is a fragment, don't treat it as having a transport protocol. + if h.FragmentOffset() != 0 || h.More() { + return &ipv4, parsePayload + } switch h.TransportProtocol() { case header.TCPProtocolNumber: nextParser = parseTCP @@ -709,12 +713,17 @@ func parseIPv6FragmentExtHdr(b []byte) (Layer, layerParser) { nextHeader := b[0] var extHdr header.IPv6FragmentExtHdr copy(extHdr[:], b[2:]) - return &IPv6FragmentExtHdr{ + fragLayer := IPv6FragmentExtHdr{ NextHeader: IPv6ExtHdrIdent(header.IPv6ExtensionHeaderIdentifier(nextHeader)), FragmentOffset: Uint16(extHdr.FragmentOffset()), MoreFragments: Bool(extHdr.More()), Identification: Uint32(extHdr.ID()), - }, nextIPv6PayloadParser(nextHeader) + } + // If it is a fragment, we can't interpret it. + if extHdr.FragmentOffset() != 0 || extHdr.More() { + return &fragLayer, parsePayload + } + return &fragLayer, nextIPv6PayloadParser(nextHeader) } func (l *IPv6HopByHopOptionsExtHdr) length() int { @@ -861,26 +870,15 @@ func (l *ICMPv6) merge(other Layer) error { return mergeLayer(l, other) } -// ICMPv4Type is a helper routine that allocates a new header.ICMPv4Type value -// to store t and returns a pointer to it. -func ICMPv4Type(t header.ICMPv4Type) *header.ICMPv4Type { - return &t -} - -// ICMPv4Code is a helper routine that allocates a new header.ICMPv4Code value -// to store t and returns a pointer to it. -func ICMPv4Code(t header.ICMPv4Code) *header.ICMPv4Code { - return &t -} - // ICMPv4 can construct and match an ICMPv4 encapsulation. type ICMPv4 struct { LayerBase Type *header.ICMPv4Type Code *header.ICMPv4Code Checksum *uint16 - Ident *uint16 - Sequence *uint16 + Ident *uint16 // Only in Echo Request/Reply. + Sequence *uint16 // Only in Echo Request/Reply. + Pointer *uint8 // Only in Parameter Problem. Payload []byte } @@ -888,6 +886,18 @@ func (l *ICMPv4) String() string { return stringLayer(l) } +// ICMPv4Type is a helper routine that allocates a new header.ICMPv4Type value +// to store t and returns a pointer to it. +func ICMPv4Type(t header.ICMPv4Type) *header.ICMPv4Type { + return &t +} + +// ICMPv4Code is a helper routine that allocates a new header.ICMPv4Code value +// to store t and returns a pointer to it. +func ICMPv4Code(t header.ICMPv4Code) *header.ICMPv4Code { + return &t +} + // ToBytes implements Layer.ToBytes. func (l *ICMPv4) ToBytes() ([]byte, error) { b := make([]byte, header.ICMPv4MinimumSize+len(l.Payload)) @@ -901,11 +911,19 @@ func (l *ICMPv4) ToBytes() ([]byte, error) { if copied := copy(h.Payload(), l.Payload); copied != len(l.Payload) { panic(fmt.Sprintf("wrong number of bytes copied into h.Payload(): got = %d, want = %d", len(h.Payload()), len(l.Payload))) } - if l.Ident != nil { - h.SetIdent(*l.Ident) - } - if l.Sequence != nil { - h.SetSequence(*l.Sequence) + typ := h.Type() + switch typ { + case header.ICMPv4EchoReply, header.ICMPv4Echo: + if l.Ident != nil { + h.SetIdent(*l.Ident) + } + if l.Sequence != nil { + h.SetSequence(*l.Sequence) + } + case header.ICMPv4ParamProblem: + if l.Pointer != nil { + h.SetPointer(*l.Pointer) + } } // The checksum must be handled last because the ICMPv4 header fields are @@ -932,14 +950,21 @@ func (l *ICMPv4) ToBytes() ([]byte, error) { // parser for the encapsulated payload. func parseICMPv4(b []byte) (Layer, layerParser) { h := header.ICMPv4(b) + + msgType := h.Type() icmpv4 := ICMPv4{ - Type: ICMPv4Type(h.Type()), + Type: ICMPv4Type(msgType), Code: ICMPv4Code(h.Code()), Checksum: Uint16(h.Checksum()), - Ident: Uint16(h.Ident()), - Sequence: Uint16(h.Sequence()), Payload: h.Payload(), } + switch msgType { + case header.ICMPv4EchoReply, header.ICMPv4Echo: + icmpv4.Ident = Uint16(h.Ident()) + icmpv4.Sequence = Uint16(h.Sequence()) + case header.ICMPv4ParamProblem: + icmpv4.Pointer = Uint8(h.Pointer()) + } return &icmpv4, nil } |