DxeIpIoLib.c revision 752ef5d80c099b1d33bf25f62f36289dac47d83c
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> 21752ef5d80c099b1d33bf25f62f36289dac47d83cmdkinney#include <Library/BaseMemoryLib.h> 22cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/UefiBootServicesTableLib.h> 23752ef5d80c099b1d33bf25f62f36289dac47d83cmdkinney#include <Library/MemoryAllocationLib.h> 24cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 25cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 26e48e37fce2611df7a52aff271835ff72ee396d9bvanjeffLIST_ENTRY mActiveIpIoList = { 27cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList, 28cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList 29cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 30cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 31cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_IP4_CONFIG_DATA mIpIoDefaultIpConfigData = { 32cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP_PROTO_UDP, 33cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 34cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TRUE, 35cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 36cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 37cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 3884b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 3984b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 40cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 41cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 255, 42cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 43cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 44cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 45cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0 46cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 47cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 48fe1e36e550c6ffcd2561903d434683d3939e1942jjiICMP_ERROR_INFO mIcmpErrMap[10] = { 4901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {TRUE, TRUE}, 5401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5601750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE}, 5701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, FALSE}, 5801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff {FALSE, TRUE} 5901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff}; 6001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff 616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 666aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 676aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 68cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 69cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 7036ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 7136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 7236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ); 7336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 756aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 766aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 776aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 786aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 796aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 806aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 816aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 8236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 8336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 84cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoTransmitHandler ( 85cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 86cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 87cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 88cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 89cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 90cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 916aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function create an IP child ,open the IP protocol, and return the opened 92e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IP protocol as Interface. 93cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 946aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 966aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle Pointer to the buffer to save the IP child handle. 976aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[out] Interface Pointer used to get the IP protocol interface. 98cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 996aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP child is created and the IP protocol 1006aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu interface is retrieved. 1016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 102cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 103cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 104cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 105cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateIpChildOpenProtocol ( 106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE *ChildHandle, 109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT VOID **Interface 110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 112cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 113cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Create an IP child. 116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibCreateServiceChild ( 118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 120cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 122cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 124cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 126cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Open the IP protocol installed on the *ChildHandle. 129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->OpenProtocol ( 131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle, 132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Interface, 134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_OPEN_PROTOCOL_BY_DRIVER 137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1406aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // On failure, destroy the IP child. 141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetLibDestroyServiceChild ( 143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 146cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle 147cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 148cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 153cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 155e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function close the previously openned IP protocol and destroy the IP child. 156cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1576aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 1586aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 1596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle The child handle of the IP child. 160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP protocol is closed and the relevant IP child 1626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu is destroyed. 1636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 164cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 166cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 167cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCloseProtocolDestroyIpChild ( 168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ChildHandle 171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1766aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Close the previously openned IP protocol. 177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseProtocol ( 179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle, 180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ProtocolGuid, 181cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle 183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 184cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1866aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Destroy the IP child. 187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibDestroyServiceChild ( 189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &gEfiIp4ServiceBindingProtocolGuid, 192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 193cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 194cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 198cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 200e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function handles ICMP packets. 201cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2026aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 2036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the ICMP packet. 2046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Session Pointer to the net session of this ICMP packet. 205cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The ICMP packet is handled successfully. 2076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_ABORTED This type of ICMP packet is not supported. 208cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 209cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 210cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 211cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoIcmpHandler ( 2126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO *IpIo, 2136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 2146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN EFI_NET_SESSION_DATA *Session 215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP4_ICMP_ERROR_HEAD *IcmpHdr; 218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_HEADER *IpHdr; 219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ICMP_ERROR IcmpErr; 220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 *PayLoadHdr; 221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Type; 222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Code; 223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT32 TrimBytes; 224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD); 226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpHdr = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead); 227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Check the ICMP packet length. 230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) { 232cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Type = IcmpHdr->Head.Type; 237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Code = IcmpHdr->Head.Code; 238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Analyze the ICMP Error in this ICMP pkt 241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Type) { 243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_UNREACH: 244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Code) { 245cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET: 246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST: 247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PROTOCOL: 248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PORT: 249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_SRCFAIL: 2504eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (ICMP_ERR_UNREACH_NET + Code); 251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NEEDFRAG: 255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_MSGSIZE; 256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_UNKNOWN: 260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_PROHIB: 261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSNET: 262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_NET; 263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_UNKNOWN: 267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_ISOLATED: 268cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_PROHIB: 269cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSHOST: 270cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_HOST; 271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 272cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 275cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 276cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 277cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 278cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 279cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 280cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_TIMXCEED: 281cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 282cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 283cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 284cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2854eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IcmpErr = (ICMP_ERROR) (Code + ICMP_ERR_TIMXCEED_INTRANS); 286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_PARAMPROB: 290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 292cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_PARAMPROB; 295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_SOURCEQUENCH: 299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code != 0) { 300cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_QUENCH; 304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 307cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 308cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 309cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 310cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 311cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 312cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Notify user the ICMP pkt only containing payload except 313cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // IP and ICMP header 314cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr)); 316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr); 317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufTrim (Pkt, TrimBytes, TRUE); 319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext); 321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 325cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 327e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Free function for receive token of IP_IO. It is used to 328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff signal the recycle event to notify IP to recycle the 329cbf316f20726bb31b7c37424601643790dbd02d9vanjeff data buffer. 330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 3316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event to be signaled. 332cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 333cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 334cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 335cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoExtFree ( 336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Event 337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent ((EFI_EVENT) Event); 340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a send entry to wrap a packet before sending 345cbf316f20726bb31b7c37424601643790dbd02d9vanjeff out it through IP. 346cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 3476aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance. 3486aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the packet. 3496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender Pointer to the IP sender. 3506aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context Pointer to the context. 3516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] NotifyData Pointer to the notify data. 3526aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest Pointer to the destination IP address. 3536aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Override Pointer to the overriden IP_IO data. 354cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the data structure created to wrap the packet. If NULL, 3566aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return resource limit occurred. 357cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 358cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 359cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_SEND_ENTRY * 360cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateSndEntry ( 3616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 3626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 3636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN EFI_IP4_PROTOCOL *Sender, 3646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 3656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 3666aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP4_ADDR Dest, 3676aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *Override 368cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 369cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 371cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *SndToken; 372cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 373cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 374cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_OVERRIDE_DATA *OverrideData; 37534edf2ae729941a6203e4e7f614db32204a9c47dvanjeff volatile UINT32 Index; 376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 377cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 378cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndEntry 379cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 380e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY)); 381cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 382cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 383cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 384cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 385cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 386cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndToken 387cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 388e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff SndToken = AllocatePool (sizeof (EFI_IP4_COMPLETION_TOKEN)); 389cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndToken) { 390cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndEntry; 391cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 392cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 393cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 394cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 395e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 396cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoTransmitHandler, 397cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry, 398cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(SndToken->Event) 399cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 400cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 401cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseSndToken; 402cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 403cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 404cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 405cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for TxData 406cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 407e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TxData = AllocatePool ( 408cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_TRANSMIT_DATA) + 409cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sizeof (EFI_IP4_FRAGMENT_DATA) * (Pkt->BlockOpNum - 1) 410cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 411cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 412cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == TxData) { 413cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseEvent; 414cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 415cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 416cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 417cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for OverrideData if needed 418cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 419cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OverrideData = NULL; 420cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != Override) { 421cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 422e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff OverrideData = AllocatePool (sizeof (EFI_IP4_OVERRIDE_DATA)); 423cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == OverrideData) { 424cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseResource; 425cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 426cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 427cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of OverrideData 428cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 42936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff CopyMem (OverrideData, Override, sizeof (*OverrideData)); 430cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 431cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 432cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 433cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of TxData 434cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 435e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&TxData->DestinationAddress, &Dest, sizeof (EFI_IPv4_ADDRESS)); 436cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OverrideData = OverrideData; 437cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsLength = 0; 438cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->OptionsBuffer = NULL; 439cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->TotalDataLength = Pkt->TotalSize; 440cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentCount = Pkt->BlockOpNum; 441cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 442cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 44334edf2ae729941a6203e4e7f614db32204a9c47dvanjeff for (Index = 0; Index < Pkt->BlockOpNum; Index++) { 444cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentBuffer = Pkt->BlockOp[Index].Head; 445cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData->FragmentTable[Index].FragmentLength = Pkt->BlockOp[Index].Size; 446cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 447cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 448cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 449cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndToken 450cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 451cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndToken->Packet.TxData = TxData; 452cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 453cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 454cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndEntry 455cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 456cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->IpIo = IpIo; 4576aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu SndEntry->Ip = Sender; 458cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context = Context; 459cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData = NotifyData; 460cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 461cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Pkt = Pkt; 462cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_GET_REF (Pkt); 463cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 464cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken = SndToken; 465cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 466e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry); 467cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 468cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return SndEntry; 469cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 470cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseResource: 471e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData); 472cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 473cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseEvent: 474cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndToken->Event); 475cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 476cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndToken: 477e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndToken); 478cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 479cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseSndEntry: 480e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry); 481cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 482cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 483cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 484cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 485cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 486cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 487cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy the SndEntry. 488e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 489e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoCreateSndEntry(). 490cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 4916aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] SndEntry Pointer to the send entry to be destroyed. 492cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 493cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 494cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 495cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroySndEntry ( 496cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_SEND_ENTRY *SndEntry 497cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 498cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 499cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_TRANSMIT_DATA *TxData; 500cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 501cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TxData = SndEntry->SndToken->Packet.TxData; 502cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 503cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != TxData->OverrideData) { 504e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData->OverrideData); 505cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 506cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 507e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (TxData); 508cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (SndEntry->Pkt); 509cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (SndEntry->SndToken->Event); 510cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 511e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry->SndToken); 512e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&SndEntry->Entry); 513cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 514e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (SndEntry); 515cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 516cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 517cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 518cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 519cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Notify function for IP transmit token. 520cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5216aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 522cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 523cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 524cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 525cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 52636ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 527cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 528cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 529cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 530cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 531cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 532cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 533cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = (IP_IO_SEND_ENTRY *) Context; 534cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 535cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = SndEntry->IpIo; 536cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5378de75da28bbd9a4d3c54fba99d943f9019b52193niry if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) { 538cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify ( 539cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->SndToken->Status, 540cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context, 541cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Ip, 542cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData 543cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 544cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 545cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 546cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 547cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 548cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 55036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 55136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for IP transmit token. 55236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 5536aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 5546aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 55536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 55636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 55736ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 55836ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 55936ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandler ( 56036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 56136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 56236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 56336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 56436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 56536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK 56636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 56736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context); 56836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 56936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 570cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 571cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 572cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The dummy handler for the dummy IP receive token. 573cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 575cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 576cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 577cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 578cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 57936ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandlerDpc ( 580cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 581cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 582cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 583cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 584cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_COMPLETION_TOKEN *DummyToken; 585cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 586cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = (IP_IO_IP_INFO *) Context; 587cbf316f20726bb31b7c37424601643790dbd02d9vanjeff DummyToken = &(IpInfo->DummyRcvToken); 588cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 58936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff if (EFI_ABORTED == DummyToken->Status) { 59036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 59136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 59236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 59336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 59436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff } else if (EFI_SUCCESS == DummyToken->Status) { 5956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT ((DummyToken->Packet.RxData)!= NULL); 596cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 597cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (DummyToken->Packet.RxData->RecycleSignal); 598cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 599cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 600cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Receive (IpInfo->Ip, DummyToken); 601cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 602cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 603cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 604cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 6056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoDummyHandlerDpc to the end of the DPC queue. 606cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 6076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 6086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 609cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 610cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 611cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 612cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 61336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandler ( 614cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 615cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 616cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 617cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 61836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 61936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK 62036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 62136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context); 62236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 62336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 62436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 62536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 62636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for the IP receive token, used to process 62736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff the received IP packets. 62836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 6296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 63036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 63136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 63236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 63336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 63436ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandlerDpc ( 63536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 63636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 63736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 638cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 639cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 640cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_RECEIVE_DATA *RxData; 641cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 642cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_NET_SESSION_DATA Session; 643cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_BUF *Pkt; 644cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 645cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = (IP_IO *) Context; 646cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 647cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 648cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIo->RcvToken.Status; 649cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData = IpIo->RcvToken.Packet.RxData; 650cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 65136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff if (EFI_ABORTED == Status) { 65236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 65336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 65436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 65536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 65636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff } 65736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 658cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) { 659cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 6606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug Only process the normal packets and the icmp error packets, if RxData is NULL 6616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although 6626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug this should be a bug of the low layer (IP). 663cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 664cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 665cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 666cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 667cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo->PktRcvdNotify) { 668cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 669cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 670cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 671cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((EFI_IP4 (RxData->Header->SourceAddress) != 0) && 672cbf316f20726bb31b7c37424601643790dbd02d9vanjeff !Ip4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), 0)) { 673cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 674cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The source address is not zero and it's not a unicast IP address, discard it. 675cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 676cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 677cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 678cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 679cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 680cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a netbuffer representing packet 681cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 682cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Pkt = NetbufFromExt ( 683cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (NET_FRAGMENT *) RxData->FragmentTable, 684cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->FragmentCount, 685cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 686cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 687cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoExtFree, 688cbf316f20726bb31b7c37424601643790dbd02d9vanjeff RxData->RecycleSignal 689cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 690cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == Pkt) { 691cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 692cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 693cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 694cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 695cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a net session 696cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 697cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Source = EFI_IP4 (RxData->Header->SourceAddress); 698cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.Dest = EFI_IP4 (RxData->Header->DestinationAddress); 699cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Session.IpHdr = RxData->Header; 700cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 701cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_SUCCESS == Status) { 702cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 7034eb65aff715faafd9040c6fc85a5d59e22343978vanjeff IpIo->PktRcvdNotify (EFI_SUCCESS, (ICMP_ERROR) 0, &Session, Pkt, IpIo->RcvdContext); 704cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 705cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 706cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Status is EFI_ICMP_ERROR 707cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 708cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoIcmpHandler (IpIo, Pkt, &Session); 709cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 710cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (Pkt); 711cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 712cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 713cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 714cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 715cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 716cbf316f20726bb31b7c37424601643790dbd02d9vanjeffCleanUp: 717cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent (RxData->RecycleSignal); 718cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 719cbf316f20726bb31b7c37424601643790dbd02d9vanjeffResume: 720cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Receive (Ip, &(IpIo->RcvToken)); 721cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 722cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 723cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 724cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 7256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoListenHandlerDpc to the end of the DPC queue. 72636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 7276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 7286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 72936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 73036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 73136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 73236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 73336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandler ( 73436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 73536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 73636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 73736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 73836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 73936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK 74036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 74136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff NetLibQueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context); 74236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 74336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 74436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 74536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 746cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a new IP_IO instance. 747e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 748e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function uses IP4 service binding protocol in Controller to create an IP4 749e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong child (aka IP4 instance). 750cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 7516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Image The image handle of the driver or application that 752e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong consumes IP_IO. 7536aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Controller The controller handle that has IP4 service binding 754e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong protocol installed. 755cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 756e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to a newly created IP_IO instance, or NULL if failed. 757cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 758cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 759cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO * 7607b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 761cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreate ( 762cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Image, 763cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Controller 764cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 765cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 766cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 767cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 768cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 769e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpIo = AllocateZeroPool (sizeof (IP_IO)); 770cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo) { 771cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 772cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 773cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 774e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->PendingSndList)); 775e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->IpList)); 776cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller = Controller; 777cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image = Image; 778cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 779cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 780cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 781e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 782cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoListenHandler, 783cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo, 784cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &(IpIo->RcvToken.Event) 785cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 786cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 787cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 788cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 789cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 790cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 791cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create an IP child and open IP protocol 792cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 793cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 794cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Controller, 795cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Image, 796cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpIo->ChildHandle, 797cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (VOID **)&(IpIo->Ip) 798cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 799cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 800cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 801cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 802cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 803cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpIo; 804cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 805cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpIo: 806cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 807cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != IpIo->RcvToken.Event) { 808cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 809cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 810cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 811e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 812cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 813cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 814cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 815cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 816cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 817cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 818cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Open an IP_IO instance for use. 819e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 820e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoCreate(). It is used for configuring the IP 821e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong instance and register the callbacks and their context data for sending and 822e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong receiving IP packets. 823cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8246aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance that needs 8256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu to open. 8266aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OpenData The configuration data and callbacks for 8276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu the IP_IO instance. 828cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance opened with OpenData 8306aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu successfully. 8316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_ACCESS_DENIED The IP_IO instance is configured, avoid to 8326aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu reopen it. 8336aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 834cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 835cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 836cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 8377b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 838cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoOpen ( 8396aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 8406aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OPEN_DATA *OpenData 841cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 842cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 843cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 844cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 845cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 846cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpIo->IsConfigured) { 847cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ACCESS_DENIED; 848cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 849cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 850cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 851cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 852cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 853cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // configure ip 854cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 855cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, &OpenData->IpConfigData); 856cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 857cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 858cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 859cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 860cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 8616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug To delete the default route entry in this Ip, if it is: 8626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified 8636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug its code 864cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 865b61439a709bb961f2f9dff1d1a4112e30a063f51vanjeff Status = Ip->Routes (Ip, TRUE, &mZeroIp4Addr, &mZeroIp4Addr, &mZeroIp4Addr); 866cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 867cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) { 868cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 869cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 870cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 871cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify = OpenData->PktRcvdNotify; 872cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify = OpenData->PktSentNotify; 873cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 874cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->RcvdContext = OpenData->RcvdContext; 875cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->SndContext = OpenData->SndContext; 876cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 877cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Protocol = OpenData->IpConfigData.DefaultProtocol; 878cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 879cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 880cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // start to listen incoming packet 881cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 882cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &(IpIo->RcvToken)); 883cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 884cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 885cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ErrorExit; 886cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 887cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 888cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = TRUE; 889e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&mActiveIpIoList, &IpIo->Entry); 890cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 891cbf316f20726bb31b7c37424601643790dbd02d9vanjeffErrorExit: 892cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 893cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 894cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 895cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 896cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 897cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 898cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Stop an IP_IO instance. 899e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 900e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoOpen(). The IP_IO will be unconfigured and all 901e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong the pending send/receive tokens will be canceled. 902cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to stop. 904cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance stopped successfully. 9066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 907cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 908cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 909cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 910e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgongEFIAPI 911cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoStop ( 9126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 913cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 914cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 915cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 916cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 917cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 918cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 919cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 920cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 921cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 922cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 923cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 924cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Remove the IpIo from the active IpIo list. 925cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 926e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpIo->Entry); 927cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 928cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpIo->Ip; 929cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 930cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 931cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Configure NULL Ip 932cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 933cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, NULL); 934cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 935cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 936cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 937cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 938cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = FALSE; 939cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 940cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 941cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Detroy the Ip List used by IpIo 942cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 94334edf2ae729941a6203e4e7f614db32204a9c47dvanjeff 944e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff while (!IsListEmpty (&(IpIo->IpList))) { 945cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry); 946cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 947cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoRemoveIp (IpIo, IpInfo); 948cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 949cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 950cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 9516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // All pending send tokens should be flushed by reseting the IP instances. 952cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 953e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff ASSERT (IsListEmpty (&IpIo->PendingSndList)); 954cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 955cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 956cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the receive event. 957cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 958cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpIo->RcvToken.Event); 959cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 960cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 961cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 962cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 963cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 964cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 965cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP_IO instance. 966e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 967e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoCreate(). The IP_IO will be closed first. 9688f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu Resource will be freed afterwards. See IpIoCloseProtocolDestroyIpChild(). 969cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9706aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to be 971e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong destroyed. 972cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9736aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance destroyed successfully. 9746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 975cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 976cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 977cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 9787b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 979cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroy ( 9806aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 981cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 982cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 983cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 984cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Stop the IpIo. 985cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 986cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoStop (IpIo); 987cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 988cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 989cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the IP protocol and destroy the child. 990cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 991cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpIo->ChildHandle); 992cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 993e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 994cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 995cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 996cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 997cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 998cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 999cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1000cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Send out an IP packet. 1001e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1002e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoOpen(). The data to be sent are wrapped in 1003e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Pkt. The IP instance wrapped in IpIo is used for sending by default but can be 1004e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong overriden by Sender. Other sending configs, like source address and gateway 1005e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong address etc., are specified in OverrideData. 1006cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance used for sending IP 10086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu packet. 10096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the IP packet to be sent. 10106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender The IP protocol instance used for sending. 10118f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] Context Optional context data. 10128f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] NotifyData Optional notify data. 10136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest The destination IP address to send this packet to. 10146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OverrideData The data to override some configuration of the IP 10156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance used for sending. 1016cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10176aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The operation is completed successfully. 10186aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_NOT_STARTED The IpIo is not configured. 10196aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. 1020cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1021cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1022cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 10237b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1024cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoSend ( 10256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 10266aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 10276aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_IP_INFO *Sender OPTIONAL, 10286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 10296aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 10306aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP4_ADDR Dest, 10316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *OverrideData OPTIONAL 1032cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1033cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1034cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1035cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1036cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 1037cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1038cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 1039cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_NOT_STARTED; 1040cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1041cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1042cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip; 1043cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1044cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1045cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // create a new SndEntry 1046cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1047cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData); 1048cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 1049cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_OUT_OF_RESOURCES; 1050cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1051cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1052cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1053cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Send this Packet 1054cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1055cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Transmit (Ip, SndEntry->SndToken); 1056cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1057cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 1058cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1059cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1060cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1061cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1062cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1063cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1064cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1065cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Cancel the IP transmit token which wraps this Packet. 1066cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10676aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 10686aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Packet Pointer to the packet of NET_BUF to cancel. 1069cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1070cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1071cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 10727b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1073cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCancelTxToken ( 1074cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 1075cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Packet 1076cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1077cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1078e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *Node; 1079cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 1080cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1081cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 10826aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT ((IpIo)!= NULL && (Packet)!= NULL); 1083cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1084cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) { 1085cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1086cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry); 1087cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1088cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (SndEntry->Pkt == Packet) { 1089cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1090cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = SndEntry->Ip; 1091cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Cancel (Ip, SndEntry->SndToken); 1092cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1093cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 1094cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1095cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1096cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1097cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1098cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1099cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1100cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1101cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Add a new IP instance for sending data. 1102e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1103e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The function is used to add the IP_IO to the IP_IO sending list. The caller 1104e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong can later use IpIoFindSender() to get the IP_IO and call IpIoSend() to send 1105e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong data. 1106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to a IP_IO instance to add a new IP 11086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance for sending purpose. 1109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1110e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to the created IP_IO_IP_INFO structure, NULL if failed. 1111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1112cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1113cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 11147b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1115cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoAddIp ( 11166aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 1117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1120cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1121cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11226aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpIo != NULL); 1123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1124e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO)); 1125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo == NULL) { 1126cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1127cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1128cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1130cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP 1131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // instance. 1132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1133e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&IpInfo->Entry); 1134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle = NULL; 1135cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1136cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask = 0; 1137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->RefCnt = 1; 1138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1140cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the IP instance and open the Ip4 protocol. 1141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 1143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->ChildHandle, 11464eb65aff715faafd9040c6fc85a5d59e22343978vanjeff (VOID **) &IpInfo->Ip 1147cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1148cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpInfo; 1150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1151cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1152cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1153cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the event for the DummyRcvToken. 1154cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1155cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 1156cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 1157e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDummyHandler, 1159cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo, 1160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->DummyRcvToken.Event 1161cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpChild; 1164cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1167cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Link this IpInfo into the IpIo. 1168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1169e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->IpList, &IpInfo->Entry); 1170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1172cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1173cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpChild: 1174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild ( 1176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle 1179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1181cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpInfo: 1182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1183e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpInfo); 1184cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1189cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Configure the IP instance of this IpInfo and start the receiving if Ip4ConfigData 1191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is not NULL. 1192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpInfo Pointer to the IP_IO_IP_INFO instance. 11946aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Ip4ConfigData The IP4 configure data used to configure the IP 11956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance, if NULL the IP instance is reset. If 11966aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu UseDefaultAddress is set to TRUE, and the configure 11976aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu operation succeeds, the default address information 11986aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu is written back in this Ip4ConfigData. 1199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12006aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP instance of this IpInfo is configured successfully 12016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu or no need to reconfigure it. 12026aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Configuration fails. 1203cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1204cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1205cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 12067b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1207cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoConfigIp ( 12086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO_IP_INFO *IpInfo, 1209cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT EFI_IP4_CONFIG_DATA *Ip4ConfigData OPTIONAL 1210cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1211cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1212cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_PROTOCOL *Ip; 1214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_MODE_DATA Ip4ModeData; 1215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12166aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpInfo != NULL); 1217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 1) { 1219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // This IP instance is shared, don't reconfigure it until it has only one 1221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // consumer. Currently, only the tcp children cloned from their passive parent 1222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // will share the same IP. So this cases only happens while Ip4ConfigData is NULL, 1223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // let the last consumer clean the IP instance. 1224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpInfo->Ip; 1229cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Configure (Ip, Ip4ConfigData); 1231cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1232cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto OnExit; 1233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1235cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData != NULL) { 1236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Ip4ConfigData->UseDefaultAddress) { 1238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->GetModeData (Ip, &Ip4ModeData, NULL, NULL); 1239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->StationAddress = Ip4ModeData.ConfigData.StationAddress; 1241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip4ConfigData->SubnetMask = Ip4ModeData.ConfigData.SubnetMask; 1242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1244e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&IpInfo->Addr, &Ip4ConfigData->StationAddress, sizeof (IP4_ADDR)); 1245e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&IpInfo->SubnetMask, &Ip4ConfigData->SubnetMask, sizeof (IP4_ADDR)); 1246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = Ip->Receive (Ip, &IpInfo->DummyRcvToken); 1248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip->Configure (Ip, NULL); 1250cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 1252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The IP instance is reseted, set the stored Addr and SubnetMask to zero. 1255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Addr = 0; 1257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->SubnetMask =0; 1258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1260cbf316f20726bb31b7c37424601643790dbd02d9vanjeffOnExit: 1261cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1262cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1263cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP instance maintained in IpIo->IpList for 1268cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sending purpose. 1269e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1270e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoAddIp(). The IpInfo is previously created by 1271e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IpIoAddIp(). The IP_IO_IP_INFO::RefCnt is decremented and the IP instance 1272e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong will be dstroyed if the RefCnt is zero. 1273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12746aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 12756aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpInfo Pointer to the IpInfo to be removed. 1276cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1277cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1278cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 12797b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1280cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoRemoveIp ( 1281e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO *IpIo, 1282e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO_IP_INFO *IpInfo 1283cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1284cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1285cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpInfo->RefCnt > 0); 1286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_PUT_REF (IpInfo); 1288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 0) { 1290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return; 1292cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1294e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpInfo->Entry); 1295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->Ip->Configure (IpInfo->Ip, NULL); 1297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild (IpIo->Controller, IpIo->Image, IpInfo->ChildHandle); 1299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1300cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseEvent (IpInfo->DummyRcvToken.Event); 1301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1302e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpInfo); 1303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1307cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Find the first IP protocol maintained in IpIo whose local 1308cbf316f20726bb31b7c37424601643790dbd02d9vanjeff address is the same with Src. 1309e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1310e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called when the caller needs the IpIo to send data to the 1311e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong specified Src. The IpIo was added previously by IpIoAddIp(). 1312cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the pointer of the IP_IO instance. 13146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Src The local IP address. 1315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the IP protocol can be used for sending purpose and its local 13176aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return address is the same with Src. 1318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1320cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 13217b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1322cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoFindSender ( 1323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN OUT IP_IO **IpIo, 1324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP4_ADDR Src 1325cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1327e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpIoEntry; 1328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIoPtr; 1329e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpInfoEntry; 1330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1331cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1332cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) { 1333cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry); 1334cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1335cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if ((*IpIo != NULL) && (*IpIo != IpIoPtr)) { 1336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff continue; 1337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) { 1340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry); 1341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->Addr == Src) { 1343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *IpIo = IpIoPtr; 1344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1345cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1346cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1347cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1348cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1349cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1350cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // No match. 1351cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1352cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1354cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1356cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1357e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Get the ICMP error map information. 1358e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1359e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The ErrorStatus will be returned. The IsHard and Notify are optional. If they 1360e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong are not NULL, this routine will fill them. 1361cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13628f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] IcmpError IcmpError Type. 13638f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[out] IsHard Whether it is a hard error. 13648f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[out] Notify Whether it need to notify SockError. 1365cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13666aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return ICMP Error Status, such as EFI_NETWORK_UNREACHABLE. 1367cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1368cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1369cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 13707b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1371cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoGetIcmpErrStatus ( 1372cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN ICMP_ERROR IcmpError, 1373e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *IsHard OPTIONAL, 1374e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *Notify OPTIONAL 1375cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 137701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff ASSERT ((IcmpError >= ICMP_ERR_UNREACH_NET) && (IcmpError <= ICMP_ERR_PARAMPROB)); 1378687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 137901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff if (IsHard != NULL) { 138001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff *IsHard = mIcmpErrMap[IcmpError].IsHard; 138101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff } 1382687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 138301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff if (Notify != NULL) { 138401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff *Notify = mIcmpErrMap[IcmpError].Notify; 138501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff } 1386687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 138701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff switch (IcmpError) { 138801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_NET: 138901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_NETWORK_UNREACHABLE; 1390687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 139101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_TIMXCEED_INTRANS: 139201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_TIMXCEED_REASS: 139301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_HOST: 139401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_HOST_UNREACHABLE; 1395cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 139601750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_PROTOCOL: 139701750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_PROTOCOL_UNREACHABLE; 1398cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 139901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_PORT: 140001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_PORT_UNREACHABLE; 1401cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 140201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_MSGSIZE: 140301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_UNREACH_SRCFAIL: 140401750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_QUENCH: 140501750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff case ICMP_ERR_PARAMPROB: 140601750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_ICMP_ERROR; 1407cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1408cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 140901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // 141001750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // will never run here! 141101750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff // 141201750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff ASSERT (FALSE); 141301750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff return EFI_UNSUPPORTED; 1414cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1415cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1416