4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo Library.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Uefi.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Protocol/Udp4.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/IpIoLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/DebugLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseMemoryLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/UefiBootServicesTableLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/MemoryAllocationLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/DpcLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mActiveIpIoList = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mActiveIpIoList,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mActiveIpIoList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_IP4_CONFIG_DATA mIp4IoDefaultIpConfigData = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP_PROTO_UDP,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TRUE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {{0, 0, 0, 0}},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {{0, 0, 0, 0}},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 255,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_IP6_CONFIG_DATA mIp6IoDefaultIpConfigData = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP_PROTO_UDP,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TRUE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 255,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO mIcmpErrMap[10] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE }, // ICMP_ERR_UNREACH_NET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE }, // ICMP_ERR_UNREACH_HOST
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE }, // ICMP_ERR_UNREACH_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE }, // ICMP_ERR_UNREACH_PORT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE }, // ICMP_ERR_MSGSIZE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE }, // ICMP_ERR_UNREACH_SRCFAIL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE }, // ICMP_ERR_TIMXCEED_INTRANS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE }, // ICMP_ERR_TIMEXCEED_REASS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, FALSE}, // ICMP_ERR_QUENCH
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE } // ICMP_ERR_PARAMPROB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO mIcmp6ErrMap[10] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_UNREACH_NET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_UNREACH_HOST
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE}, // ICMP6_ERR_UNREACH_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE}, // ICMP6_ERR_UNREACH_PORT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {TRUE, TRUE}, // ICMP6_ERR_PACKAGE_TOOBIG
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_HOPLIMIT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_REASS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_HEADER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_NEXHEADER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {FALSE, TRUE} // ICMP6_ERR_PARAMPROB_IPV6OPTION
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for IP transmit token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoTransmitHandlerDpc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for IP transmit token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The event signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoTransmitHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function create an IP child ,open the IP protocol, and return the opened
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP protocol as Interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ControllerHandle The controller handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The image handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ChildHandle Pointer to the buffer to save the IP child handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpVersion The version of the IP protocol to use, either
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv4 or IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Interface Pointer used to get the IP protocol interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP child is created and the IP protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync interface is retrieved.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others The required operation failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoCreateIpChildOpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE *ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IpVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT VOID **Interface
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *ServiceBindingGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *IpProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid = &gEfiIp4ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpVersion == IP_VERSION_6){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid = &gEfiIp6ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create an IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetLibCreateServiceChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the IP protocol installed on the *ChildHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Interface,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_DRIVER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // On failure, destroy the IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetLibDestroyServiceChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function close the previously openned IP protocol and destroy the IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ControllerHandle The controller handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The image handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ChildHandle The child handle of the IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpVersion The version of the IP protocol to use, either
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv4 or IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP protocol is closed and the relevant IP child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is destroyed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others The required operation failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoCloseProtocolDestroyIpChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IpVersion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *ServiceBindingGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GUID *IpProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid = &gEfiIp4ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpVersion == IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid = &gEfiIp6ProtocolGuid;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the previously openned IP protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Destroy the IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetLibDestroyServiceChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBindingGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function handles ICMPv4 packets. It is the worker function of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoIcmpHandler.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pkt Pointer to the ICMPv4 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session Pointer to the net session of this ICMPv4 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv4 packet is handled successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED This type of ICMPv4 packet is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoIcmpv4Handler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *Pkt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_NET_SESSION_DATA *Session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP4_ICMP_ERROR_HEAD *IcmpHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP4_HEADER *IpHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IcmpErr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *PayLoadHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Code;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 TrimBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpIo->IpVersion == IP_VERSION_4);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpHdr = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the ICMP packet length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = IcmpHdr->Head.Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Code = IcmpHdr->Head.Code;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Analyze the ICMP Error in this ICMP pkt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Type) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_TYPE_UNREACH:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Code) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_NET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_HOST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_PROTOCOL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_PORT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_SRCFAIL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = (UINT8) (ICMP_ERR_UNREACH_NET + Code);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_NEEDFRAG:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP_ERR_MSGSIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_NET_UNKNOWN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_NET_PROHIB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_TOSNET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP_ERR_UNREACH_NET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_HOST_UNKNOWN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_ISOLATED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_HOST_PROHIB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_CODE_UNREACH_TOSHOST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP_ERR_UNREACH_HOST;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_TYPE_TIMXCEED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = (UINT8) (Code + ICMP_ERR_TIMXCEED_INTRANS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_TYPE_PARAMPROB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP_ERR_PARAMPROB;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_TYPE_SOURCEQUENCH:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP_ERR_QUENCH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Notify user the ICMP pkt only containing payload except
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IP and ICMP header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (Pkt, TrimBytes, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function handles ICMPv6 packets. It is the worker function of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoIcmpHandler.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pkt Pointer to the ICMPv6 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session Pointer to the net session of this ICMPv6 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 packet is handled successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED This type of ICMPv6 packet is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoIcmpv6Handler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *Pkt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_NET_SESSION_DATA *Session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_ERROR_HEAD *IcmpHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_HEADER *IpHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IcmpErr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *PayLoadHdr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Code;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 NextHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 TrimBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpIo->IpVersion == IP_VERSION_6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the ICMPv6 packet length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Pkt->TotalSize < sizeof (IP6_ICMP_ERROR_HEAD)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHdr = NET_PROTO_HDR (Pkt, IP6_ICMP_ERROR_HEAD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = IcmpHdr->Head.Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Code = IcmpHdr->Head.Code;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Analyze the ICMPv6 Error in this ICMPv6 packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Type) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_DEST_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Code) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_NO_ROUTE_TO_DEST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_BEYOND_SCOPE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_ROUTE_REJECTED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP6_ERR_UNREACH_NET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_COMM_PROHIBITED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_ADDR_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_SOURCE_ADDR_FAILED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP6_ERR_UNREACH_HOST;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_PORT_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP6_ERR_UNREACH_PORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_PACKET_TOO_BIG:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code >= 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = ICMP6_ERR_PACKAGE_TOOBIG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_TIME_EXCEEDED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = (UINT8) (ICMP6_ERR_TIMXCEED_HOPLIMIT + Code);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_PARAMETER_PROBLEM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Code > 3) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpErr = (UINT8) (ICMP6_ERR_PARAMPROB_HEADER + Code);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Notify user the ICMPv6 packet only containing payload except
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IPv6 basic header, extension header and ICMP header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpHdr = (EFI_IP6_HEADER *) (&IcmpHdr->IpHead);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextHeader = IpHdr->NextHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayLoadHdr = (UINT8 *) ((UINT8 *) IcmpHdr + sizeof (IP6_ICMP_ERROR_HEAD));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flag = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (NextHeader) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_IP_PROTO_UDP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_IP_PROTO_TCP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_IP_PROTO_ICMP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case IP6_NO_NEXT_HEADER:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flag = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case IP6_HOP_BY_HOP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case IP6_DESTINATION:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The Hdr Ext Len is 8-bit unsigned integer in 8-octet units, not including
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the first 8 octets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextHeader = *(PayLoadHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayLoadHdr = (UINT8 *) (PayLoadHdr + (*(PayLoadHdr + 1) + 1) * 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case IP6_FRAGMENT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The Fragment Header Length is 8 octets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextHeader = *(PayLoadHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayLoadHdr = (UINT8 *) (PayLoadHdr + 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Flag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (Pkt, TrimBytes, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function handles ICMP packets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pkt Pointer to the ICMP packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session Pointer to the net session of this ICMP packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMP packet is handled successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED This type of ICMP packet is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The IP protocol version in IP_IO is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoIcmpHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *Pkt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_NET_SESSION_DATA *Session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpIoIcmpv4Handler (IpIo, Pkt, Session);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpIo->IpVersion == IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpIoIcmpv6Handler (IpIo, Pkt, Session);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free function for receive token of IP_IO. It is used to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync signal the recycle event to notify IP to recycle the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The event to be signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoExtFree (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent ((EFI_EVENT) Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a send entry to wrap a packet before sending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync out it through IP.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pkt Pointer to the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sender Pointer to the IP sender.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context Pointer to the context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NotifyData Pointer to the notify data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Dest Pointer to the destination IP address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Override Pointer to the overriden IP_IO data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the data structure created to wrap the packet. If NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return resource limit occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIP_IO_SEND_ENTRY *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoCreateSndEntry (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *Pkt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_IP_PROTOCOL Sender,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *NotifyData OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP_ADDRESS *Dest OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_OVERRIDE *Override
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_SEND_ENTRY *SndEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_FRAGMENT *ExtFragment;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 FragmentCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_OVERRIDE *OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_TX_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP4_TRANSMIT_DATA *Ip4TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_TRANSMIT_DATA *Ip6TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((IpIo->IpVersion != IP_VERSION_4) && (IpIo->IpVersion != IP_VERSION_6)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OverrideData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate resource for SndEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == SndEntry) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_NOTIFY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoTransmitHandler,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FragmentCount = Pkt->BlockOpNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate resource for TxData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = (IP_IO_IP_TX_DATA *) AllocatePool (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (IP_IO_IP_TX_DATA) + sizeof (NET_FRAGMENT) * (FragmentCount - 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == TxData) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build a fragment table to contain the fragments in the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtFragment = (NET_FRAGMENT *) TxData->Ip4TxData.FragmentTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtFragment = (NET_FRAGMENT *) TxData->Ip6TxData.FragmentTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufBuildExt (Pkt, ExtFragment, &FragmentCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate resource for OverrideData if needed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL != Override) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OverrideData = AllocateCopyPool (sizeof (IP_IO_OVERRIDE), Override);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == OverrideData) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set other fields of TxData except the fragment table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData = &TxData->Ip4TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Ip4TxData->DestinationAddress, Dest, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData->OverrideData = &OverrideData->Ip4OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData->OptionsLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData->OptionsBuffer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData->TotalDataLength = Pkt->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip4TxData->FragmentCount = FragmentCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the fields of SndToken
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->SndToken.Ip4Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->SndToken.Ip4Token.Packet.TxData = Ip4TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData = &TxData->Ip6TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Dest != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Ip6TxData->DestinationAddress, Dest, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Ip6TxData->DestinationAddress, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData->OverrideData = &OverrideData->Ip6OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData->DataLength = Pkt->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData->FragmentCount = FragmentCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData->ExtHdrsLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TxData->ExtHdrs = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the fields of SndToken
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->SndToken.Ip6Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->SndToken.Ip6Token.Packet.TxData = Ip6TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the fields of SndEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->IpIo = IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->Ip = Sender;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->Context = Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->NotifyData = NotifyData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->Pkt = Pkt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_GET_REF (Pkt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return SndEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_ERROR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OverrideData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (OverrideData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (TxData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SndEntry != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SndEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Event != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroy the SndEntry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function pairs with IpIoCreateSndEntry().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SndEntry Pointer to the send entry to be destroyed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoDestroySndEntry (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_SEND_ENTRY *SndEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_TX_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_OVERRIDE *Override;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SndEntry->IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event = SndEntry->SndToken.Ip4Token.Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip4Token.Packet.TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Override = (IP_IO_OVERRIDE *) TxData->Ip4TxData.OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (SndEntry->IpIo->IpVersion == IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event = SndEntry->SndToken.Ip6Token.Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip6Token.Packet.TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Override = (IP_IO_OVERRIDE *) TxData->Ip6TxData.OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (TxData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL != Override) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Override);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (SndEntry->Pkt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&SndEntry->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (SndEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for IP transmit token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoTransmitHandlerDpc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO *IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_SEND_ENTRY *SndEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry = (IP_IO_SEND_ENTRY *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo = SndEntry->IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SndEntry->SndToken.Ip4Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpIo->IpVersion == IP_VERSION_6){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SndEntry->SndToken.Ip6Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktSentNotify (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->Context,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->Ip,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry->NotifyData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoDestroySndEntry (SndEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for IP transmit token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The event signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoTransmitHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync QueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The dummy handler for the dummy IP receive token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoDummyHandlerDpc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_INFO *IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT RecycleEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo = (IP_IO_IP_INFO *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((IpInfo->IpVersion != IP_VERSION_4) && (IpInfo->IpVersion != IP_VERSION_6)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RecycleEvent = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpInfo->DummyRcvToken.Ip4Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->DummyRcvToken.Ip4Token.Packet.RxData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RecycleEvent = IpInfo->DummyRcvToken.Ip4Token.Packet.RxData->RecycleSignal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpInfo->DummyRcvToken.Ip6Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->DummyRcvToken.Ip6Token.Packet.RxData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RecycleEvent = IpInfo->DummyRcvToken.Ip6Token.Packet.RxData->RecycleSignal;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ABORTED == Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The reception is actively aborted by the consumer, directly return.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (EFI_SUCCESS == Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Recycle the RxData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (RecycleEvent != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (RecycleEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Continue the receive.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip4->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->DummyRcvToken.Ip4Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip6->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->DummyRcvToken.Ip6Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function add IpIoDummyHandlerDpc to the end of the DPC queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The event signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoDummyHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync QueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for the IP receive token, used to process
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the received IP packets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoListenHandlerDpc (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO *IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_RX_DATA *RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NET_SESSION_DATA Session;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *Pkt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo = (IP_IO *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->RcvToken.Ip4Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip4Token.Packet.RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpIo->IpVersion == IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->RcvToken.Ip6Token.Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip6Token.Packet.RxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ABORTED == Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The reception is actively aborted by the consumer, directly return.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug Only process the normal packets and the icmp error packets, if RxData is NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug this should be a bug of the low layer (IP).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Resume;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == IpIo->PktRcvdNotify) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto CleanUp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress) != 0) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !NetIp4IsUnicast (EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *) RxData)->Header->SourceAddress), 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The source address is not zero and it's not a unicast IP address, discard it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto CleanUp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a netbuffer representing IPv4 packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pkt = NetbufFromExt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (NET_FRAGMENT *) RxData->Ip4RxData.FragmentTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->Ip4RxData.FragmentCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoExtFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->Ip4RxData.RecycleSignal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Pkt) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto CleanUp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a net session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.Source.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.Dest.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpHdr.Ip4Hdr = RxData->Ip4RxData.Header;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpHdrLen = RxData->Ip4RxData.HeaderLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpVersion = IP_VERSION_4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsValidUnicast(&RxData->Ip6RxData.Header->SourceAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto CleanUp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a netbuffer representing IPv6 packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pkt = NetbufFromExt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (NET_FRAGMENT *) RxData->Ip6RxData.FragmentTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->Ip6RxData.FragmentCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoExtFree,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RxData->Ip6RxData.RecycleSignal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == Pkt) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto CleanUp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a net session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Session.Source,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &RxData->Ip6RxData.Header->SourceAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof(EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Session.Dest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &RxData->Ip6RxData.Header->DestinationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof(EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpHdr.Ip6Hdr = RxData->Ip6RxData.Header;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpHdrLen = RxData->Ip6RxData.HeaderLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session.IpVersion = IP_VERSION_6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_SUCCESS == Status) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktRcvdNotify (EFI_SUCCESS, 0, &Session, Pkt, IpIo->RcvdContext);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Status is EFI_ICMP_ERROR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIoIcmpHandler (IpIo, Pkt, &Session);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Pkt);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Resume;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCleanUp:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (RxData->Ip4RxData.RecycleSignal);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (RxData->Ip6RxData.RecycleSignal);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncResume:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip4->Receive (IpIo->Ip.Ip4, &(IpIo->RcvToken.Ip4Token));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip6->Receive (IpIo->Ip.Ip6, &(IpIo->RcvToken.Ip6Token));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function add IpIoListenHandlerDpc to the end of the DPC queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The event signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context passed in by the event notifier.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoListenHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync QueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a new IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function uses IP4/IP6 service binding protocol in Controller to create
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync an IP4/IP6 child (aka IP4/IP6 instance).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Image The image handle of the driver or application that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync consumes IP_IO.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Controller The controller handle that has IP4 or IP6 service
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync binding protocol installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpVersion The version of the IP protocol to use, either
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv4 or IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to a newly created IP_IO instance, or NULL if failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIP_IO *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoCreate (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IpVersion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO *IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo = AllocateZeroPool (sizeof (IP_IO));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == IpIo) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&(IpIo->PendingSndList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&(IpIo->IpList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller = Controller;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image = Image;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->IpVersion = IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_NOTIFY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoListenHandler,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ReleaseIpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->RcvToken.Ip4Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->RcvToken.Ip6Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create an IP child and open IP protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIoCreateIpChildOpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpIo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **)&(IpIo->Ip)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ReleaseIpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReleaseIpIo:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Event != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool (IpIo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Open an IP_IO instance for use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is called after IpIoCreate(). It is used for configuring the IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance and register the callbacks and their context data for sending and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receiving IP packets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to an IP_IO instance that needs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to open.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] OpenData The configuration data and callbacks for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP_IO instance opened with OpenData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The IP_IO instance is configured, avoid to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reopen it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Error condition occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoOpen (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_OPEN_DATA *OpenData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IsConfigured) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ACCESS_DENIED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpVersion = IpIo->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // configure ip
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip4->Configure (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &OpenData->IpConfigData.Ip4CfgData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip6->Configure (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &OpenData->IpConfigData.Ip6CfgData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug To delete the default route entry in this Ip, if it is:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // @bug its code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip4->Routes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TRUE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mZeroIp4Addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mZeroIp4Addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mZeroIp4Addr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktRcvdNotify = OpenData->PktRcvdNotify;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->PktSentNotify = OpenData->PktSentNotify;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->RcvdContext = OpenData->RcvdContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->SndContext = OpenData->SndContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Protocol = OpenData->IpConfigData.Ip4CfgData.DefaultProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // start to listen incoming packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip4->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(IpIo->RcvToken.Ip4Token)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ErrorExit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Protocol = OpenData->IpConfigData.Ip6CfgData.DefaultProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip6->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(IpIo->RcvToken.Ip6Token)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ErrorExit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->IsConfigured = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&mActiveIpIoList, &IpIo->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncErrorExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stop an IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is paired with IpIoOpen(). The IP_IO will be unconfigured and all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the pending send/receive tokens will be canceled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to the IP_IO instance that needs to stop.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP_IO instance stopped successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Error condition occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoStop (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_INFO *IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IpIo->IsConfigured) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpVersion = IpIo->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the IpIo from the active IpIo list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&IpIo->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Configure NULL Ip
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->IsConfigured = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Detroy the Ip List used by IpIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!IsListEmpty (&(IpIo->IpList))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoRemoveIp (IpIo, IpInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All pending send tokens should be flushed by reseting the IP instances.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IsListEmpty (&IpIo->PendingSndList));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the receive event.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpIo->RcvToken.Ip4Token.Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpIo->RcvToken.Ip6Token.Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroy an IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is paired with IpIoCreate(). The IP_IO will be closed first.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Resource will be freed afterwards. See IpIoCloseProtocolDestroyIpChild().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to the IP_IO instance that needs to be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync destroyed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP_IO instance destroyed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Error condition occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoDestroy (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stop the IpIo.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoStop (IpIo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the IP protocol and destroy the child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoCloseProtocolDestroyIpChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->IpVersion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool (IpIo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send out an IP packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is called after IpIoOpen(). The data to be sent are wrapped in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pkt. The IP instance wrapped in IpIo is used for sending by default but can be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync overriden by Sender. Other sending configs, like source address and gateway
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address etc., are specified in OverrideData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to an IP_IO instance used for sending IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pkt Pointer to the IP packet to be sent.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Sender The IP protocol instance used for sending.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context Optional context data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NotifyData Optional notify data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Dest The destination IP address to send this packet to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] OverrideData The data to override some configuration of the IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance used for sending.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation is completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED The IpIo is not configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoSend (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT NET_BUF *Pkt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_IP_INFO *Sender OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *NotifyData OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP_ADDRESS *Dest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_OVERRIDE *OverrideData OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_PROTOCOL Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_SEND_ENTRY *SndEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpIo->IpVersion != IP_VERSION_4) || (Dest != NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IpIo->IsConfigured) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // create a new SndEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NULL == SndEntry) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send this Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip4->Transmit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SndEntry->SndToken.Ip4Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip6->Transmit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SndEntry->SndToken.Ip6Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoDestroySndEntry (SndEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cancel the IP transmit token which wraps this Packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet Pointer to the packet of NET_BUF to cancel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoCancelTxToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_SEND_ENTRY *SndEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_PROTOCOL Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpIo != NULL) && (Packet != NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SndEntry->Pkt == Packet) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip = SndEntry->Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4->Cancel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SndEntry->SndToken.Ip4Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6->Cancel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &SndEntry->SndToken.Ip6Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add a new IP instance for sending data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The function is used to add the IP_IO to the IP_IO sending list. The caller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync can later use IpIoFindSender() to get the IP_IO and call IpIoSend() to send
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to a IP_IO instance to add a new IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance for sending purpose.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the created IP_IO_IP_INFO structure, NULL if failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIP_IO_IP_INFO *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoAddIp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO *IpIo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_INFO *IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpIo != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpInfo->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->ChildHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->RefCnt = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->IpVersion = IpIo->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the IP instance and open the IP protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpIoCreateIpChildOpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->IpVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &IpInfo->Ip
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ReleaseIpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the event for the DummyRcvToken.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_NOTIFY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoDummyHandler,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ReleaseIpChild;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->DummyRcvToken.Ip4Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->DummyRcvToken.Ip6Token.Event = Event;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Link this IpInfo into the IpIo.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&IpIo->IpList, &IpInfo->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReleaseIpChild:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoCloseProtocolDestroyIpChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->IpVersion
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReleaseIpInfo:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool (IpInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Configure the IP instance of this IpInfo and start the receiving if IpConfigData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is not NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpInfo Pointer to the IP_IO_IP_INFO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpConfigData The IP configure data used to configure the IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance, if NULL the IP instance is reset. If
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UseDefaultAddress is set to TRUE, and the configure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation succeeds, the default address information
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is written back in this IpConfigData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP instance of this IpInfo is configured successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or no need to reconfigure it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Configuration fails.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoConfigIp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO_IP_INFO *IpInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT VOID *IpConfigData OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_PROTOCOL Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP4_MODE_DATA Ip4ModeData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_MODE_DATA Ip6ModeData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpInfo != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->RefCnt > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This IP instance is shared, don't reconfigure it until it has only one
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // consumer. Currently, only the tcp children cloned from their passive parent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will share the same IP. So this cases only happens while IpConfigData is NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // let the last consumer clean the IP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpVersion = IpInfo->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip = IpInfo->Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip4->Configure (Ip.Ip4, IpConfigData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip6->Configure (Ip.Ip6, IpConfigData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnExit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpConfigData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((EFI_IP4_CONFIG_DATA *) IpConfigData)->UseDefaultAddress) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4->GetModeData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip4ModeData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((EFI_IP4_CONFIG_DATA*) IpConfigData)->StationAddress = Ip4ModeData.ConfigData.StationAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((EFI_IP4_CONFIG_DATA*) IpConfigData)->SubnetMask = Ip4ModeData.ConfigData.SubnetMask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->Addr.Addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &((EFI_IP4_CONFIG_DATA *) IpConfigData)->StationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (IP4_ADDR)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->PreMask.SubnetMask,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &((EFI_IP4_CONFIG_DATA *) IpConfigData)->SubnetMask,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (IP4_ADDR)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip4->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->DummyRcvToken.Ip4Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip4->Configure (Ip.Ip4, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6->GetModeData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.IsConfigured) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &((EFI_IP6_CONFIG_DATA *) IpConfigData)->StationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData.ConfigData.StationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.AddressList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.AddressList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.GroupTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.GroupTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.RouteTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.RouteTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.NeighborCache != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.NeighborCache);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.PrefixTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.PrefixTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData.IcmpTypeList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData.IcmpTypeList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NO_MAPPING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto OnExit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->Addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData.ConfigData.StationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip.Ip6->Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInfo->DummyRcvToken.Ip6Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip.Ip6->Configure (Ip.Ip6, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The IP instance is reset, set the stored Addr and SubnetMask to zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOnExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroy an IP instance maintained in IpIo->IpList for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sending purpose.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function pairs with IpIoAddIp(). The IpInfo is previously created by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoAddIp(). The IP_IO_IP_INFO::RefCnt is decremented and the IP instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync will be dstroyed if the RefCnt is zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpInfo Pointer to the IpInfo to be removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoRemoveIp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO_IP_INFO *IpInfo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpInfo->RefCnt > 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_PUT_REF (IpInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->RefCnt > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpVersion = IpIo->IpVersion;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&IpInfo->Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip4->Configure (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoCloseProtocolDestroyIpChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_VERSION_4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpInfo->DummyRcvToken.Ip4Token.Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip6->Configure (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->Ip.Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoCloseProtocolDestroyIpChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIo->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo->ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_VERSION_6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpInfo->DummyRcvToken.Ip6Token.Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the first IP protocol maintained in IpIo whose local
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address is the same as Src.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is called when the caller needs the IpIo to send data to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified Src. The IpIo was added previously by IpIoAddIp().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpIo Pointer to the pointer of the IP_IO instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpVersion The version of the IP protocol to use, either
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv4 or IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Src The local IP address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the IP protocol can be used for sending purpose and its local
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address is the same with Src.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIP_IO_IP_INFO *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoFindSender (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP_IO **IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IpVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP_ADDRESS *Src
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *IpIoEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO *IpIoPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *IpInfoEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP_IO_IP_INFO *IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((*IpIo != NULL) && (*IpIo != IpIoPtr)) || (IpIoPtr->IpVersion != IpVersion)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInfo->IpVersion == IP_VERSION_4){
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_IP4_EQUAL (&IpInfo->Addr.v4, &Src->v4)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IpIo = IpIoPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_IP6_EQUAL (&IpInfo->Addr.v6, &Src->v6)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IpIo = IpIoPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IpInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No match.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the ICMP error map information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ErrorStatus will be returned. The IsHard and Notify are optional. If they
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are not NULL, this routine will fill them.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IcmpError IcmpError Type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpVersion The version of the IP protocol to use,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync either IPv4 or IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] IsHard If TRUE, indicates that it is a hard error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Notify If TRUE, SockError needs to be notified.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return ICMP Error Status, such as EFI_NETWORK_UNREACHABLE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoGetIcmpErrStatus (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IcmpError,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 IpVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *IsHard OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *Notify OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpVersion == IP_VERSION_4 ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IcmpError <= ICMP_ERR_PARAMPROB);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsHard != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsHard = mIcmpErrMap[IcmpError].IsHard;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Notify != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Notify = mIcmpErrMap[IcmpError].Notify;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (IcmpError) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_UNREACH_NET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NETWORK_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_TIMXCEED_INTRANS:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_TIMXCEED_REASS:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_UNREACH_HOST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_HOST_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_UNREACH_PROTOCOL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PROTOCOL_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_UNREACH_PORT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PORT_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_MSGSIZE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_UNREACH_SRCFAIL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_QUENCH:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_ERR_PARAMPROB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ICMP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IpVersion == IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IcmpError <= ICMP6_ERR_PARAMPROB_IPV6OPTION);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsHard != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsHard = mIcmp6ErrMap[IcmpError].IsHard;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Notify != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Notify = mIcmp6ErrMap[IcmpError].Notify;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (IcmpError) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_UNREACH_NET:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NETWORK_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_UNREACH_HOST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_TIMXCEED_HOPLIMIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_TIMXCEED_REASS:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_HOST_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_UNREACH_PROTOCOL:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PROTOCOL_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_UNREACH_PORT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PORT_UNREACHABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_PACKAGE_TOOBIG:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_PARAMPROB_HEADER:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_PARAMPROB_NEXHEADER:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP6_ERR_PARAMPROB_IPV6OPTION:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ICMP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Should never be here
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Refresh the remote peer's Neighbor Cache entries.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is called when the caller needs the IpIo to refresh the existing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv6 neighbor cache entries since the neighbor is considered reachable by the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync node has recently received a confirmation that packets sent recently to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync neighbor were received by its IP layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpIo Pointer to an IP_IO instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Neighbor The IP address of the neighbor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Timeout Time in 100-ns units that this entry will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync remain in the neighbor cache. A value of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync zero means that the entry is permanent.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync A value of non-zero means that the entry is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dynamic and will be deleted after Timeout.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation is completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED The IpIo is not configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Neighbor Address is invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The neighbor cache entry is not in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync neighbor table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIpIoRefreshNeighbor (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP_IO *IpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP_ADDRESS *Neighbor,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Timeout
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_PROTOCOL *Ip;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IpIo->IsConfigured || IpIo->IpVersion != IP_VERSION_6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip = IpIo->Ip.Ip6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip->Neighbors (Ip, FALSE, &Neighbor->v6, NULL, Timeout, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync