/** @file\r
Implementation of Neighbor Discovery support routines.\r
\r
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
LIST_ENTRY *Entry;\r
IP6_PREFIX_LIST_ENTRY *TmpPrefixEntry;\r
\r
- if (Prefix == NULL || PreferredLifetime > ValidLifetime || PrefixLength >= IP6_PREFIX_NUM) {\r
+ if (Prefix == NULL || PreferredLifetime > ValidLifetime || PrefixLength > IP6_PREFIX_MAX) {\r
return NULL;\r
}\r
\r
UINT16 OptBuf[4];\r
EFI_DHCP6_PACKET_OPTION *Oro;\r
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;\r
+ EFI_IPv6_ADDRESS AllNodes;\r
\r
IpSb = IpIf->Service;\r
AddrInfo = DadEntry->AddressInfo;\r
// with DNS SERVERS.\r
//\r
Oro = (EFI_DHCP6_PACKET_OPTION *) OptBuf;\r
- Oro->OpCode = HTONS (IP6_CONFIG_DHCP6_OPTION_ORO);\r
+ Oro->OpCode = HTONS (DHCP6_OPT_ORO);\r
Oro->OpLen = HTONS (2);\r
- *((UINT16 *) &Oro->Data[0]) = HTONS (IP6_CONFIG_DHCP6_OPTION_DNS_SERVERS);\r
+ *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS);\r
\r
InfoReqReXmit.Irt = 4;\r
InfoReqReXmit.Mrc = 64;\r
RemoveEntryList (&DadEntry->Link);\r
FreePool (DadEntry);\r
//\r
+ // Leave link-scope all-nodes multicast address (FF02::1)\r
+ //\r
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);\r
+ Ip6LeaveGroup (IpSb, &AllNodes);\r
+ //\r
// Disable IP operation since link-local address is a duplicate address.\r
//\r
IpSb->LinkLocalDadFail = TRUE;\r
NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE);\r
ASSERT (AddressInfo != NULL);\r
\r
+ //\r
+ // Do nothing if we have already started DAD on the address.\r
+ //\r
+ if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
Status = EFI_SUCCESS;\r
IpSb = IpIf->Service;\r
DadXmits = &IpSb->Ip6ConfigInstance.DadXmits;\r
if (IsDAD && !IsMaintained) {\r
DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf);\r
if (DupAddrDetect != NULL) {\r
- if (DupAddrDetect->Transmit == 0) {\r
- //\r
- // The NS is from another node to performing DAD on the same address since\r
- // we haven't send out any NS yet. Fail DAD for the tentative address.\r
- //\r
- Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect);\r
- Status = EFI_ICMP_ERROR;\r
- goto Exit;\r
- }\r
-\r
//\r
// Check the MAC address of the incoming packet.\r
//\r
//\r
// Sends a Neighbor Advertisement as response.\r
// Set the Router flag to zero since the node is a host.\r
- // If the source address of the solicitation is unspeicifed, and target address\r
+ // If the source address of the solicitation is unspecified, and target address\r
// is one of the maintained address, reply a unsolicited multicast advertisement.\r
//\r
if (IsDAD && IsMaintained) {\r
UINT32 ReachableTime;\r
UINT32 RetransTimer;\r
UINT16 RouterLifetime;\r
- UINT16 Offset;\r
+ UINT32 Offset;\r
UINT8 Type;\r
UINT8 Length;\r
IP6_ETHER_ADDR_OPTION LinkLayerOption;\r
}\r
\r
//\r
- // If an valid router advertisment is received, stops router solicitation.\r
+ // If an valid router advertisement is received, stops router solicitation.\r
//\r
IpSb->RouterAdvertiseReceived = TRUE;\r
\r
//\r
// The only defined options that may appear are the Source\r
// Link-Layer Address, Prefix information and MTU options.\r
- // All included options have a length that is greater than zero.\r
+ // All included options have a length that is greater than zero and\r
+ // fit within the input packet.\r
//\r
Offset = 16;\r
- while (Offset < Head->PayloadLength) {\r
+ while (Offset < (UINT32) Head->PayloadLength) {\r
NetbufCopy (Packet, Offset, sizeof (UINT8), &Type);\r
switch (Type) {\r
case Ip6OptionEtherSource:\r
// Update the neighbor cache\r
//\r
NetbufCopy (Packet, Offset, sizeof (IP6_ETHER_ADDR_OPTION), (UINT8 *) &LinkLayerOption);\r
- if (LinkLayerOption.Length <= 0) {\r
- goto Exit;\r
- }\r
+\r
+ //\r
+ // Option size validity ensured by Ip6IsNDOptionValid().\r
+ //\r
+ ASSERT (LinkLayerOption.Length != 0);\r
+ ASSERT (Offset + (UINT32) LinkLayerOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
\r
ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS));\r
CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6);\r
}\r
}\r
\r
- Offset = (UINT16) (Offset + (UINT16) LinkLayerOption.Length * 8);\r
+ Offset += (UINT32) LinkLayerOption.Length * 8;\r
break;\r
case Ip6OptionPrefixInfo:\r
NetbufCopy (Packet, Offset, sizeof (IP6_PREFIX_INFO_OPTION), (UINT8 *) &PrefixOption);\r
- if (PrefixOption.Length != 4) {\r
- goto Exit;\r
- }\r
+\r
+ //\r
+ // Option size validity ensured by Ip6IsNDOptionValid().\r
+ //\r
+ ASSERT (PrefixOption.Length == 4);\r
+ ASSERT (Offset + (UINT32) PrefixOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
+\r
PrefixOption.ValidLifetime = NTOHL (PrefixOption.ValidLifetime);\r
PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime);\r
\r
//\r
if (!Ip6IsOneOfSetAddress (IpSb, &StatelessAddress, NULL, NULL)) {\r
//\r
- // And also not in the DAD process, check its uniqeness firstly.\r
+ // And also not in the DAD process, check its uniqueness firstly.\r
//\r
if (Ip6FindDADEntry (IpSb, &StatelessAddress, NULL) == NULL) {\r
Status = Ip6SetAddress (\r
\r
} else if (PrefixList->ValidLifetime <= 7200) {\r
//\r
- // If RemainingLifetime is less than or equls to 2 hours, ignore the\r
+ // If RemainingLifetime is less than or equals to 2 hours, ignore the\r
// Prefix Information option with regards to the valid lifetime.\r
// TODO: If this option has been authenticated, set the valid lifetime.\r
//\r
break;\r
case Ip6OptionMtu:\r
NetbufCopy (Packet, Offset, sizeof (IP6_MTU_OPTION), (UINT8 *) &MTUOption);\r
- if (MTUOption.Length != 1) {\r
- goto Exit;\r
- }\r
+\r
+ //\r
+ // Option size validity ensured by Ip6IsNDOptionValid().\r
+ //\r
+ ASSERT (MTUOption.Length == 1);\r
+ ASSERT (Offset + (UINT32) MTUOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
\r
//\r
// Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order\r
// Silently ignore unrecognized options\r
//\r
NetbufCopy (Packet, Offset + sizeof (UINT8), sizeof (UINT8), &Length);\r
- if (Length <= 0) {\r
- goto Exit;\r
- }\r
\r
- Offset = (UINT16) (Offset + (UINT16) Length * 8);\r
+ ASSERT (Length != 0);\r
+\r
+ Offset += (UINT32) Length * 8;\r
break;\r
}\r
}\r
the IP head removed.\r
\r
@retval EFI_INVALID_PARAMETER The parameter is invalid.\r
- @retval EFI_OUT_OF_RESOURCES Insuffcient resources to complete the\r
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the\r
operation.\r
@retval EFI_SUCCESS Successfully updated the route caches.\r
\r
//\r
Flag = FALSE;\r
if ((DupAddrDetect->Receive == 0) ||\r
- (DupAddrDetect->Transmit == DupAddrDetect->Receive)) {\r
+ (DupAddrDetect->Transmit <= DupAddrDetect->Receive)) {\r
Flag = TRUE;\r
}\r
\r
\r
/**\r
The heartbeat timer of ND module in 1 second. This time routine handles following\r
- things: 1) maitain default router list; 2) maintain prefix options;\r
+ things: 1) maintain default router list; 2) maintain prefix options;\r
3) maintain route caches.\r
\r
@param[in] IpSb The IP6 service binding instance.\r