diff options
author | Arthur Sfez <asfez@google.com> | 2021-02-18 12:27:53 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-18 12:29:54 -0800 |
commit | 2a2cb29e1cc5c94299b79a3e561d7a6915158ae6 (patch) | |
tree | c87faf21bc50374099a54d82249aefe449998986 /pkg/tcpip/header | |
parent | 26eada5dea1cce3e0911b1419d1257657378f494 (diff) |
Validate IGMP packets
This change also adds support for Router Alert option processing on
incoming packets, a new stat for Router Alert option, and exports
all the IP-option related stats.
Fixes #5491
PiperOrigin-RevId: 358238123
Diffstat (limited to 'pkg/tcpip/header')
-rw-r--r-- | pkg/tcpip/header/ipv4.go | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index 48ca60319..f588311e0 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -519,6 +519,7 @@ func (o *IPv4OptionGeneric) Contents() []byte { return []byte(*o) } // IPv4OptionIterator is an iterator pointing to a specific IP option // at any point of time. It also holds information as to a new options buffer // that we are building up to hand back to the caller. +// TODO(https://gvisor.dev/issues/5513): Add unit tests for IPv4OptionIterator. type IPv4OptionIterator struct { options IPv4Options // ErrCursor is where we are while parsing options. It is exported as any @@ -539,6 +540,15 @@ func (o IPv4Options) MakeIterator() IPv4OptionIterator { } } +// InitReplacement copies the option into the new option buffer. +func (i *IPv4OptionIterator) InitReplacement(option IPv4Option) IPv4Options { + replacementOption := i.RemainingBuffer()[:option.Size()] + if copied := copy(replacementOption, option.Contents()); copied != len(replacementOption) { + panic(fmt.Sprintf("copied %d bytes in the replacement option buffer, expected %d bytes", copied, len(replacementOption))) + } + return replacementOption +} + // RemainingBuffer returns the remaining (unused) part of the new option buffer, // into which a new option may be written. func (i *IPv4OptionIterator) RemainingBuffer() IPv4Options { @@ -649,6 +659,17 @@ func (i *IPv4OptionIterator) Next() (IPv4Option, bool, *IPv4OptParameterProblem) } retval := IPv4OptionRecordRoute(optionBody) return &retval, false, nil + + case IPv4OptionRouterAlertType: + if optLen != IPv4OptionRouterAlertLength { + i.ErrCursor++ + return nil, false, &IPv4OptParameterProblem{ + Pointer: i.ErrCursor, + NeedICMP: true, + } + } + retval := IPv4OptionRouterAlert(optionBody) + return &retval, false, nil } retval := IPv4OptionGeneric(optionBody) return &retval, false, nil @@ -896,11 +917,30 @@ const ( // payload of the router alert option. IPv4OptionRouterAlertValue = 0 - // iPv4OptionRouterAlertValueOffset is the offset for the value of a + // IPv4OptionRouterAlertValueOffset is the offset for the value of a // RouterAlert option. - iPv4OptionRouterAlertValueOffset = 2 + IPv4OptionRouterAlertValueOffset = 2 ) +var _ IPv4Option = (*IPv4OptionRouterAlert)(nil) + +// IPv4OptionRouterAlert is an IPv4 RouterAlert option defined by RFC 2113. +type IPv4OptionRouterAlert []byte + +// Type implements IPv4Option. +func (*IPv4OptionRouterAlert) Type() IPv4OptionType { return IPv4OptionRouterAlertType } + +// Size implements IPv4Option. +func (ra *IPv4OptionRouterAlert) Size() uint8 { return uint8(len(*ra)) } + +// Contents implements IPv4Option. +func (ra *IPv4OptionRouterAlert) Contents() []byte { return []byte(*ra) } + +// Value returns the value of the IPv4OptionRouterAlert. +func (ra *IPv4OptionRouterAlert) Value() uint16 { + return binary.BigEndian.Uint16(ra.Contents()[IPv4OptionRouterAlertValueOffset:]) +} + // IPv4SerializableOption is an interface to represent serializable IPv4 option // types. type IPv4SerializableOption interface { @@ -999,7 +1039,7 @@ func (*IPv4SerializableRouterAlertOption) optionType() IPv4OptionType { // Length implements IPv4SerializableOption. func (*IPv4SerializableRouterAlertOption) length() uint8 { - return IPv4OptionRouterAlertLength - iPv4OptionRouterAlertValueOffset + return IPv4OptionRouterAlertLength - IPv4OptionRouterAlertValueOffset } // SerializeInto implements IPv4SerializableOption. |