DxeIpIoLib.c revision 8de75da28bbd9a4d3c54fba99d943f9019b52193
1cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** @file 26aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IpIo Library. 3cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 46aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywuCopyright (c) 2005 - 2007, Intel Corporation.<BR> 5cbf316f20726bb31b7c37424601643790dbd02d9vanjeffAll rights reserved. This program and the accompanying materials 6cbf316f20726bb31b7c37424601643790dbd02d9vanjeffare licensed and made available under the terms and conditions of the BSD License 7cbf316f20726bb31b7c37424601643790dbd02d9vanjeffwhich accompanies this distribution. The full text of the license may be found at 8cbf316f20726bb31b7c37424601643790dbd02d9vanjeffhttp://opensource.org/licenses/bsd-license.php 9cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10cbf316f20726bb31b7c37424601643790dbd02d9vanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11cbf316f20726bb31b7c37424601643790dbd02d9vanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 13cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu#include <Uefi.h> 15cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 16cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Protocol/Udp4.h> 17cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 18cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/IpIoLib.h> 19cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/BaseLib.h> 20cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/DebugLib.h> 21cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/UefiBootServicesTableLib.h> 22cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 23cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 24e48e37fce2611df7a52aff271835ff72ee396d9bvanjeffLIST_ENTRY mActiveIpIoList = { 25cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList, 26cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList 27cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 28cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 29cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_IP4_CONFIG_DATA mIpIoDefaultIpConfigData = { 30cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP_PROTO_UDP, 31cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 32cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TRUE, 33cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 34cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 35cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 3684b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 3784b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 38cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 39cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 255, 40cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 41cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 42cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 43cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0 44cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 45cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 46fe1e36e550c6ffcd2561903d434683d3939e1942jjiICMP_ERROR_INFO mIcmpErrMap[10] = { 4701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 4801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 4901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, FALSE}, 5601750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE} 5701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff}; 5801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff 596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 66cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 67cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 6836ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 6936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 7036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ); 7136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 736aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 756aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 766aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 776aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 786aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 796aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 8036ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 8136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 82cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoTransmitHandler ( 83cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 84cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 85cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 86cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 87cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 88cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 896aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function create an IP child ,open the IP protocol, and return the opened 90e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IP protocol as Interface. 91cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 926aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 946aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle Pointer to the buffer to save the IP child handle. 956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[out] Interface Pointer used to get the IP protocol interface. 96cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 976aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP child is created and the IP protocol 986aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu interface is retrieved. 996aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 100cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 101cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 102cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 103cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateIpChildOpenProtocol ( 104cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 105cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE *ChildHandle, 107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT VOID **Interface 108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 112cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Create an IP child. 114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibCreateServiceChild ( 116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 120cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 122cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 124cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1266aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Open the IP protocol installed on the *ChildHandle. 127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 128cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->OpenProtocol ( 129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle, 130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Interface, 132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_OPEN_PROTOCOL_BY_DRIVER 135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1386aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // On failure, destroy the IP child. 139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 140cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetLibDestroyServiceChild ( 141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle 145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 146cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 147cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 148cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 153e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function close the previously openned IP protocol and destroy the IP child. 154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1556aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 1566aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 1576aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle The child handle of the IP child. 158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP protocol is closed and the relevant IP child 1606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu is destroyed. 1616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 164cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 165cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCloseProtocolDestroyIpChild ( 166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 167cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ChildHandle 169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Close the previously openned IP protocol. 175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseProtocol ( 177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle, 178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle 181cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1846aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Destroy the IP child. 185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibDestroyServiceChild ( 187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 193cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 194cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 198e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function handles ICMP packets. 199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2006aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 2016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the ICMP packet. 2026aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Session Pointer to the net session of this ICMP packet. 203cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The ICMP packet is handled successfully. 2056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_ABORTED This type of ICMP packet is not supported. 206cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 207cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 208cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 209cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoIcmpHandler ( 2106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO *IpIo, 2116aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 2126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN EFI_NET_SESSION_DATA *Session 213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP4_ICMP_ERROR_HEAD *IcmpHdr; 216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_HEADER *IpHdr; 217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ICMP_ERROR IcmpErr; 218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 *PayLoadHdr; 219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Type; 220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Code; 221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT32 TrimBytes; 222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD); 224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpHdr = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead); 225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Check the ICMP packet length. 228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) { 230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 232cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Type = IcmpHdr->Head.Type; 235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Code = IcmpHdr->Head.Code; 236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Analyze the ICMP Error in this ICMP pkt 239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Type) { 241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_UNREACH: 242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Code) { 243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET: 244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST: 245cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PROTOCOL: 246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PORT: 247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_SRCFAIL: 2484eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (ICMP_ERR_UNREACH_NET + Code); 249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 250cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NEEDFRAG: 253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_MSGSIZE; 254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_UNKNOWN: 258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_PROHIB: 259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSNET: 260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_NET; 261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_UNKNOWN: 265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_ISOLATED: 266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_PROHIB: 267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSHOST: 268cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_HOST; 269cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 270cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 272cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 275cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 276cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 277cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 278cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_TIMXCEED: 279cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 280cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 281cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 282cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2834eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (Code + ICMP_ERR_TIMXCEED_INTRANS); 284cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 285cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_PARAMPROB: 288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 292cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_PARAMPROB; 293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_SOURCEQUENCH: 297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code != 0) { 298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 300cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_QUENCH; 302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 307cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 308cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 309cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 310cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Notify user the ICMP pkt only containing payload except 311cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // IP and ICMP header 312cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 313cbf316f20726bb31b7c37424601643790dbd02d9vanjeff PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr)); 314cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr); 315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufTrim (Pkt, TrimBytes, TRUE); 317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext); 319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 325e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Free function for receive token of IP_IO. It is used to 326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff signal the recycle event to notify IP to recycle the 327cbf316f20726bb31b7c37424601643790dbd02d9vanjeff data buffer. 328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 3296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event to be signaled. 330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 331cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 332cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 333cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoExtFree ( 334cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Event 335cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent ((EFI_EVENT) Event); 338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a send entry to wrap a packet before sending 343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff out it through IP. 344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 3456aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance. 3466aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the packet. 3476aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender Pointer to the IP sender. 3486aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context Pointer to the context. 3496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] NotifyData Pointer to the notify data. 3506aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest Pointer to the destination IP address. 3516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Override Pointer to the overriden IP_IO data. 352cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the data structure created to wrap the packet. If NULL, 3546aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return resource limit occurred. 355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 356cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 357cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_SEND_ENTRY * 358cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateSndEntry ( 3596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 3606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 3616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN EFI_IP4_PROTOCOL *Sender, 3626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 3636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 3646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP4_ADDR Dest, 3656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *Override 366cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 367cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 368cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 369cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *SndToken; 370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 371cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 372cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_OVERRIDE_DATA *OverrideData; 37334edf2ae729941a6203e4e7f614db32204a9c47dvanjeff volatile UINT32 Index; 374cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 375cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndEntry 377cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 378e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY)); 379cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 380cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 381cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 382cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 383cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 384cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndToken 385cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 386e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff SndToken = AllocatePool (sizeof (EFI_IP4_COMPLETION_TOKEN)); 387cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndToken) { 388cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndEntry; 389cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 390cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 391cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 392cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 393e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 394cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoTransmitHandler, 395cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry, 396cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(SndToken->Event) 397cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 398cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 399cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndToken; 400cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 401cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 402cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 403cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for TxData 404cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 405e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TxData = AllocatePool ( 406cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_TRANSMIT_DATA) + 407cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_FRAGMENT_DATA) * (Pkt->BlockOpNum - 1) 408cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 409cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 410cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == TxData) { 411cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseEvent; 412cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 413cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 414cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 415cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for OverrideData if needed 416cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 417cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OverrideData = NULL; 418cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != Override) { 419cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 420e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff OverrideData = AllocatePool (sizeof (EFI_IP4_OVERRIDE_DATA)); 421cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == OverrideData) { 422cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseResource; 423cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 424cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 425cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of OverrideData 426cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 42736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff CopyMem (OverrideData, Override, sizeof (*OverrideData)); 428cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 429cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 430cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 431cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of TxData 432cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 433e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&TxData->DestinationAddress, &Dest, sizeof (EFI_IPv4_ADDRESS)); 434cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OverrideData = OverrideData; 435cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsLength = 0; 436cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsBuffer = NULL; 437cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->TotalDataLength = Pkt->TotalSize; 438cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentCount = Pkt->BlockOpNum; 439cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 440cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 44134edf2ae729941a6203e4e7f614db32204a9c47dvanjeff for (Index = 0; Index < Pkt->BlockOpNum; Index++) { 442cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentBuffer = Pkt->BlockOp[Index].Head; 443cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentLength = Pkt->BlockOp[Index].Size; 444cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 445cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 446cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 447cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndToken 448cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 449cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndToken->Packet.TxData = TxData; 450cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 451cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 452cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndEntry 453cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 454cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->IpIo = IpIo; 4556aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu SndEntry->Ip = Sender; 456cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context = Context; 457cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData = NotifyData; 458cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 459cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Pkt = Pkt; 460cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_GET_REF (Pkt); 461cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 462cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken = SndToken; 463cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 464e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry); 465cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 466cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return SndEntry; 467cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 468cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseResource: 469e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData); 470cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 471cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseEvent: 472cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndToken->Event); 473cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 474cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndToken: 475e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndToken); 476cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 477cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndEntry: 478e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry); 479cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 480cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 481cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 482cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 483cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 484cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 485cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy the SndEntry. 486e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 487e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoCreateSndEntry(). 488cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 4896aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] SndEntry Pointer to the send entry to be destroyed. 490cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 491cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 492cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 493cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroySndEntry ( 494cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_SEND_ENTRY *SndEntry 495cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 496cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 497cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 498cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 499cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData = SndEntry->SndToken->Packet.TxData; 500cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 501cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != TxData->OverrideData) { 502e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData->OverrideData); 503cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 504cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 505e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData); 506cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (SndEntry->Pkt); 507cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndEntry->SndToken->Event); 508cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 509e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry->SndToken); 510e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&SndEntry->Entry); 511cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 512e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry); 513cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 514cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 515cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 516cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 517cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Notify function for IP transmit token. 518cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5196aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 520cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 521cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 522cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 523cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 52436ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 525cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 526cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 527cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 528cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 529cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 530cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 531cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = (IP_IO_SEND_ENTRY *) Context; 532cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 533cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = SndEntry->IpIo; 534cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5358de75da28bbd9a4d3c54fba99d943f9019b52193niry if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) { 536cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify ( 537cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken->Status, 538cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context, 539cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Ip, 540cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData 541cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 542cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 543cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 544cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 545cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 546cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5476aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 54836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 54936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for IP transmit token. 55036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 5516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 5526aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 55336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 55436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 55536ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 55636ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 55736ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandler ( 55836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 55936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 56036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 56136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 56236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 56336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK 56436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 56536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context); 56636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 56736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 568cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 569cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 570cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The dummy handler for the dummy IP receive token. 571cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 573cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 574cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 575cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 576cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 57736ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandlerDpc ( 578cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 579cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 580cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 581cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 582cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *DummyToken; 583cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 584cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = (IP_IO_IP_INFO *) Context; 585cbf316f20726bb31b7c37424601643790dbd02d9vanjeff DummyToken = &(IpInfo->DummyRcvToken); 586cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 58736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff if (EFI_ABORTED == DummyToken->Status) { 58836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 58936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 59036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 59136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 59236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff } else if (EFI_SUCCESS == DummyToken->Status) { 5936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT ((DummyToken->Packet.RxData)!= NULL); 594cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 595cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (DummyToken->Packet.RxData->RecycleSignal); 596cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 597cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 598cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Receive (IpInfo->Ip, DummyToken); 599cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 600cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 601cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 602cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 6036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoDummyHandlerDpc to the end of the DPC queue. 604cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 6056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 6066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 607cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 608cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 609cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 610cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 61136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandler ( 612cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 613cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 614cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 615cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 61636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 61736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK 61836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 61936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context); 62036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 62136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 62236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 62336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 62436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for the IP receive token, used to process 62536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff the received IP packets. 62636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 6276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 62836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 62936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 63036ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 63136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 63236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandlerDpc ( 63336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 63436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 63536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 636cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 637cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 638cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_RECEIVE_DATA *RxData; 639cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 640cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_NET_SESSION_DATA Session; 641cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_BUF *Pkt; 642cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 643cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = (IP_IO *) Context; 644cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 645cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 646cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIo->RcvToken.Status; 647cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData = IpIo->RcvToken.Packet.RxData; 648cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 64936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff if (EFI_ABORTED == Status) { 65036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 65136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 65236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 65336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 65436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff } 65536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 656cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) { 657cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 6586aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug Only process the normal packets and the icmp error packets, if RxData is NULL 6596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although 6606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug this should be a bug of the low layer (IP). 661cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 662cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 663cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 664cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 665cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo->PktRcvdNotify) { 666cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 667cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 668cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 669cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((EFI_IP4 (RxData->Header->SourceAddress) != 0) && 670cbf316f20726bb31b7c37424601643790dbd02d9vanjeff !Ip4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), 0)) { 671cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 672cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The source address is not zero and it's not a unicast IP address, discard it. 673cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 674cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 675cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 676cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 677cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 678cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a netbuffer representing packet 679cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 680cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Pkt = NetbufFromExt ( 681cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (NET_FRAGMENT *) RxData->FragmentTable, 682cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->FragmentCount, 683cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 684cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 685cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoExtFree, 686cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->RecycleSignal 687cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 688cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == Pkt) { 689cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 690cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 691cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 692cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 693cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a net session 694cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 695cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Source = EFI_IP4 (RxData->Header->SourceAddress); 696cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Dest = EFI_IP4 (RxData->Header->DestinationAddress); 697cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.IpHdr = RxData->Header; 698cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 699cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_SUCCESS == Status) { 700cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 7014eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IpIo->PktRcvdNotify (EFI_SUCCESS, (ICMP_ERROR) 0, &Session, Pkt, IpIo->RcvdContext); 702cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 703cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 704cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Status is EFI_ICMP_ERROR 705cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 706cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoIcmpHandler (IpIo, Pkt, &Session); 707cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 708cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (Pkt); 709cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 710cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 711cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 712cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 713cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 714cbf316f20726bb31b7c37424601643790dbd02d9vanjeffCleanUp: 715cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (RxData->RecycleSignal); 716cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 717cbf316f20726bb31b7c37424601643790dbd02d9vanjeffResume: 718cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Receive (Ip, &(IpIo->RcvToken)); 719cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 720cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 721cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 722cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 7236aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoListenHandlerDpc to the end of the DPC queue. 72436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 7256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 7266aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 72736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 72836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 72936ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 73036ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 73136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandler ( 73236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 73336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 73436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 73536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 73636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 73736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK 73836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 73936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context); 74036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 74136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 74236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 74336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 744cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a new IP_IO instance. 745e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 746e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function uses IP4 service binding protocol in Controller to create an IP4 747e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong child (aka IP4 instance). 748cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 7496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Image The image handle of the driver or application that 750e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong consumes IP_IO. 7516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Controller The controller handle that has IP4 service binding 752e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong protocol installed. 753cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 754e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to a newly created IP_IO instance, or NULL if failed. 755cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 756cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 757cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO * 7587b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 759cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreate ( 760cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Image, 761cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Controller 762cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 763cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 764cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 765cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 766cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 767e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpIo = AllocateZeroPool (sizeof (IP_IO)); 768cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo) { 769cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 770cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 771cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 772e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->PendingSndList)); 773e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->IpList)); 774cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller = Controller; 775cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image = Image; 776cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 777cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 778cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 779e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 780cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoListenHandler, 781cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo, 782cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(IpIo->RcvToken.Event) 783cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 784cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 785cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 786cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 787cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 788cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 789cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create an IP child and open IP protocol 790cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 791cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 792cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Controller, 793cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Image, 794cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpIo->ChildHandle, 795cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (VOID **)&(IpIo->Ip) 796cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 797cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 798cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 799cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 800cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 801cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpIo; 802cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 803cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpIo: 804cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 805cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != IpIo->RcvToken.Event) { 806cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 807cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 808cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 809e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 810cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 811cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 812cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 813cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 814cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 815cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 816cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Open an IP_IO instance for use. 817e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 818e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoCreate(). It is used for configuring the IP 819e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong instance and register the callbacks and their context data for sending and 820e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong receiving IP packets. 821cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8226aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance that needs 8236aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu to open. 8246aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OpenData The configuration data and callbacks for 8256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu the IP_IO instance. 826cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance opened with OpenData 8286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu successfully. 8296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_ACCESS_DENIED The IP_IO instance is configured, avoid to 8306aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu reopen it. 8316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 832cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 833cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 834cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 8357b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 836cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoOpen ( 8376aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 8386aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OPEN_DATA *OpenData 839cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 840cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 841cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 842cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 843cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 844cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpIo->IsConfigured) { 845cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ACCESS_DENIED; 846cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 847cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 848cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 849cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 850cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 851cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // configure ip 852cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 853cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, &OpenData->IpConfigData); 854cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 855cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 856cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 857cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 858cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 8596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug To delete the default route entry in this Ip, if it is: 8606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified 8616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug its code 862cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 863b61439a709bb961f2f9dff1d1a4112e30a063f51vanjeff Status = Ip->Routes (Ip, TRUE, &mZeroIp4Addr, &mZeroIp4Addr, &mZeroIp4Addr); 864cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 865cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) { 866cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 867cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 868cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 869cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify = OpenData->PktRcvdNotify; 870cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify = OpenData->PktSentNotify; 871cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 872cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->RcvdContext = OpenData->RcvdContext; 873cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->SndContext = OpenData->SndContext; 874cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 875cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Protocol = OpenData->IpConfigData.DefaultProtocol; 876cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 877cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 878cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // start to listen incoming packet 879cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 880cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &(IpIo->RcvToken)); 881cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 882cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 883cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ErrorExit; 884cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 885cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 886cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = TRUE; 887e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&mActiveIpIoList, &IpIo->Entry); 888cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 889cbf316f20726bb31b7c37424601643790dbd02d9vanjeffErrorExit: 890cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 891cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 892cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 893cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 894cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 895cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 896cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Stop an IP_IO instance. 897e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 898e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoOpen(). The IP_IO will be unconfigured and all 899e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong the pending send/receive tokens will be canceled. 900cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to stop. 902cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance stopped successfully. 9046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 905cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 906cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 907cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 908e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgongEFIAPI 909cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoStop ( 9106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 911cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 912cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 913cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 914cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 915cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 916cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 917cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 918cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 919cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 920cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 921cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 922cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Remove the IpIo from the active IpIo list. 923cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 924e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpIo->Entry); 925cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 926cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 927cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 928cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 929cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Configure NULL Ip 930cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 931cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, NULL); 932cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 933cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 934cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 935cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 936cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = FALSE; 937cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 938cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 939cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Detroy the Ip List used by IpIo 940cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 94134edf2ae729941a6203e4e7f614db32204a9c47dvanjeff 942e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff while (!IsListEmpty (&(IpIo->IpList))) { 943cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry); 944cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 945cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoRemoveIp (IpIo, IpInfo); 946cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 947cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 948cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 9496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // All pending send tokens should be flushed by reseting the IP instances. 950cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 951e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff ASSERT (IsListEmpty (&IpIo->PendingSndList)); 952cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 953cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 954cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the receive event. 955cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 956cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 957cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 958cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 959cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 960cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 961cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 962cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 963cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP_IO instance. 964e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 965e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoCreate(). The IP_IO will be closed first. 9668f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu Resource will be freed afterwards. See IpIoCloseProtocolDestroyIpChild(). 967cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9686aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to be 969e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong destroyed. 970cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9716aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance destroyed successfully. 9726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 973cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 974cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 975cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 9767b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 977cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroy ( 9786aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 979cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 980cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 981cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 982cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Stop the IpIo. 983cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 984cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoStop (IpIo); 985cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 986cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 987cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the IP protocol and destroy the child. 988cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 989cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpIo->ChildHandle); 990cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 991e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 992cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 993cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 994cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 995cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 996cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 997cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 998cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Send out an IP packet. 999e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1000e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoOpen(). The data to be sent are wrapped in 1001e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Pkt. The IP instance wrapped in IpIo is used for sending by default but can be 1002e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong overriden by Sender. Other sending configs, like source address and gateway 1003e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong address etc., are specified in OverrideData. 1004cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance used for sending IP 10066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu packet. 10076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the IP packet to be sent. 10086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender The IP protocol instance used for sending. 10098f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] Context Optional context data. 10108f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] NotifyData Optional notify data. 10116aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest The destination IP address to send this packet to. 10126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OverrideData The data to override some configuration of the IP 10136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance used for sending. 1014cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The operation is completed successfully. 10166aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_NOT_STARTED The IpIo is not configured. 10176aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. 1018cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1019cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1020cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 10217b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1022cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoSend ( 10236aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 10246aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 10256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_IP_INFO *Sender OPTIONAL, 10266aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 10276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 10286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP4_ADDR Dest, 10296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *OverrideData OPTIONAL 1030cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1031cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1032cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1033cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1034cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 1035cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1036cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 1037cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_NOT_STARTED; 1038cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1039cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1040cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip; 1041cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1042cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1043cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // create a new SndEntry 1044cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1045cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData); 1046cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 1047cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_OUT_OF_RESOURCES; 1048cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1049cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1050cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1051cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Send this Packet 1052cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1053cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Transmit (Ip, SndEntry->SndToken); 1054cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1055cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 1056cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1057cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1058cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1059cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1060cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1061cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1062cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1063cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Cancel the IP transmit token which wraps this Packet. 1064cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 10666aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Packet Pointer to the packet of NET_BUF to cancel. 1067cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1068cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1069cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 10707b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1071cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCancelTxToken ( 1072cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 1073cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Packet 1074cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1075cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1076e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *Node; 1077cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 1078cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1079cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10806aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT ((IpIo)!= NULL && (Packet)!= NULL); 1081cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1082cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) { 1083cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1084cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry); 1085cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1086cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (SndEntry->Pkt == Packet) { 1087cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1088cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = SndEntry->Ip; 1089cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Cancel (Ip, SndEntry->SndToken); 1090cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1091cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 1092cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1093cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1094cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1095cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1096cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1097cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1098cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1099cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Add a new IP instance for sending data. 1100e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1101e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The function is used to add the IP_IO to the IP_IO sending list. The caller 1102e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong can later use IpIoFindSender() to get the IP_IO and call IpIoSend() to send 1103e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong data. 1104cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to a IP_IO instance to add a new IP 11066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance for sending purpose. 1107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1108e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to the created IP_IO_IP_INFO structure, NULL if failed. 1109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1111cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 11127b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1113cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoAddIp ( 11146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 1115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11206aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpIo != NULL); 1121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1122e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO)); 1123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo == NULL) { 1124cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1126cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1128cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP 1129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // instance. 1130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1131e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&IpInfo->Entry); 1132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle = NULL; 1133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask = 0; 1135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->RefCnt = 1; 1136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the IP instance and open the Ip4 protocol. 1139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1140cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 1141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->ChildHandle, 11444eb65aff715faafd9040c6fc85a5d59e22343978vanjeff (VOID **) &IpInfo->Ip 1145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1146cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1147cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpInfo; 1148cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the event for the DummyRcvToken. 1152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1153cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 1154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 1155e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1156cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDummyHandler, 1157cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo, 1158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->DummyRcvToken.Event 1159cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1161cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpChild; 1162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1164cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Link this IpInfo into the IpIo. 1166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1167e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->IpList, &IpInfo->Entry); 1168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1171cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpChild: 1172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild ( 1174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle 1177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1179cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpInfo: 1180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1181e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpInfo); 1182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1184cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Configure the IP instance of this IpInfo and start the receiving if Ip4ConfigData 1189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is not NULL. 1190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11916aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpInfo Pointer to the IP_IO_IP_INFO instance. 11926aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Ip4ConfigData The IP4 configure data used to configure the IP 11936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance, if NULL the IP instance is reset. If 11946aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu UseDefaultAddress is set to TRUE, and the configure 11956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu operation succeeds, the default address information 11966aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu is written back in this Ip4ConfigData. 1197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11986aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP instance of this IpInfo is configured successfully 11996aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu or no need to reconfigure it. 12006aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Configuration fails. 1201cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1202cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1203cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 12047b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1205cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoConfigIp ( 12066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO_IP_INFO *IpInfo, 1207cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT EFI_IP4_CONFIG_DATA *Ip4ConfigData OPTIONAL 1208cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1209cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1210cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1211cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1212cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_MODE_DATA Ip4ModeData; 1213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpInfo != NULL); 1215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 1) { 1217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // This IP instance is shared, don't reconfigure it until it has only one 1219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // consumer. Currently, only the tcp children cloned from their passive parent 1220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // will share the same IP. So this cases only happens while Ip4ConfigData is NULL, 1221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // let the last consumer clean the IP instance. 1222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpInfo->Ip; 1227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, Ip4ConfigData); 1229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto OnExit; 1231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1232cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData != NULL) { 1234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData->UseDefaultAddress) { 1236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->GetModeData (Ip, &Ip4ModeData, NULL, NULL); 1237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->StationAddress = Ip4ModeData.ConfigData.StationAddress; 1239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->SubnetMask = Ip4ModeData.ConfigData.SubnetMask; 1240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1242e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&IpInfo->Addr, &Ip4ConfigData->StationAddress, sizeof (IP4_ADDR)); 1243e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&IpInfo->SubnetMask, &Ip4ConfigData->SubnetMask, sizeof (IP4_ADDR)); 1244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1245cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &IpInfo->DummyRcvToken); 1246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 1248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 1250cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The IP instance is reseted, set the stored Addr and SubnetMask to zero. 1253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask =0; 1256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1258cbf316f20726bb31b7c37424601643790dbd02d9vanjeffOnExit: 1259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP instance maintained in IpIo->IpList for 1266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sending purpose. 1267e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1268e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoAddIp(). The IpInfo is previously created by 1269e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IpIoAddIp(). The IP_IO_IP_INFO::RefCnt is decremented and the IP instance 1270e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong will be dstroyed if the RefCnt is zero. 1271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 12736aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpInfo Pointer to the IpInfo to be removed. 1274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1275cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1276cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 12777b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1278cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoRemoveIp ( 1279e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO *IpIo, 1280e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO_IP_INFO *IpInfo 1281cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1282cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1283cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpInfo->RefCnt > 0); 1284cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1285cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_PUT_REF (IpInfo); 1286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 0) { 1288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return; 1290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1292e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpInfo->Entry); 1293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Configure (IpInfo->Ip, NULL); 1295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpInfo->ChildHandle); 1297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpInfo->DummyRcvToken.Event); 1299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1300e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpInfo); 1301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Find the first IP protocol maintained in IpIo whose local 1306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff address is the same with Src. 1307e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1308e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called when the caller needs the IpIo to send data to the 1309e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong specified Src. The IpIo was added previously by IpIoAddIp(). 1310cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13116aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the pointer of the IP_IO instance. 13126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Src The local IP address. 1313cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1314cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the IP protocol can be used for sending purpose and its local 13156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return address is the same with Src. 1316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1318cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 13197b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1320cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoFindSender ( 1321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT IP_IO **IpIo, 1322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP4_ADDR Src 1323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1325e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpIoEntry; 1326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIoPtr; 1327e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpInfoEntry; 1328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1329cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) { 1331cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry); 1332cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1333cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((*IpIo != NULL) && (*IpIo != IpIoPtr)) { 1334cbf316f20726bb31b7c37424601643790dbd02d9vanjeff continue; 1335cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) { 1338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry); 1339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->Addr == Src) { 1341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *IpIo = IpIoPtr; 1342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1345cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1346cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1347cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1348cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // No match. 1349cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1350cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1351cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1352cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1354cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1355e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Get the ICMP error map information. 1356e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1357e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The ErrorStatus will be returned. The IsHard and Notify are optional. If they 1358e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong are not NULL, this routine will fill them. 1359cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13608f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] IcmpError IcmpError Type. 13618f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[out] IsHard Whether it is a hard error. 13628f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[out] Notify Whether it need to notify SockError. 1363cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return ICMP Error Status, such as EFI_NETWORK_UNREACHABLE. 1365cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1366cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1367cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 13687b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1369cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoGetIcmpErrStatus ( 1370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN ICMP_ERROR IcmpError, 1371e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *IsHard OPTIONAL, 1372e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *Notify OPTIONAL 1373cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1374cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 137501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff ASSERT ((IcmpError >= ICMP_ERR_UNREACH_NET) && (IcmpError <= ICMP_ERR_PARAMPROB)); 1376687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 137701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff if (IsHard != NULL) { 137801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff *IsHard = mIcmpErrMap[IcmpError].IsHard; 137901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff } 1380687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 138101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff if (Notify != NULL) { 138201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff *Notify = mIcmpErrMap[IcmpError].Notify; 138301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff } 1384687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 138501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff switch (IcmpError) { 138601750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_NET: 138701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_NETWORK_UNREACHABLE; 1388687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 138901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_TIMXCEED_INTRANS: 139001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_TIMXCEED_REASS: 139101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_HOST: 139201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_HOST_UNREACHABLE; 1393cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 139401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_PROTOCOL: 139501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_PROTOCOL_UNREACHABLE; 1396cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 139701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_PORT: 139801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_PORT_UNREACHABLE; 1399cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 140001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_MSGSIZE: 140101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_SRCFAIL: 140201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_QUENCH: 140301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_PARAMPROB: 140401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_ICMP_ERROR; 1405cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1406cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 140701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // 140801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // will never run here! 140901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // 141001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff ASSERT (FALSE); 141101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_UNSUPPORTED; 1412cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1413cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1414