X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FArpDxe%2FArpImpl.c;h=0e9ef103eff9c31d1f34fb5a1feae5bd97021bed;hp=e29fbf872ca157214f6f8b6d2e246b6fc3ebf748;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=7bce0c5a0eb806a55d7231b05769d0efc71cdc59 diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c index e29fbf872c..0e9ef103ef 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c @@ -1,26 +1,16 @@ /** @file + The implementation of the ARP protocol. -Copyright (c) 2006 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - ArpImpl.c - -Abstract: - +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ - #include "ArpImpl.h" +// +// Global variable of EFI ARP Protocol Interface. +// EFI_ARP_PROTOCOL mEfiArpProtocolTemplate = { ArpConfigure, ArpAdd, @@ -35,17 +25,17 @@ EFI_ARP_PROTOCOL mEfiArpProtocolTemplate = { /** Initialize the instance context data. - @param ArpService Pointer to the arp service context data this + @param[in] ArpService Pointer to the arp service context data this instance belongs to. - @param Instance Pointer to the instance context data. + @param[out] Instance Pointer to the instance context data. @return None. **/ VOID ArpInitInstance ( - IN ARP_SERVICE_DATA *ArpService, - IN ARP_INSTANCE_DATA *Instance + IN ARP_SERVICE_DATA *ArpService, + OUT ARP_INSTANCE_DATA *Instance ) { NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE); @@ -56,7 +46,7 @@ ArpInitInstance ( CopyMem (&Instance->ArpProto, &mEfiArpProtocolTemplate, sizeof (Instance->ArpProto)); Instance->Configured = FALSE; - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; InitializeListHead (&Instance->List); } @@ -65,7 +55,7 @@ ArpInitInstance ( /** Process the Arp packets received from Mnp, the procedure conforms to RFC826. - @param Context Pointer to the context data registerd to the + @param[in] Context Pointer to the context data registerd to the Event. @return None. @@ -116,15 +106,28 @@ ArpOnFrameRcvdDpc ( // Status is EFI_SUCCESS, process the received frame. // RxData = RxToken->Packet.RxData; - Head = (ARP_HEAD *) RxData->PacketData; + // + // Sanity check. + // + if (RxData->DataLength < sizeof (ARP_HEAD)) { + // + // Restart the receiving if packet size is not correct. + // + goto RESTART_RECEIVE; + } // // Convert the byte order of the multi-byte fields. // + Head = (ARP_HEAD *) RxData->PacketData; Head->HwType = NTOHS (Head->HwType); Head->ProtoType = NTOHS (Head->ProtoType); Head->OpCode = NTOHS (Head->OpCode); + if (RxData->DataLength < (sizeof (ARP_HEAD) + 2 * Head->HwAddrLen + 2 * Head->ProtoAddrLen)) { + goto RESTART_RECEIVE; + } + if ((Head->HwType != ArpService->SnpMode.IfType) || (Head->HwAddrLen != ArpService->SnpMode.HwAddressSize) || (RxData->ProtocolType != ARP_ETHER_PROTO_TYPE)) { @@ -312,9 +315,9 @@ RESTART_RECEIVE: /** Queue ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK. - @param Event The Event this notify function registered to. - @param Context Pointer to the context data registerd to the - Event. + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registerd to the + Event. @return None. @@ -329,14 +332,14 @@ ArpOnFrameRcvd ( // // Request ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK // - NetLibQueueDpc (TPL_CALLBACK, ArpOnFrameRcvdDpc, Context); + QueueDpc (TPL_CALLBACK, ArpOnFrameRcvdDpc, Context); } /** Process the already sent arp packets. - @param Context Pointer to the context data registerd to the - Event. + @param[in] Context Pointer to the context data registerd to the + Event. @return None. @@ -364,18 +367,18 @@ ArpOnFrameSentDpc ( // // Free the allocated memory and close the event. // - gBS->FreePool (TxData->FragmentTable[0].FragmentBuffer); - gBS->FreePool (TxData); + FreePool (TxData->FragmentTable[0].FragmentBuffer); + FreePool (TxData); gBS->CloseEvent (TxToken->Event); - gBS->FreePool (TxToken); + FreePool (TxToken); } /** Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK. - @param Event The Event this notify function registered to. - @param Context Pointer to the context data registerd to the - Event. + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registerd to the + Event. @return None. @@ -390,16 +393,16 @@ ArpOnFrameSent ( // // Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK // - NetLibQueueDpc (TPL_CALLBACK, ArpOnFrameSentDpc, Context); + QueueDpc (TPL_CALLBACK, ArpOnFrameSentDpc, Context); } /** Process the arp cache olding and drive the retrying arp requests. - @param Event The Event this notify function registered to. - @param Context Pointer to the context data registerd to the - Event. + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registerd to the + Event. @return None. @@ -441,7 +444,7 @@ ArpTimerHandler ( ASSERT (IsListEmpty (&CacheEntry->UserRequestList)); RemoveEntryList (&CacheEntry->List); - gBS->FreePool (CacheEntry); + FreePool (CacheEntry); } else { // // resend the ARP request. @@ -483,7 +486,7 @@ ArpTimerHandler ( // Time out, remove it. // RemoveEntryList (&CacheEntry->List); - gBS->FreePool (CacheEntry); + FreePool (CacheEntry); } else { // // Update the DecayTime. @@ -511,7 +514,7 @@ ArpTimerHandler ( // Time out, remove it. // RemoveEntryList (&CacheEntry->List); - gBS->FreePool (CacheEntry); + FreePool (CacheEntry); } else { // // Update the DecayTime. @@ -525,8 +528,8 @@ ArpTimerHandler ( /** Match the two NET_ARP_ADDRESSes. - @param AddressOne Pointer to the first address to match. - @param AddressTwo Pointer to the second address to match. + @param[in] AddressOne Pointer to the first address to match. + @param[in] AddressTwo Pointer to the second address to match. @return The two addresses match or not. @@ -537,6 +540,8 @@ ArpMatchAddress ( IN NET_ARP_ADDRESS *AddressTwo ) { + ASSERT (AddressOne != NULL && AddressTwo != NULL); + if ((AddressOne->Type != AddressTwo->Type) || (AddressOne->Length != AddressTwo->Length)) { // @@ -564,12 +569,12 @@ ArpMatchAddress ( /** Find the CacheEntry which matches the requirements in the specified CacheTable. - @param CacheTable Pointer to the arp cache table. - @param StartEntry Pointer to the start entry this search begins with - in the cache table. - @param FindOpType The search type. - @param ProtocolAddress Pointer to the protocol address to match. - @param HardwareAddress Pointer to the hardware address to match. + @param[in] CacheTable Pointer to the arp cache table. + @param[in] StartEntry Pointer to the start entry this search begins with + in the cache table. + @param[in] FindOpType The search type. + @param[in] ProtocolAddress Pointer to the protocol address to match. + @param[in] HardwareAddress Pointer to the hardware address to match. @return Pointer to the matched arp cache entry, if NULL, no match is found. @@ -637,9 +642,9 @@ ArpFindNextCacheEntryInTable ( Find the CacheEntry, using ProtocolAddress or HardwareAddress or both, as the keyword, in the DeniedCacheTable. - @param ArpService Pointer to the arp service context data. - @param ProtocolAddress Pointer to the protocol address. - @param HardwareAddress Pointer to the hardware address. + @param[in] ArpService Pointer to the arp service context data. + @param[in] ProtocolAddress Pointer to the protocol address. + @param[in] HardwareAddress Pointer to the hardware address. @return Pointer to the matched cache entry, if NULL no match is found. @@ -697,7 +702,7 @@ ArpFindDeniedCacheEntry ( /** Allocate a cache entry and initialize it. - @param Instance Pointer to the instance context data. + @param[in] Instance Pointer to the instance context data. @return Pointer to the new created cache entry. @@ -764,9 +769,9 @@ ArpAllocCacheEntry ( /** Turn the CacheEntry into the resolved status. - @param CacheEntry Pointer to the resolved cache entry. - @param Instance Pointer to the instance context data. - @param UserEvent Pointer to the UserEvent to notify. + @param[in] CacheEntry Pointer to the resolved cache entry. + @param[in] Instance Pointer to the instance context data. + @param[in] UserEvent Pointer to the UserEvent to notify. @return The count of notifications sent to the instance. @@ -807,7 +812,7 @@ ArpAddressResolved ( // Remove this user request and free the context data. // RemoveEntryList (&Context->List); - gBS->FreePool (Context); + FreePool (Context); Count++; } @@ -816,7 +821,7 @@ ArpAddressResolved ( // // Dispatch the DPCs queued by the NotifyFunction of the Context->UserRequestEvent. // - NetLibDispatchDpc (); + DispatchDpc (); return Count; } @@ -826,9 +831,9 @@ ArpAddressResolved ( Fill the addresses in the CacheEntry using the information passed in by HwAddr and SwAddr. - @param CacheEntry Pointer to the cache entry. - @param HwAddr Pointer to the software address. - @param SwAddr Pointer to the hardware address. + @param[in] CacheEntry Pointer to the cache entry. + @param[in] HwAddr Pointer to the software address. + @param[in] SwAddr Pointer to the hardware address. @return None. @@ -880,9 +885,9 @@ ArpFillAddressInCacheEntry ( /** Configure the instance using the ConfigData. ConfigData is already validated. - @param Instance Pointer to the instance context data to be + @param[in] Instance Pointer to the instance context data to be configured. - @param ConfigData Pointer to the configuration data used to + @param[in] ConfigData Pointer to the configuration data used to configure the instance. @retval EFI_SUCCESS The instance is configured with the ConfigData. @@ -932,9 +937,9 @@ ArpConfigureInstance ( if (ConfigData->SwAddressType == IPV4_ETHER_PROTO_TYPE) { CopyMem (&Ip, ConfigData->StationAddress, sizeof (IP4_ADDR)); - if (!Ip4IsUnicast (NTOHL (Ip), 0)) { + if (IP4_IS_UNSPECIFIED (Ip) || IP4_IS_LOCAL_BROADCAST (Ip)) { // - // The station address is not a valid IPv4 unicast address. + // The station address should not be zero or broadcast address. // return EFI_INVALID_PARAMETER; } @@ -992,7 +997,7 @@ ArpConfigureInstance ( // // Free the buffer previously allocated to hold the station address. // - gBS->FreePool (OldConfigData->StationAddress); + FreePool (OldConfigData->StationAddress); } Instance->Configured = FALSE; @@ -1005,11 +1010,11 @@ ArpConfigureInstance ( /** Send out an arp frame using the CachEntry and the ArpOpCode. - @param Instance Pointer to the instance context data. - @param CacheEntry Pointer to the configuration data used to - configure the instance. - @param ArpOpCode The opcode used to send out this Arp frame, either - request or reply. + @param[in] Instance Pointer to the instance context data. + @param[in] CacheEntry Pointer to the configuration data used to + configure the instance. + @param[in] ArpOpCode The opcode used to send out this Arp frame, either + request or reply. @return None. @@ -1087,6 +1092,7 @@ ArpSendFrame ( Packet = AllocatePool (TotalLength); if (Packet == NULL) { DEBUG ((EFI_D_ERROR, "ArpSendFrame: Allocate memory for Packet failed.\n")); + ASSERT (Packet != NULL); } TmpPtr = Packet; @@ -1192,18 +1198,18 @@ ArpSendFrame ( CLEAN_EXIT: if (Packet != NULL) { - gBS->FreePool (Packet); + FreePool (Packet); } if (TxData != NULL) { - gBS->FreePool (TxData); + FreePool (TxData); } if (TxToken->Event != NULL) { gBS->CloseEvent (TxToken->Event); } - gBS->FreePool (TxToken); + FreePool (TxToken); } @@ -1212,13 +1218,13 @@ CLEAN_EXIT: SwAddressType, AddressBuffer combination as the matching key, if Force is TRUE, the cache is deleted event it's a static entry. - @param CacheTable Pointer to the cache table to do the deletion. - @param BySwAddress Delete the cache entry by software address or by - hardware address. - @param SwAddressType The software address used to do the deletion. - @param AddressBuffer Pointer to the buffer containing the address to - match for the deletion. - @param Force This deletion is forced or not. + @param[in] CacheTable Pointer to the cache table to do the deletion. + @param[in] BySwAddress Delete the cache entry by software address or by + hardware address. + @param[in] SwAddressType The software address used to do the deletion. + @param[in] AddressBuffer Pointer to the buffer containing the address to + match for the deletion. + @param[in] Force This deletion is forced or not. @return The count of the deleted cache entries. @@ -1289,7 +1295,7 @@ MATCHED: // RemoveEntryList (&CacheEntry->List); ASSERT (IsListEmpty (&CacheEntry->UserRequestList)); - gBS->FreePool (CacheEntry); + FreePool (CacheEntry); Count++; } @@ -1301,12 +1307,12 @@ MATCHED: /** Delete cache entries in all the cache tables. - @param Instance Pointer to the instance context data. - @param BySwAddress Delete the cache entry by software address or by - hardware address. - @param AddressBuffer Pointer to the buffer containing the address to - match for the deletion. - @param Force This deletion is forced or not. + @param[in] Instance Pointer to the instance context data. + @param[in] BySwAddress Delete the cache entry by software address or by + hardware address. + @param[in] AddressBuffer Pointer to the buffer containing the address to + match for the deletion. + @param[in] Force This deletion is forced or not. @return The count of the deleted cache entries. @@ -1355,11 +1361,11 @@ ArpDeleteCacheEntry ( /** Cancel the arp request. - @param Instance Pointer to the instance context data. - @param TargetSwAddress Pointer to the buffer containing the target - software address to match the arp request. - @param UserEvent The user event used to notify this request - cancellation. + @param[in] Instance Pointer to the instance context data. + @param[in] TargetSwAddress Pointer to the buffer containing the target + software address to match the arp request. + @param[in] UserEvent The user event used to notify this request + cancellation. @return The count of the cancelled requests. @@ -1402,7 +1408,7 @@ ArpCancelRequest ( // No user requests any more, remove this request cache entry. // RemoveEntryList (&CacheEntry->List); - gBS->FreePool (CacheEntry); + FreePool (CacheEntry); } } } @@ -1414,18 +1420,18 @@ ArpCancelRequest ( /** Find the cache entry in the cache table. - @param Instance Pointer to the instance context data. - @param BySwAddress Set to TRUE to look for matching software protocol + @param[in] Instance Pointer to the instance context data. + @param[in] BySwAddress Set to TRUE to look for matching software protocol addresses. Set to FALSE to look for matching hardware protocol addresses. - @param AddressBuffer Pointer to address buffer. Set to NULL to match + @param[in] AddressBuffer Pointer to address buffer. Set to NULL to match all addresses. - @param EntryLength The size of an entry in the entries buffer. - @param EntryCount The number of ARP cache entries that are found by + @param[out] EntryLength The size of an entry in the entries buffer. + @param[out] EntryCount The number of ARP cache entries that are found by the specified criteria. - @param Entries Pointer to the buffer that will receive the ARP + @param[out] Entries Pointer to the buffer that will receive the ARP cache entries. - @param Refresh Set to TRUE to refresh the timeout value of the + @param[in] Refresh Set to TRUE to refresh the timeout value of the matching ARP cache entry. @retval EFI_SUCCESS The requested ARP cache entries are copied into @@ -1455,6 +1461,7 @@ ArpFindCacheEntry ( UINT32 FoundCount; EFI_ARP_FIND_DATA *FindData; LIST_ENTRY *CacheTable; + UINT32 FoundEntryLength; ArpService = Instance->ArpService; @@ -1571,12 +1578,14 @@ ArpFindCacheEntry ( goto CLEAN_EXIT; } + // + // Found the entry length, make sure its 8 bytes alignment. + // + FoundEntryLength = (((sizeof (EFI_ARP_FIND_DATA) + Instance->ConfigData.SwAddressLength + + ArpService->SnpMode.HwAddressSize) + 3) & ~(0x3)); + if (EntryLength != NULL) { - // - // Return the entry length, make sure its 8 bytes alignment. - // - *EntryLength = (((sizeof (EFI_ARP_FIND_DATA) + Instance->ConfigData.SwAddressLength + - ArpService->SnpMode.HwAddressSize) + 3) & ~(0x3)); + *EntryLength = FoundEntryLength; } if (EntryCount != NULL) { @@ -1593,7 +1602,7 @@ ArpFindCacheEntry ( // // Allocate buffer to copy the found entries. // - FindData = AllocatePool (FoundCount * (*EntryLength)); + FindData = AllocatePool (FoundCount * FoundEntryLength); if (FindData == NULL) { DEBUG ((EFI_D_ERROR, "ArpFindCacheEntry: Failed to allocate memory.\n")); Status = EFI_OUT_OF_RESOURCES; @@ -1617,7 +1626,7 @@ ArpFindCacheEntry ( // // Set the fields in FindData. // - FindData->Size = *EntryLength; + FindData->Size = FoundEntryLength; FindData->DenyFlag = (BOOLEAN)(CacheTable == &ArpService->DeniedCacheTable); FindData->StaticFlag = (BOOLEAN)(CacheEntry->DefaultDecayTime == 0); FindData->HwAddressType = ArpService->SnpMode.IfType; @@ -1646,7 +1655,7 @@ ArpFindCacheEntry ( // // Slip to the next FindData. // - FindData = (EFI_ARP_FIND_DATA *)((UINT8 *)FindData + *EntryLength); + FindData = (EFI_ARP_FIND_DATA *)((UINT8 *)FindData + FoundEntryLength); } CLEAN_EXIT: