IN UINT16 OptionLen\r
)\r
{\r
- UINT16 Offset;\r
- UINT8 OptionType;\r
+ UINT32 Offset;\r
UINT16 Length;\r
+ IP6_OPTION_HEADER *OptionHeader;\r
+\r
+ if (Option == NULL) {\r
+ ASSERT (Option != NULL);\r
+ return FALSE;\r
+ }\r
\r
Offset = 0;\r
\r
- while (Offset < OptionLen) {\r
- OptionType = *(Option + Offset);\r
- Length = (UINT16) (*(Option + Offset + 1) * 8);\r
+ //\r
+ // RFC 4861 states that Neighbor Discovery packet can contain zero or more\r
+ // options. Start processing the options if at least Type + Length fields\r
+ // fit within the input buffer.\r
+ //\r
+ while (Offset + sizeof (IP6_OPTION_HEADER) - 1 < OptionLen) {\r
+ OptionHeader = (IP6_OPTION_HEADER*) (Option + Offset);\r
+ Length = (UINT16) OptionHeader->Length * 8;\r
\r
- switch (OptionType) {\r
+ switch (OptionHeader->Type) {\r
case Ip6OptionPrefixInfo:\r
if (Length != 32) {\r
return FALSE;\r
}\r
-\r
break;\r
\r
case Ip6OptionMtu:\r
if (Length != 8) {\r
return FALSE;\r
}\r
-\r
break;\r
\r
default:\r
- //\r
- // Check the length of Ip6OptionEtherSource, Ip6OptionEtherTarget, and\r
- // Ip6OptionRedirected here. For unrecognized options, silently ignore\r
- // and continue processing the message.\r
- //\r
+ // RFC 4861 states that Length field cannot be 0.\r
if (Length == 0) {\r
return FALSE;\r
}\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Check whether recognized options are within the input buffer's scope.\r
+ //\r
+ switch (OptionHeader->Type) {\r
+ case Ip6OptionEtherSource:\r
+ case Ip6OptionEtherTarget:\r
+ case Ip6OptionPrefixInfo:\r
+ case Ip6OptionRedirected:\r
+ case Ip6OptionMtu:\r
+ if (Offset + Length > (UINT32) OptionLen) {\r
+ return FALSE;\r
+ }\r
+ break;\r
\r
+ default:\r
+ //\r
+ // Unrecognized options can be either valid (but unused) or invalid\r
+ // (garbage in between or right after valid options). Silently ignore.\r
+ //\r
break;\r
}\r
\r
- Offset = (UINT16) (Offset + Length);\r
+ //\r
+ // Advance to the next option.\r
+ // Length already considers option header's Type + Length.\r
+ //\r
+ Offset += Length;\r
}\r
\r
return TRUE;\r