DxeIpIoLib.c revision 687a2e5f6902fa26c7a1d7a7705e0747c4095125
1cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** @file 2cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 3cbf316f20726bb31b7c37424601643790dbd02d9vanjeffCopyright (c) 2005 - 2007, Intel Corporation 4cbf316f20726bb31b7c37424601643790dbd02d9vanjeffAll rights reserved. This program and the accompanying materials 5cbf316f20726bb31b7c37424601643790dbd02d9vanjeffare licensed and made available under the terms and conditions of the BSD License 6cbf316f20726bb31b7c37424601643790dbd02d9vanjeffwhich accompanies this distribution. The full text of the license may be found at 7cbf316f20726bb31b7c37424601643790dbd02d9vanjeffhttp://opensource.org/licenses/bsd-license.php 8cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9cbf316f20726bb31b7c37424601643790dbd02d9vanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10cbf316f20726bb31b7c37424601643790dbd02d9vanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12cbf316f20726bb31b7c37424601643790dbd02d9vanjeffModule Name: 13cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 14cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo.c 15cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 16cbf316f20726bb31b7c37424601643790dbd02d9vanjeffAbstract: 17cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 18cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The implementation of the IpIo layer. 19cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 20cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 21cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 22cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 23cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <PiDxe.h> 24cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 25cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Protocol/Udp4.h> 26cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 27cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/IpIoLib.h> 28cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/BaseLib.h> 29cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/DebugLib.h> 30cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/UefiBootServicesTableLib.h> 31cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/MemoryAllocationLib.h> 32cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 33cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 34cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#define NET_PROTO_HDR(Buf, Type) ((Type *) ((Buf)->BlockOp[0].Head)) 35cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#define ICMP_ERRLEN(IpHdr) \ 36cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (sizeof(IP4_ICMP_HEAD) + EFI_IP4_HEADER_LEN(IpHdr) + 8) 37cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 38cbf316f20726bb31b7c37424601643790dbd02d9vanjeffNET_LIST_ENTRY mActiveIpIoList = { 39cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList, 40cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList 41cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 42cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 43cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_IP4_CONFIG_DATA mIpIoDefaultIpConfigData = { 44cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP_PROTO_UDP, 45cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 46cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TRUE, 47cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 48cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 49cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 50cbf316f20726bb31b7c37424601643790dbd02d9vanjeff {0, 0, 0, 0}, 51cbf316f20726bb31b7c37424601643790dbd02d9vanjeff {0, 0, 0, 0}, 52cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 53cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 255, 54cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 55cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 56cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 57cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0 58cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 59cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 60cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 61cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 62cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 63cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoTransmitHandler ( 64cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 65cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 66cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 67cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 68cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 69cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 70cbf316f20726bb31b7c37424601643790dbd02d9vanjeff This function create an ip child ,open the IP protocol, return the opened 71cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip protocol to Interface. 72cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 73cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ControllerHandle The controller handle. 74cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ImageHandle The image handle. 75cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ChildHandle Pointer to the buffer to save the ip child handle. 76cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Interface Pointer used to get the ip protocol interface. 77cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 78cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The ip child is created and the ip protocol 79cbf316f20726bb31b7c37424601643790dbd02d9vanjeff interface is retrieved. 80cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval other The required operation failed. 81cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 82cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 83cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 84cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 85cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateIpChildOpenProtocol ( 86cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 87cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 88cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE *ChildHandle, 89cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT VOID **Interface 90cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 91cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 92cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 93cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 94cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 95cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create an ip child. 96cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 97cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibCreateServiceChild ( 98cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 99cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 100cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 101cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 102cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 103cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 104cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 105cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Open the ip protocol installed on the *ChildHandle. 109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->OpenProtocol ( 111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle, 112cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 113cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Interface, 114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_OPEN_PROTOCOL_BY_DRIVER 117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 120cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // On failure, destroy the ip child. 121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 122cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetLibDestroyServiceChild ( 123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 124cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 126cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle 127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 128cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff This function close the previously openned ip protocol and destroy the ip child. 136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ControllerHandle The controller handle. 138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ImageHandle the image handle. 139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param ChildHandle The child handle of the ip child. 140cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The ip protocol is closed and the relevant ip child 142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is destroyed. 143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval other The required operation failed. 144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 146cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 147cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 148cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCloseProtocolDestroyIpChild ( 149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ChildHandle 152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 153cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 155cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 156cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 157cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the previously openned ip protocol. 158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 159cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseProtocol ( 160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle, 161cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle 164cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 167cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Destroy the ip child. 168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibDestroyServiceChild ( 170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 181cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Handle ICMP packets. 182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance. 184cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Pkt Pointer to the ICMP packet. 185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Session Pointer to the net session of this ICMP packet. 186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The ICMP packet is handled successfully. 188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_ABORTED This type of ICMP packet is not supported. 189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 191cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 192cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 193cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoIcmpHandler ( 194cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN NET_BUF *Pkt, 196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_NET_SESSION_DATA *Session 197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 198cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP4_ICMP_ERROR_HEAD *IcmpHdr; 200cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_HEADER *IpHdr; 201cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ICMP_ERROR IcmpErr; 202cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 *PayLoadHdr; 203cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Type; 204cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Code; 205cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT32 TrimBytes; 206cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 207cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD); 208cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpHdr = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead); 209cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 210cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 211cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Check the ICMP packet length. 212cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) { 214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Type = IcmpHdr->Head.Type; 219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Code = IcmpHdr->Head.Code; 220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Analyze the ICMP Error in this ICMP pkt 223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Type) { 225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_UNREACH: 226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Code) { 227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET: 228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST: 229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PROTOCOL: 230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PORT: 231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_SRCFAIL: 2324eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (ICMP_ERR_UNREACH_NET + Code); 233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NEEDFRAG: 237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_MSGSIZE; 238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_UNKNOWN: 242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_PROHIB: 243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSNET: 244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_NET; 245cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_UNKNOWN: 249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_ISOLATED: 250cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_PROHIB: 251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSHOST: 252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_HOST; 253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_TIMXCEED: 265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 268cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2694eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (Code + ICMP_ERR_TIMXCEED_INTRANS); 270cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 272cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_PARAMPROB: 274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 275cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 276cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 277cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 278cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_PARAMPROB; 279cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 280cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 281cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 282cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_SOURCEQUENCH: 283cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code != 0) { 284cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 285cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_QUENCH; 288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 292cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Notify user the ICMP pkt only containing payload except 299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // IP and ICMP header 300cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr)); 302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr); 303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufTrim (Pkt, TrimBytes, TRUE); 305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext); 307cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 308cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 309cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 310cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 311cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 312cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 313cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ext free function for net buffer. This function is 314cbf316f20726bb31b7c37424601643790dbd02d9vanjeff called when the net buffer is freed. It is used to 315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff signal the recycle event to notify IP to recycle the 316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff data buffer. 317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Event The event to be signaled. 319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 323cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 324cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 325cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoExtFree ( 326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Event 327cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 329cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent ((EFI_EVENT) Event); 330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 331cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 332cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 333cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 334cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a send entry to wrap a packet before sending 335cbf316f20726bb31b7c37424601643790dbd02d9vanjeff out it through IP. 336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance. 338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Pkt Pointer to the packet. 339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Sender Pointer to the IP sender. 340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param NotifyData Pointer to the notify data. 341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Dest Pointer to the destination IP address. 342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Override Pointer to the overriden IP_IO data. 343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the data structure created to wrap the packet. If NULL, 345cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return resource limit occurred. 346cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 347cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 348cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 349cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_SEND_ENTRY * 350cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateSndEntry ( 351cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 352cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN NET_BUF *Pkt, 353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_IP4_PROTOCOL *Sender, 354cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context OPTIONAL, 355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *NotifyData OPTIONAL, 356cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP4_ADDR Dest, 357cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_OVERRIDE *Override 358cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 359cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 360cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 361cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *SndToken; 362cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 363cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 364cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_OVERRIDE_DATA *OverrideData; 36534edf2ae729941a6203e4e7f614db32204a9c47dvanjeff volatile UINT32 Index; 366cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 367cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 368cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndEntry 369cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = NetAllocatePool (sizeof (IP_IO_SEND_ENTRY)); 371cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 372cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 373cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 374cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 375cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndToken 377cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 378cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndToken = NetAllocatePool (sizeof (EFI_IP4_COMPLETION_TOKEN)); 379cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndToken) { 380cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndEntry; 381cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 382cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 383cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 384cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 385cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_TPL_EVENT, 386cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoTransmitHandler, 387cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry, 388cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(SndToken->Event) 389cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 390cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 391cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndToken; 392cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 393cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 394cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 395cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for TxData 396cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 397cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData = NetAllocatePool ( 398cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_TRANSMIT_DATA) + 399cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_FRAGMENT_DATA) * (Pkt->BlockOpNum - 1) 400cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 401cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 402cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == TxData) { 403cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseEvent; 404cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 405cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 406cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 407cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for OverrideData if needed 408cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 409cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OverrideData = NULL; 410cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != Override) { 411cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 412cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OverrideData = NetAllocatePool (sizeof (EFI_IP4_OVERRIDE_DATA)); 413cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == OverrideData) { 414cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseResource; 415cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 416cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 417cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of OverrideData 418cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 419cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *OverrideData = * (EFI_IP4_OVERRIDE_DATA *) Override; 420cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 421cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 422cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 423cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of TxData 424cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 425cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4 (TxData->DestinationAddress) = Dest; 426cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OverrideData = OverrideData; 427cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsLength = 0; 428cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsBuffer = NULL; 429cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->TotalDataLength = Pkt->TotalSize; 430cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentCount = Pkt->BlockOpNum; 431cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 432cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 43334edf2ae729941a6203e4e7f614db32204a9c47dvanjeff for (Index = 0; Index < Pkt->BlockOpNum; Index++) { 434cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentBuffer = Pkt->BlockOp[Index].Head; 435cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentLength = Pkt->BlockOp[Index].Size; 436cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 437cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 438cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 439cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndToken 440cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 441cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndToken->Packet.TxData = TxData; 442cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 443cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 444cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndEntry 445cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 446cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->IpIo = IpIo; 447cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Ip = Sender; 448cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context = Context; 449cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData = NotifyData; 450cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 451cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Pkt = Pkt; 452cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_GET_REF (Pkt); 453cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 454cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken = SndToken; 455cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 456cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInsertTail (&IpIo->PendingSndList, &SndEntry->Entry); 457cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 458cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return SndEntry; 459cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 460cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseResource: 461cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (TxData); 462cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 463cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseEvent: 464cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndToken->Event); 465cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 466cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndToken: 467cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (SndToken); 468cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 469cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndEntry: 470cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (SndEntry); 471cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 472cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 473cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 474cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 475cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 476cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 477cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy the SndEntry. 478cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 479cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param SndEntry Pointer to the send entry to be destroyed. 480cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 481cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 482cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 483cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 484cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 485cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 486cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroySndEntry ( 487cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_SEND_ENTRY *SndEntry 488cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 489cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 490cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 491cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 492cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData = SndEntry->SndToken->Packet.TxData; 493cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 494cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != TxData->OverrideData) { 495cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (TxData->OverrideData); 496cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 497cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 498cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (TxData); 499cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (SndEntry->Pkt); 500cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndEntry->SndToken->Event); 501cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 502cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (SndEntry->SndToken); 503cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListRemoveEntry (&SndEntry->Entry); 504cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 505cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (SndEntry); 506cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 507cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 508cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 509cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 510cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Notify function for IP transmit token. 511cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 512cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Event The event signaled. 513cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Context The context passed in by the event notifier. 514cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 515cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 516cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 517cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 518cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 519cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 520cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 521cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoTransmitHandler ( 522cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 523cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 524cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 525cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 526cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 527cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 528cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 529cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = (IP_IO_SEND_ENTRY *) Context; 530cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 531cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = SndEntry->IpIo; 532cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 533cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpIo->PktSentNotify && SndEntry->NotifyData) { 534cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify ( 535cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken->Status, 536cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context, 537cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Ip, 538cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData 539cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 540cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 541cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 542cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 543cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 544cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 545cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 546cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 547cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The dummy handler for the dummy IP receive token. 548cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 549cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Evt The event signaled. 550cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Context The context passed in by the event notifier. 551cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 552cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 553cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 554cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 555cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 556cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 557cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 558cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDummyHandler ( 559cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 560cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 561cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 562cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 563cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 564cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *DummyToken; 565cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 566cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (Event && Context); 567cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 568cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = (IP_IO_IP_INFO *) Context; 569cbf316f20726bb31b7c37424601643790dbd02d9vanjeff DummyToken = &(IpInfo->DummyRcvToken); 570cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 571cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_SUCCESS == DummyToken->Status) { 572cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (DummyToken->Packet.RxData); 573cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 574cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (DummyToken->Packet.RxData->RecycleSignal); 575cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 576cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 577cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Receive (IpInfo->Ip, DummyToken); 578cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 579cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 580cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 581cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 582cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Notify function for the IP receive token, used to process 583cbf316f20726bb31b7c37424601643790dbd02d9vanjeff the received IP packets. 584cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 585cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Event The event signaled. 586cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Context The context passed in by the event notifier. 587cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 588cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 589cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 590cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 591cbf316f20726bb31b7c37424601643790dbd02d9vanjeffSTATIC 592cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 593cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 594cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoListenHandler ( 595cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 596cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 597cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 598cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 599cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 600cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 601cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_RECEIVE_DATA *RxData; 602cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 603cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_NET_SESSION_DATA Session; 604cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_BUF *Pkt; 605cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 606cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = (IP_IO *) Context; 607cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 608cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 609cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIo->RcvToken.Status; 610cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData = IpIo->RcvToken.Packet.RxData; 611cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 612cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) { 613cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 614cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Only process the normal packets and the icmp error packets, if RxData is NULL 615cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although 616cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // this should be a bug of the low layer (IP). 617cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 618cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 619cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 620cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 621cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo->PktRcvdNotify) { 622cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 623cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 624cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 625cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((EFI_IP4 (RxData->Header->SourceAddress) != 0) && 626cbf316f20726bb31b7c37424601643790dbd02d9vanjeff !Ip4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), 0)) { 627cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 628cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The source address is not zero and it's not a unicast IP address, discard it. 629cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 630cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 631cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 632cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 633cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 634cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a netbuffer representing packet 635cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 636cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Pkt = NetbufFromExt ( 637cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (NET_FRAGMENT *) RxData->FragmentTable, 638cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->FragmentCount, 639cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 640cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 641cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoExtFree, 642cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->RecycleSignal 643cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 644cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == Pkt) { 645cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 646cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 647cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 648cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 649cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a net session 650cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 651cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Source = EFI_IP4 (RxData->Header->SourceAddress); 652cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Dest = EFI_IP4 (RxData->Header->DestinationAddress); 653cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.IpHdr = RxData->Header; 654cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 655cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_SUCCESS == Status) { 656cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 6574eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IpIo->PktRcvdNotify (EFI_SUCCESS, (ICMP_ERROR) 0, &Session, Pkt, IpIo->RcvdContext); 658cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 659cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 660cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Status is EFI_ICMP_ERROR 661cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 662cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoIcmpHandler (IpIo, Pkt, &Session); 663cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 664cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (Pkt); 665cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 666cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 667cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 668cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 669cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 670cbf316f20726bb31b7c37424601643790dbd02d9vanjeffCleanUp: 671cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (RxData->RecycleSignal); 672cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 673cbf316f20726bb31b7c37424601643790dbd02d9vanjeffResume: 674cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Receive (Ip, &(IpIo->RcvToken)); 675cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 676cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 677cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 678cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 679cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a new IP_IO instance. 680cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 681cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Image The image handle of an IP_IO consumer protocol. 682cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Controller The controller handle of an IP_IO consumer protocol 683cbf316f20726bb31b7c37424601643790dbd02d9vanjeff installed on. 684cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 685cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to a newly created IP_IO instance. 686cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 687cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 688cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO * 689cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreate ( 690cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Image, 691cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Controller 692cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 693cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 694cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 695cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 696cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 697cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = NetAllocateZeroPool (sizeof (IP_IO)); 698cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo) { 699cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 700cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 701cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 702cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInit (&(IpIo->PendingSndList)); 703cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInit (&(IpIo->IpList)); 704cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller = Controller; 705cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image = Image; 706cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 707cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 708cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 709cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_TPL_EVENT, 710cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoListenHandler, 711cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo, 712cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(IpIo->RcvToken.Event) 713cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 714cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 715cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 716cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 717cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 718cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 719cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create an IP child and open IP protocol 720cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 721cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 722cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Controller, 723cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Image, 724cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpIo->ChildHandle, 725cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (VOID **)&(IpIo->Ip) 726cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 727cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 728cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 729cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 730cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 731cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpIo; 732cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 733cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpIo: 734cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 735cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != IpIo->RcvToken.Event) { 736cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 737cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 738cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 739cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (IpIo); 740cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 741cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 742cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 743cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 744cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 745cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 746cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Open an IP_IO instance for use. 747cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 748cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to an IP_IO instance that needs to open. 749cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param OpenData The configuration data for the IP_IO instance. 750cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 751cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The IP_IO instance opened with OpenData 752cbf316f20726bb31b7c37424601643790dbd02d9vanjeff successfully. 753cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval other Error condition occurred. 754cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 755cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 756cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 757cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoOpen ( 758cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 759cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_OPEN_DATA *OpenData 760cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 761cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 762cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 763cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 764cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IPv4_ADDRESS ZeroIp; 765cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 766cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpIo->IsConfigured) { 767cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ACCESS_DENIED; 768cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 769cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 770cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 771cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 772cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 773cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // configure ip 774cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 775cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, &OpenData->IpConfigData); 776cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 777cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 778cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 779cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 780cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 781cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // bugbug: to delete the default route entry in this Ip, if it is: 782cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified 783cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // its code 784cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 785cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4 (ZeroIp) = 0; 786cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Routes (Ip, TRUE, &ZeroIp, &ZeroIp, &ZeroIp); 787cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 788cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) { 789cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 790cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 791cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 792cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify = OpenData->PktRcvdNotify; 793cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify = OpenData->PktSentNotify; 794cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 795cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->RcvdContext = OpenData->RcvdContext; 796cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->SndContext = OpenData->SndContext; 797cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 798cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Protocol = OpenData->IpConfigData.DefaultProtocol; 799cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 800cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 801cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // start to listen incoming packet 802cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 803cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &(IpIo->RcvToken)); 804cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 805cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 806cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ErrorExit; 807cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 808cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 809cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = TRUE; 810cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInsertTail (&mActiveIpIoList, &IpIo->Entry); 811cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 812cbf316f20726bb31b7c37424601643790dbd02d9vanjeffErrorExit: 813cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 814cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 815cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 816cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 817cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 818cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 819cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Stop an IP_IO instance. 820cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 821cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance that needs to stop. 822cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 823cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The IP_IO instance stopped successfully. 824cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval other Error condition occurred. 825cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 826cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 827cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 828cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoStop ( 829cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo 830cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 831cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 832cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 833cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 834cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 835cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 836cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 837cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 838cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 839cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 840cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 841cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Remove the IpIo from the active IpIo list. 842cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 843cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListRemoveEntry (&IpIo->Entry); 844cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 845cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 846cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 847cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 848cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Configure NULL Ip 849cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 850cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, NULL); 851cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 852cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 853cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 854cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 855cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = FALSE; 856cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 857cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 858cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Detroy the Ip List used by IpIo 859cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 86034edf2ae729941a6203e4e7f614db32204a9c47dvanjeff 861cbf316f20726bb31b7c37424601643790dbd02d9vanjeff while (!NetListIsEmpty (&(IpIo->IpList))) { 862cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry); 863cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 864cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoRemoveIp (IpIo, IpInfo); 865cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 866cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 867cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 868cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // All pending snd tokens should be flushed by reseting the IP instances. 869cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 870cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (NetListIsEmpty (&IpIo->PendingSndList)); 871cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 872cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 873cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the receive event. 874cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 875cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 876cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 877cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 878cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 879cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 880cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 881cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 882cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP_IO instance. 883cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 884cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance that needs to 885cbf316f20726bb31b7c37424601643790dbd02d9vanjeff destroy. 886cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 887cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The IP_IO instance destroyed successfully. 888cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval other Error condition occurred. 889cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 890cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 891cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 892cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroy ( 893cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo 894cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 895cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 896cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 897cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Stop the IpIo. 898cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 899cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoStop (IpIo); 900cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 901cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 902cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the IP protocol and destroy the child. 903cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 904cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpIo->ChildHandle); 905cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 906cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (IpIo); 907cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 908cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 909cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 910cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 911cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 912cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 913cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Send out an IP packet. 914cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 915cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to an IP_IO instance used for sending IP 916cbf316f20726bb31b7c37424601643790dbd02d9vanjeff packet. 917cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Pkt Pointer to the IP packet to be sent. 918cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Sender The IP protocol instance used for sending. 919cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param NotifyData 920cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Dest The destination IP address to send this packet to. 921cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param OverrideData The data to override some configuration of the IP 922cbf316f20726bb31b7c37424601643790dbd02d9vanjeff instance used for sending. 923cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 924cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_SUCCESS The operation is completed successfully. 925cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_NOT_STARTED The IpIo is not configured. 926cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. 927cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 928cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 929cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 930cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoSend ( 931cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 932cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN NET_BUF *Pkt, 933cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_IP_INFO *Sender, 934cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context OPTIONAL, 935cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *NotifyData OPTIONAL, 936cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP4_ADDR Dest, 937cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_OVERRIDE *OverrideData 938cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 939cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 940cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 941cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 942cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 943cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 944cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 945cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_NOT_STARTED; 946cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 947cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 948cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip; 949cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 950cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 951cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // create a new SndEntry 952cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 953cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData); 954cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 955cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_OUT_OF_RESOURCES; 956cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 957cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 958cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 959cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Send this Packet 960cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 961cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Transmit (Ip, SndEntry->SndToken); 962cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 963cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 964cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 965cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 966cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 967cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 968cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 969cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 970cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 971cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Cancel the IP transmit token which wraps this Packet. 972cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 973cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance. 974cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Packet Pointer to the packet to cancel. 975cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 976cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return N/A. 977cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 978cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 979cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 980cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCancelTxToken ( 981cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 982cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Packet 983cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 984cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 985cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_ENTRY *Node; 986cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 987cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 988cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 989cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpIo && Packet); 990cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 991cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) { 992cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 993cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry); 994cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 995cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (SndEntry->Pkt == Packet) { 996cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 997cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = SndEntry->Ip; 998cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Cancel (Ip, SndEntry->SndToken); 999cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1000cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1001cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Abort the user token. 1002cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1003cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken->Status = EFI_ABORTED; 1004cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoTransmitHandler (NULL, SndEntry); 1005cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1006cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 1007cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1008cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1009cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1010cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1011cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1012cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1013cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1014cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Add a new IP instance for sending data. 1015cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1016cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to a IP_IO instance to add a new IP 1017cbf316f20726bb31b7c37424601643790dbd02d9vanjeff instance for sending purpose. 1018cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1019cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the created IP_IO_IP_INFO structure, NULL is failed. 1020cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1021cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1022cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 1023cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoAddIp ( 1024cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo 1025cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1026cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1027cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1028cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1029cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1030cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpIo); 1031cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1032cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NetAllocatePool (sizeof (IP_IO_IP_INFO)); 1033cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo == NULL) { 1034cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1035cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1036cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1037cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1038cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP 1039cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // instance. 1040cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1041cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInit (&IpInfo->Entry); 1042cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle = NULL; 1043cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1044cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask = 0; 1045cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->RefCnt = 1; 1046cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1047cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1048cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the IP instance and open the Ip4 protocol. 1049cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1050cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 1051cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1052cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1053cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->ChildHandle, 10544eb65aff715faafd9040c6fc85a5d59e22343978vanjeff (VOID **) &IpInfo->Ip 1055cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1056cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1057cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpInfo; 1058cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1059cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1060cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1061cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the event for the DummyRcvToken. 1062cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1063cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 1064cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 1065cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_TPL_EVENT, 1066cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDummyHandler, 1067cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo, 1068cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->DummyRcvToken.Event 1069cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1070cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1071cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpChild; 1072cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1073cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1074cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1075cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Link this IpInfo into the IpIo. 1076cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1077cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListInsertTail (&IpIo->IpList, &IpInfo->Entry); 1078cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1079cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1080cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1081cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpChild: 1082cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1083cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild ( 1084cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1085cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1086cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle 1087cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1088cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1089cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpInfo: 1090cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1091cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (IpInfo); 1092cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1093cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1094cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1095cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1096cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1097cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1098cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Configure the IP instance of this IpInfo and start the receiving if Ip4ConfigData 1099cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is not NULL. 1100cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1101cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpInfo Pointer to the IP_IO_IP_INFO instance. 1102cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Ip4ConfigData The IP4 configure data used to configure the ip 1103cbf316f20726bb31b7c37424601643790dbd02d9vanjeff instance, if NULL the ip instance is reseted. If 1104cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UseDefaultAddress is set to TRUE, and the configure 1105cbf316f20726bb31b7c37424601643790dbd02d9vanjeff operation succeeds, the default address information 1106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is written back in this Ip4ConfigData. 1107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @retval EFI_STATUS The status returned by IP4->Configure or 1109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP4->Receive. 1110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1112cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 1113cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoConfigIp ( 1114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_IP_INFO *IpInfo, 1115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT EFI_IP4_CONFIG_DATA *Ip4ConfigData OPTIONAL 1116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1120cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_MODE_DATA Ip4ModeData; 1121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1122cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpInfo); 1123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1124cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 1) { 1125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1126cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // This IP instance is shared, don't reconfigure it until it has only one 1127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // consumer. Currently, only the tcp children cloned from their passive parent 1128cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // will share the same IP. So this cases only happens while Ip4ConfigData is NULL, 1129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // let the last consumer clean the IP instance. 1130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpInfo->Ip; 1135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, Ip4ConfigData); 1137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto OnExit; 1139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1140cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData != NULL) { 1142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData->UseDefaultAddress) { 1144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->GetModeData (Ip, &Ip4ModeData, NULL, NULL); 1145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1146cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->StationAddress = Ip4ModeData.ConfigData.StationAddress; 1147cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->SubnetMask = Ip4ModeData.ConfigData.SubnetMask; 1148cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = EFI_IP4 (Ip4ConfigData->StationAddress); 1151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask = EFI_IP4 (Ip4ConfigData->SubnetMask); 1152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1153cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &IpInfo->DummyRcvToken); 1154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1155cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 1156cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1157cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 1158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1159cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The IP instance is reseted, set the stored Addr and SubnetMask to zero. 1161cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask =0; 1164cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1166cbf316f20726bb31b7c37424601643790dbd02d9vanjeffOnExit: 1167cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP instance maintained in IpIo->IpList for 1174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sending purpose. 1175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the IP_IO instance. 1177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpInfo Pointer to the IpInfo to be removed. 1178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return None. 1180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1181cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1182cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 1183cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoRemoveIp ( 1184cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 1185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_IP_INFO *IpInfo 1186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpInfo->RefCnt > 0); 1189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_PUT_REF (IpInfo); 1191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 0) { 1193cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1194cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return; 1195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetListRemoveEntry (&IpInfo->Entry); 1198cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Configure (IpInfo->Ip, NULL); 1200cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1201cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpInfo->ChildHandle); 1202cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1203cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpInfo->DummyRcvToken.Event); 1204cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1205cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetFreePool (IpInfo); 1206cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1207cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1208cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1209cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1210cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Find the first IP protocol maintained in IpIo whose local 1211cbf316f20726bb31b7c37424601643790dbd02d9vanjeff address is the same with Src. 1212cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IpIo Pointer to the pointer of the IP_IO instance. 1214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Src The local IP address. 1215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the IP protocol can be used for sending purpose and its local 1217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return address is the same with Src. 1218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1220cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 1221cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoFindSender ( 1222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT IP_IO **IpIo, 1223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP4_ADDR Src 1224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_ENTRY *IpIoEntry; 1227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIoPtr; 1228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_ENTRY *IpInfoEntry; 1229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) { 1232cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry); 1233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((*IpIo != NULL) && (*IpIo != IpIoPtr)) { 1235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff continue; 1236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) { 1239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry); 1240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->Addr == Src) { 1242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *IpIo = IpIoPtr; 1243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1245cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // No match. 1250cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Get the ICMP error map information, the ErrorStatus will be returned. 1257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The IsHard and Notify are optional. If they are not NULL, this rouine will 1258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff fill them. 1259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff We move IcmpErrMap[] to local variable to enable EBC build. 1260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IcmpError IcmpError Type 1262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param IsHard Whether it is a hard error 1263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @param Notify Whether it need to notify SockError 1264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return ICMP Error Status 1266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1268cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 1269cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoGetIcmpErrStatus ( 1270cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN ICMP_ERROR IcmpError, 1271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT BOOLEAN *IsHard, OPTIONAL 1272cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT BOOLEAN *Notify OPTIONAL 1273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1275687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff ICMP_ERROR_INFO IcmpErrMap[10]; 1276687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1277687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[0].Error = EFI_NETWORK_UNREACHABLE; 1278687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[0].IsHard = FALSE; 1279687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[0].Notify = TRUE; 1280687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1281687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[1].Error = EFI_HOST_UNREACHABLE; 1282687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[1].IsHard = FALSE; 1283687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[1].Notify = TRUE; 1284687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1285687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[2].Error = EFI_PROTOCOL_UNREACHABLE; 1286687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[2].IsHard = TRUE; 1287687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[2].Notify = TRUE; 1288687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1289687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[3].Error = EFI_PORT_UNREACHABLE; 1290687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[3].IsHard = TRUE; 1291687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[3].Notify = TRUE; 1292687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1293687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[4].Error = EFI_ICMP_ERROR; 1294687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[4].IsHard = TRUE; 1295687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[4].Notify = TRUE; 1296687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1297687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[5].Error = EFI_ICMP_ERROR; 1298687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[5].IsHard = FALSE; 1299687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[5].Notify = TRUE; 1300687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1301687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[6].Error = EFI_HOST_UNREACHABLE; 1302687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[6].IsHard = FALSE; 1303687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[6].Notify = TRUE; 1304687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1305687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[7].Error = EFI_HOST_UNREACHABLE; 1306687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[7].IsHard = FALSE; 1307687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[7].Notify = TRUE; 1308687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1309687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[8].Error = EFI_ICMP_ERROR; 1310687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[8].IsHard = FALSE; 1311687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[8].Notify = FALSE; 1312687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 1313687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[9].Error = EFI_ICMP_ERROR; 1314687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[9].IsHard = FALSE; 1315687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff IcmpErrMap[9].Notify = TRUE; 1316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT ((IcmpError >= ICMP_ERR_UNREACH_NET) && (IcmpError <= ICMP_ERR_PARAMPROB)); 1318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IsHard != NULL) { 1320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *IsHard = IcmpErrMap[IcmpError].IsHard; 1321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Notify != NULL) { 1324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *Notify = IcmpErrMap[IcmpError].Notify; 1325cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1327cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IcmpErrMap[IcmpError].Error; 1328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1329cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1330