1cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** @file 26aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IpIo Library. 3cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 435f910f08b58e978bc9251872635075d6f422e48Randy Pawell(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR> 5cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianCopyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR> 6cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis program and the accompanying materials 7cbf316f20726bb31b7c37424601643790dbd02d9vanjeffare licensed and made available under the terms and conditions of the BSD License 8cbf316f20726bb31b7c37424601643790dbd02d9vanjeffwhich accompanies this distribution. The full text of the license may be found at 9cbf316f20726bb31b7c37424601643790dbd02d9vanjeffhttp://opensource.org/licenses/bsd-license.php 10cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11cbf316f20726bb31b7c37424601643790dbd02d9vanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12cbf316f20726bb31b7c37424601643790dbd02d9vanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 14cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu#include <Uefi.h> 16cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 17cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Protocol/Udp4.h> 18cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 19cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/IpIoLib.h> 20cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/BaseLib.h> 21cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/DebugLib.h> 22752ef5d80c099b1d33bf25f62f36289dac47d83cmdkinney#include <Library/BaseMemoryLib.h> 23cbf316f20726bb31b7c37424601643790dbd02d9vanjeff#include <Library/UefiBootServicesTableLib.h> 24752ef5d80c099b1d33bf25f62f36289dac47d83cmdkinney#include <Library/MemoryAllocationLib.h> 25d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney#include <Library/DpcLib.h> 26cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 27cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 281204fe8319e5e6f77df68c375ef403e9ffa9227exduGLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mActiveIpIoList = { 29cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList, 30cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &mActiveIpIoList 31cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 32cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 331204fe8319e5e6f77df68c375ef403e9ffa9227exduGLOBAL_REMOVE_IF_UNREFERENCED EFI_IP4_CONFIG_DATA mIp4IoDefaultIpConfigData = { 34cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP_PROTO_UDP, 35cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 36cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TRUE, 37cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 38cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 39cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 4084b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 4184b5c78e89686879f799a4cd095eeef83ff7cf34qwang {{0, 0, 0, 0}}, 42cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 43cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 255, 44cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 45cbf316f20726bb31b7c37424601643790dbd02d9vanjeff FALSE, 46cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 47cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0 48cbf316f20726bb31b7c37424601643790dbd02d9vanjeff}; 49cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 501204fe8319e5e6f77df68c375ef403e9ffa9227exduGLOBAL_REMOVE_IF_UNREFERENCED EFI_IP6_CONFIG_DATA mIp6IoDefaultIpConfigData = { 51fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP_PROTO_UDP, 52fb115c61504fe6c4f94be0a87f75e28e1684657ftye FALSE, 53fb115c61504fe6c4f94be0a87f75e28e1684657ftye TRUE, 54fb115c61504fe6c4f94be0a87f75e28e1684657ftye FALSE, 55fb115c61504fe6c4f94be0a87f75e28e1684657ftye {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 56fb115c61504fe6c4f94be0a87f75e28e1684657ftye {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 57fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0, 58fb115c61504fe6c4f94be0a87f75e28e1684657ftye 255, 59fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0, 60fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0, 61fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0 62fb115c61504fe6c4f94be0a87f75e28e1684657ftye}; 63fb115c61504fe6c4f94be0a87f75e28e1684657ftye 641204fe8319e5e6f77df68c375ef403e9ffa9227exduGLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO mIcmpErrMap[10] = { 653cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE }, // ICMP_ERR_UNREACH_NET 663cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE }, // ICMP_ERR_UNREACH_HOST 673cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE }, // ICMP_ERR_UNREACH_PROTOCOL 683cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE }, // ICMP_ERR_UNREACH_PORT 693cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE }, // ICMP_ERR_MSGSIZE 703cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE }, // ICMP_ERR_UNREACH_SRCFAIL 713cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE }, // ICMP_ERR_TIMXCEED_INTRANS 723cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE }, // ICMP_ERR_TIMEXCEED_REASS 733cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, FALSE}, // ICMP_ERR_QUENCH 743cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE } // ICMP_ERR_PARAMPROB 75fb115c61504fe6c4f94be0a87f75e28e1684657ftye}; 76fb115c61504fe6c4f94be0a87f75e28e1684657ftye 771204fe8319e5e6f77df68c375ef403e9ffa9227exduGLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO mIcmp6ErrMap[10] = { 783cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_UNREACH_NET 793cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_UNREACH_HOST 803cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE}, // ICMP6_ERR_UNREACH_PROTOCOL 813cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE}, // ICMP6_ERR_UNREACH_PORT 823cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {TRUE, TRUE}, // ICMP6_ERR_PACKAGE_TOOBIG 833cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_HOPLIMIT 843cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_REASS 853cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_HEADER 863cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_NEXHEADER 873cf888f5f90526fa0d613c2a1486e0c1f416bd67tye {FALSE, TRUE} // ICMP6_ERR_PARAMPROB_IPV6OPTION 8801750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff}; 8901750eb0aad0510c13da7453fa0c0b64aef0bc72vanjeff 906aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 916aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 926aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 946aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 966aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 97cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 98cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 9936ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 10036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 10136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ); 10236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 1036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 1046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu/** 1056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu Notify function for IP transmit token. 1066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 1076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 1086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 1096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 1106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu**/ 11136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 11236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 113cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoTransmitHandler ( 114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 116cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 117cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 118cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 119cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1206aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function create an IP child ,open the IP protocol, and return the opened 121e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IP protocol as Interface. 122cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1236aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 1246aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 1256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle Pointer to the buffer to save the IP child handle. 126fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpVersion The version of the IP protocol to use, either 127fb115c61504fe6c4f94be0a87f75e28e1684657ftye IPv4 or IPv6. 1286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[out] Interface Pointer used to get the IP protocol interface. 129cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1306aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP child is created and the IP protocol 1316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu interface is retrieved. 1326aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 134cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 135cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 136cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateIpChildOpenProtocol ( 137cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 138cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 139cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE *ChildHandle, 140b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IpVersion, 141cbf316f20726bb31b7c37424601643790dbd02d9vanjeff OUT VOID **Interface 142cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 143cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 145fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_GUID *ServiceBindingGuid; 146fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_GUID *IpProtocolGuid; 147fb115c61504fe6c4f94be0a87f75e28e1684657ftye 148fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4) { 149fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid; 150fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid = &gEfiIp4ProtocolGuid; 151fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpVersion == IP_VERSION_6){ 152fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid; 153fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid = &gEfiIp6ProtocolGuid; 154fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 155fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_UNSUPPORTED; 156fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 157cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 158cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Create an IP child. 160cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 161cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibCreateServiceChild ( 162cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 163cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 164fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid, 165cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 167cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 170cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 171cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Open the IP protocol installed on the *ChildHandle. 173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 174cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->OpenProtocol ( 175cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle, 176fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid, 177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Interface, 178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 180cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_OPEN_PROTOCOL_BY_DRIVER 181cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 182cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1846aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // On failure, destroy the IP child. 185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetLibDestroyServiceChild ( 187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 189fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid, 190cbf316f20726bb31b7c37424601643790dbd02d9vanjeff *ChildHandle 191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 193cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 194cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 198cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 199e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function close the previously openned IP protocol and destroy the IP child. 200cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ControllerHandle The controller handle. 2026aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ImageHandle The image handle. 2036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] ChildHandle The child handle of the IP child. 204fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpVersion The version of the IP protocol to use, either 205fb115c61504fe6c4f94be0a87f75e28e1684657ftye IPv4 or IPv6. 206cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP protocol is closed and the relevant IP child 2086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu is destroyed. 2096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others The required operation failed. 210cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 211cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 212cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 213cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCloseProtocolDestroyIpChild ( 214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ControllerHandle, 215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE ImageHandle, 216fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_HANDLE ChildHandle, 217b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IpVersion 218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 220cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 221fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_GUID *ServiceBindingGuid; 222fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_GUID *IpProtocolGuid; 223fb115c61504fe6c4f94be0a87f75e28e1684657ftye 224fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4) { 225fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid; 226fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid = &gEfiIp4ProtocolGuid; 227fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpVersion == IP_VERSION_6) { 228fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid; 229fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid = &gEfiIp6ProtocolGuid; 230fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 231fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_UNSUPPORTED; 232fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 2356aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Close the previously openned IP protocol. 236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->CloseProtocol ( 238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle, 239fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpProtocolGuid, 240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle 242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 243cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 244cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 2456aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // Destroy the IP child. 246cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = NetLibDestroyServiceChild ( 248cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ControllerHandle, 249cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ImageHandle, 250fb115c61504fe6c4f94be0a87f75e28e1684657ftye ServiceBindingGuid, 251cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ChildHandle 252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 253cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 254cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 255cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 256cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 257cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 258fb115c61504fe6c4f94be0a87f75e28e1684657ftye This function handles ICMPv4 packets. It is the worker function of 259fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoIcmpHandler. 260cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 261fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpIo Pointer to the IP_IO instance. 262fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in, out] Pkt Pointer to the ICMPv4 packet. 263fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Session Pointer to the net session of this ICMPv4 packet. 264cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 265fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_SUCCESS The ICMPv4 packet is handled successfully. 266fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_ABORTED This type of ICMPv4 packet is not supported. 267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 268cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 269cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 270fb115c61504fe6c4f94be0a87f75e28e1684657ftyeIpIoIcmpv4Handler ( 2716aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO *IpIo, 2726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 2736aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN EFI_NET_SESSION_DATA *Session 274cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 275cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 276cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP4_ICMP_ERROR_HEAD *IcmpHdr; 277cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_HEADER *IpHdr; 278b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IcmpErr; 279cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 *PayLoadHdr; 280cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Type; 281cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT8 Code; 282cbf316f20726bb31b7c37424601643790dbd02d9vanjeff UINT32 TrimBytes; 283cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 284fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT (IpIo->IpVersion == IP_VERSION_4); 285fb115c61504fe6c4f94be0a87f75e28e1684657ftye 286cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD); 287cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpHdr = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead); 288cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 289cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 290cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Check the ICMP packet length. 291cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 292cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) { 293cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Type = IcmpHdr->Head.Type; 298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Code = IcmpHdr->Head.Code; 299cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 300cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 301cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Analyze the ICMP Error in this ICMP pkt 302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 303cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Type) { 304cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_UNREACH: 305cbf316f20726bb31b7c37424601643790dbd02d9vanjeff switch (Code) { 306cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET: 307cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST: 308cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PROTOCOL: 309cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_PORT: 310cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_SRCFAIL: 311b45b45b2d248892930620c33a9d01d8457ae0e54tye IcmpErr = (UINT8) (ICMP_ERR_UNREACH_NET + Code); 312cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 313cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 314cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NEEDFRAG: 316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_MSGSIZE; 317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_UNKNOWN: 321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_NET_PROHIB: 322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSNET: 323cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_NET; 324cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 325cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 326cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 327cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_UNKNOWN: 328cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_ISOLATED: 329cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_HOST_PROHIB: 330cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_CODE_UNREACH_TOSHOST: 331cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_UNREACH_HOST; 332cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 333cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 334cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 335cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 336cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 337cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 338cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 339cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 340cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 341cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_TIMXCEED: 342cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 343cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 344cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 345cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 346b45b45b2d248892930620c33a9d01d8457ae0e54tye IcmpErr = (UINT8) (Code + ICMP_ERR_TIMXCEED_INTRANS); 347cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 348cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 349cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 350cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_PARAMPROB: 351cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code > 1) { 352cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 354cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_PARAMPROB; 356cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 357cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 358cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 359cbf316f20726bb31b7c37424601643790dbd02d9vanjeff case ICMP_TYPE_SOURCEQUENCH: 360cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (Code != 0) { 361cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 362cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 363cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 364cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IcmpErr = ICMP_ERR_QUENCH; 365cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 366cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 367cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 368cbf316f20726bb31b7c37424601643790dbd02d9vanjeff default: 369cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ABORTED; 370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 371cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 372cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 373cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Notify user the ICMP pkt only containing payload except 374cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // IP and ICMP header 375cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr)); 377cbf316f20726bb31b7c37424601643790dbd02d9vanjeff TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr); 378cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 379cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufTrim (Pkt, TrimBytes, TRUE); 380cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 381cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext); 382cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 383fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_SUCCESS; 384fb115c61504fe6c4f94be0a87f75e28e1684657ftye} 385fb115c61504fe6c4f94be0a87f75e28e1684657ftye 386fb115c61504fe6c4f94be0a87f75e28e1684657ftye/** 387fb115c61504fe6c4f94be0a87f75e28e1684657ftye This function handles ICMPv6 packets. It is the worker function of 388fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoIcmpHandler. 389fb115c61504fe6c4f94be0a87f75e28e1684657ftye 390fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpIo Pointer to the IP_IO instance. 391fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in, out] Pkt Pointer to the ICMPv6 packet. 392fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Session Pointer to the net session of this ICMPv6 packet. 393fb115c61504fe6c4f94be0a87f75e28e1684657ftye 394fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_SUCCESS The ICMPv6 packet is handled successfully. 395fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_ABORTED This type of ICMPv6 packet is not supported. 396fb115c61504fe6c4f94be0a87f75e28e1684657ftye 397fb115c61504fe6c4f94be0a87f75e28e1684657ftye**/ 398fb115c61504fe6c4f94be0a87f75e28e1684657ftyeEFI_STATUS 399fb115c61504fe6c4f94be0a87f75e28e1684657ftyeIpIoIcmpv6Handler ( 400fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN IP_IO *IpIo, 401fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN OUT NET_BUF *Pkt, 402fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_NET_SESSION_DATA *Session 403fb115c61504fe6c4f94be0a87f75e28e1684657ftye ) 404fb115c61504fe6c4f94be0a87f75e28e1684657ftye{ 405fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP6_ICMP_ERROR_HEAD *IcmpHdr; 406fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP6_HEADER *IpHdr; 407b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IcmpErr; 408fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT8 *PayLoadHdr; 409fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT8 Type; 410fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT8 Code; 411fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT8 NextHeader; 412fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT32 TrimBytes; 413fb115c61504fe6c4f94be0a87f75e28e1684657ftye BOOLEAN Flag; 414fb115c61504fe6c4f94be0a87f75e28e1684657ftye 415fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT (IpIo->IpVersion == IP_VERSION_6); 416fb115c61504fe6c4f94be0a87f75e28e1684657ftye 417fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 418fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Check the ICMPv6 packet length. 419fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 420fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Pkt->TotalSize < sizeof (IP6_ICMP_ERROR_HEAD)) { 421fb115c61504fe6c4f94be0a87f75e28e1684657ftye 422fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 423fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 424fb115c61504fe6c4f94be0a87f75e28e1684657ftye 425fb115c61504fe6c4f94be0a87f75e28e1684657ftye IcmpHdr = NET_PROTO_HDR (Pkt, IP6_ICMP_ERROR_HEAD); 426fb115c61504fe6c4f94be0a87f75e28e1684657ftye Type = IcmpHdr->Head.Type; 427fb115c61504fe6c4f94be0a87f75e28e1684657ftye Code = IcmpHdr->Head.Code; 428fb115c61504fe6c4f94be0a87f75e28e1684657ftye 429fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 430fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Analyze the ICMPv6 Error in this ICMPv6 packet 431fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 432fb115c61504fe6c4f94be0a87f75e28e1684657ftye switch (Type) { 433fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_DEST_UNREACHABLE: 434fb115c61504fe6c4f94be0a87f75e28e1684657ftye switch (Code) { 435fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_NO_ROUTE_TO_DEST: 436fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_BEYOND_SCOPE: 437fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_ROUTE_REJECTED: 438fb115c61504fe6c4f94be0a87f75e28e1684657ftye IcmpErr = ICMP6_ERR_UNREACH_NET; 439fb115c61504fe6c4f94be0a87f75e28e1684657ftye 440fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 441fb115c61504fe6c4f94be0a87f75e28e1684657ftye 442fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_COMM_PROHIBITED: 443fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_ADDR_UNREACHABLE: 444fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_SOURCE_ADDR_FAILED: 445fb115c61504fe6c4f94be0a87f75e28e1684657ftye IcmpErr = ICMP6_ERR_UNREACH_HOST; 446fb115c61504fe6c4f94be0a87f75e28e1684657ftye 447fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 448fb115c61504fe6c4f94be0a87f75e28e1684657ftye 449fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_PORT_UNREACHABLE: 450fb115c61504fe6c4f94be0a87f75e28e1684657ftye IcmpErr = ICMP6_ERR_UNREACH_PORT; 451fb115c61504fe6c4f94be0a87f75e28e1684657ftye 452fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 453fb115c61504fe6c4f94be0a87f75e28e1684657ftye 454fb115c61504fe6c4f94be0a87f75e28e1684657ftye default: 455fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 456fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 457fb115c61504fe6c4f94be0a87f75e28e1684657ftye 458fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 459fb115c61504fe6c4f94be0a87f75e28e1684657ftye 460fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_PACKET_TOO_BIG: 461fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Code >= 1) { 462fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 463fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 464fb115c61504fe6c4f94be0a87f75e28e1684657ftye 465fb115c61504fe6c4f94be0a87f75e28e1684657ftye IcmpErr = ICMP6_ERR_PACKAGE_TOOBIG; 466fb115c61504fe6c4f94be0a87f75e28e1684657ftye 467fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 468fb115c61504fe6c4f94be0a87f75e28e1684657ftye 469fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_TIME_EXCEEDED: 470fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Code > 1) { 471fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 472fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 473fb115c61504fe6c4f94be0a87f75e28e1684657ftye 474b45b45b2d248892930620c33a9d01d8457ae0e54tye IcmpErr = (UINT8) (ICMP6_ERR_TIMXCEED_HOPLIMIT + Code); 475fb115c61504fe6c4f94be0a87f75e28e1684657ftye 476fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 477fb115c61504fe6c4f94be0a87f75e28e1684657ftye 478fb115c61504fe6c4f94be0a87f75e28e1684657ftye case ICMP_V6_PARAMETER_PROBLEM: 479fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Code > 3) { 480fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 481fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 482fb115c61504fe6c4f94be0a87f75e28e1684657ftye 483b45b45b2d248892930620c33a9d01d8457ae0e54tye IcmpErr = (UINT8) (ICMP6_ERR_PARAMPROB_HEADER + Code); 484fb115c61504fe6c4f94be0a87f75e28e1684657ftye 485fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 486fb115c61504fe6c4f94be0a87f75e28e1684657ftye 487fb115c61504fe6c4f94be0a87f75e28e1684657ftye default: 488fb115c61504fe6c4f94be0a87f75e28e1684657ftye 489fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 490fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 491fb115c61504fe6c4f94be0a87f75e28e1684657ftye 492fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 493fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Notify user the ICMPv6 packet only containing payload except 494fb115c61504fe6c4f94be0a87f75e28e1684657ftye // IPv6 basic header, extension header and ICMP header 495fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 496fb115c61504fe6c4f94be0a87f75e28e1684657ftye 497fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpHdr = (EFI_IP6_HEADER *) (&IcmpHdr->IpHead); 498fb115c61504fe6c4f94be0a87f75e28e1684657ftye NextHeader = IpHdr->NextHeader; 499fb115c61504fe6c4f94be0a87f75e28e1684657ftye PayLoadHdr = (UINT8 *) ((UINT8 *) IcmpHdr + sizeof (IP6_ICMP_ERROR_HEAD)); 500fb115c61504fe6c4f94be0a87f75e28e1684657ftye Flag = TRUE; 501fb115c61504fe6c4f94be0a87f75e28e1684657ftye 502fb115c61504fe6c4f94be0a87f75e28e1684657ftye do { 503fb115c61504fe6c4f94be0a87f75e28e1684657ftye switch (NextHeader) { 504fb115c61504fe6c4f94be0a87f75e28e1684657ftye case EFI_IP_PROTO_UDP: 505fb115c61504fe6c4f94be0a87f75e28e1684657ftye case EFI_IP_PROTO_TCP: 506fb115c61504fe6c4f94be0a87f75e28e1684657ftye case EFI_IP_PROTO_ICMP: 507fb115c61504fe6c4f94be0a87f75e28e1684657ftye case IP6_NO_NEXT_HEADER: 508fb115c61504fe6c4f94be0a87f75e28e1684657ftye Flag = FALSE; 509fb115c61504fe6c4f94be0a87f75e28e1684657ftye 510fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 511fb115c61504fe6c4f94be0a87f75e28e1684657ftye 512fb115c61504fe6c4f94be0a87f75e28e1684657ftye case IP6_HOP_BY_HOP: 513fb115c61504fe6c4f94be0a87f75e28e1684657ftye case IP6_DESTINATION: 514fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 515fb115c61504fe6c4f94be0a87f75e28e1684657ftye // The Hdr Ext Len is 8-bit unsigned integer in 8-octet units, not including 516fb115c61504fe6c4f94be0a87f75e28e1684657ftye // the first 8 octets. 517fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 518fb115c61504fe6c4f94be0a87f75e28e1684657ftye NextHeader = *(PayLoadHdr); 519fb115c61504fe6c4f94be0a87f75e28e1684657ftye PayLoadHdr = (UINT8 *) (PayLoadHdr + (*(PayLoadHdr + 1) + 1) * 8); 520fb115c61504fe6c4f94be0a87f75e28e1684657ftye 521fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 522fb115c61504fe6c4f94be0a87f75e28e1684657ftye 523fb115c61504fe6c4f94be0a87f75e28e1684657ftye case IP6_FRAGMENT: 524fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 525fb115c61504fe6c4f94be0a87f75e28e1684657ftye // The Fragment Header Length is 8 octets. 526fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 527fb115c61504fe6c4f94be0a87f75e28e1684657ftye NextHeader = *(PayLoadHdr); 528fb115c61504fe6c4f94be0a87f75e28e1684657ftye PayLoadHdr = (UINT8 *) (PayLoadHdr + 8); 529fb115c61504fe6c4f94be0a87f75e28e1684657ftye 530fb115c61504fe6c4f94be0a87f75e28e1684657ftye break; 531fb115c61504fe6c4f94be0a87f75e28e1684657ftye 532fb115c61504fe6c4f94be0a87f75e28e1684657ftye default: 533fb115c61504fe6c4f94be0a87f75e28e1684657ftye 534fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_ABORTED; 535fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 536fb115c61504fe6c4f94be0a87f75e28e1684657ftye } while (Flag); 537fb115c61504fe6c4f94be0a87f75e28e1684657ftye 538fb115c61504fe6c4f94be0a87f75e28e1684657ftye TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr); 539fb115c61504fe6c4f94be0a87f75e28e1684657ftye 540fb115c61504fe6c4f94be0a87f75e28e1684657ftye NetbufTrim (Pkt, TrimBytes, TRUE); 541fb115c61504fe6c4f94be0a87f75e28e1684657ftye 542b45b45b2d248892930620c33a9d01d8457ae0e54tye IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext); 543fb115c61504fe6c4f94be0a87f75e28e1684657ftye 544cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 545cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 546cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 547fb115c61504fe6c4f94be0a87f75e28e1684657ftye/** 548fb115c61504fe6c4f94be0a87f75e28e1684657ftye This function handles ICMP packets. 549fb115c61504fe6c4f94be0a87f75e28e1684657ftye 550fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpIo Pointer to the IP_IO instance. 551fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in, out] Pkt Pointer to the ICMP packet. 552fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Session Pointer to the net session of this ICMP packet. 553fb115c61504fe6c4f94be0a87f75e28e1684657ftye 554fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_SUCCESS The ICMP packet is handled successfully. 555fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_ABORTED This type of ICMP packet is not supported. 556fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_UNSUPPORTED The IP protocol version in IP_IO is not supported. 557fb115c61504fe6c4f94be0a87f75e28e1684657ftye 558fb115c61504fe6c4f94be0a87f75e28e1684657ftye**/ 559fb115c61504fe6c4f94be0a87f75e28e1684657ftyeEFI_STATUS 560fb115c61504fe6c4f94be0a87f75e28e1684657ftyeIpIoIcmpHandler ( 561fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN IP_IO *IpIo, 562fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN OUT NET_BUF *Pkt, 563fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_NET_SESSION_DATA *Session 564fb115c61504fe6c4f94be0a87f75e28e1684657ftye ) 565fb115c61504fe6c4f94be0a87f75e28e1684657ftye{ 566fb115c61504fe6c4f94be0a87f75e28e1684657ftye 567fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 568fb115c61504fe6c4f94be0a87f75e28e1684657ftye 569fb115c61504fe6c4f94be0a87f75e28e1684657ftye return IpIoIcmpv4Handler (IpIo, Pkt, Session); 570fb115c61504fe6c4f94be0a87f75e28e1684657ftye 571fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpIo->IpVersion == IP_VERSION_6) { 572fb115c61504fe6c4f94be0a87f75e28e1684657ftye 573fb115c61504fe6c4f94be0a87f75e28e1684657ftye return IpIoIcmpv6Handler (IpIo, Pkt, Session); 574fb115c61504fe6c4f94be0a87f75e28e1684657ftye 575fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 576fb115c61504fe6c4f94be0a87f75e28e1684657ftye 577fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_UNSUPPORTED; 578fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 579fb115c61504fe6c4f94be0a87f75e28e1684657ftye} 580fb115c61504fe6c4f94be0a87f75e28e1684657ftye 581cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 582cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 583e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Free function for receive token of IP_IO. It is used to 584cbf316f20726bb31b7c37424601643790dbd02d9vanjeff signal the recycle event to notify IP to recycle the 585cbf316f20726bb31b7c37424601643790dbd02d9vanjeff data buffer. 586cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 5876aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event to be signaled. 588cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 589cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 590cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 591e798cd87ca9a3a30c4cea50c5f5de84e10a8bc5ageekboyEFIAPI 592cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoExtFree ( 593cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Event 594cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 595cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 596cbf316f20726bb31b7c37424601643790dbd02d9vanjeff gBS->SignalEvent ((EFI_EVENT) Event); 597cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 598cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 599cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 600cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 601cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a send entry to wrap a packet before sending 602cbf316f20726bb31b7c37424601643790dbd02d9vanjeff out it through IP. 603cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 6046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance. 6056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the packet. 6066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender Pointer to the IP sender. 6076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context Pointer to the context. 6086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] NotifyData Pointer to the notify data. 6096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest Pointer to the destination IP address. 6106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Override Pointer to the overriden IP_IO data. 611cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 612cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the data structure created to wrap the packet. If NULL, 6136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return resource limit occurred. 614cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 615cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 616cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_SEND_ENTRY * 617cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreateSndEntry ( 6186aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 6196aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 6202a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IN IP_IO_IP_PROTOCOL Sender, 6216aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 6226aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 623fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_IP_ADDRESS *Dest OPTIONAL, 6246aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *Override 625cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 626cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 627cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 628fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_EVENT Event; 629cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 630fb115c61504fe6c4f94be0a87f75e28e1684657ftye NET_FRAGMENT *ExtFragment; 631fb115c61504fe6c4f94be0a87f75e28e1684657ftye UINT32 FragmentCount; 632fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_IO_OVERRIDE *OverrideData; 633fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_IO_IP_TX_DATA *TxData; 634fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP4_TRANSMIT_DATA *Ip4TxData; 635fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP6_TRANSMIT_DATA *Ip6TxData; 636fb115c61504fe6c4f94be0a87f75e28e1684657ftye 637fb115c61504fe6c4f94be0a87f75e28e1684657ftye if ((IpIo->IpVersion != IP_VERSION_4) && (IpIo->IpVersion != IP_VERSION_6)) { 638fb115c61504fe6c4f94be0a87f75e28e1684657ftye return NULL; 639fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 640fb115c61504fe6c4f94be0a87f75e28e1684657ftye 641fb115c61504fe6c4f94be0a87f75e28e1684657ftye Event = NULL; 642fb115c61504fe6c4f94be0a87f75e28e1684657ftye TxData = NULL; 643fb115c61504fe6c4f94be0a87f75e28e1684657ftye OverrideData = NULL; 644cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 645cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 646cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for SndEntry 647cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 648e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY)); 649cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 650cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 651cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 652cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 653cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 654cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 655e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 656cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoTransmitHandler, 657cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry, 658fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Event 659cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 660cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 661fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto ON_ERROR; 662cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 663cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 664fb115c61504fe6c4f94be0a87f75e28e1684657ftye FragmentCount = Pkt->BlockOpNum; 665fb115c61504fe6c4f94be0a87f75e28e1684657ftye 666cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 667cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for TxData 668cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 669fb115c61504fe6c4f94be0a87f75e28e1684657ftye TxData = (IP_IO_IP_TX_DATA *) AllocatePool ( 670fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof (IP_IO_IP_TX_DATA) + sizeof (NET_FRAGMENT) * (FragmentCount - 1) 671cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 672cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 673cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == TxData) { 674fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto ON_ERROR; 675fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 676fb115c61504fe6c4f94be0a87f75e28e1684657ftye 677fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 678fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Build a fragment table to contain the fragments in the packet. 679fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 680fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 681fb115c61504fe6c4f94be0a87f75e28e1684657ftye ExtFragment = (NET_FRAGMENT *) TxData->Ip4TxData.FragmentTable; 682fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 683fb115c61504fe6c4f94be0a87f75e28e1684657ftye ExtFragment = (NET_FRAGMENT *) TxData->Ip6TxData.FragmentTable; 684cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 685cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 686fb115c61504fe6c4f94be0a87f75e28e1684657ftye NetbufBuildExt (Pkt, ExtFragment, &FragmentCount); 687fb115c61504fe6c4f94be0a87f75e28e1684657ftye 688fb115c61504fe6c4f94be0a87f75e28e1684657ftye 689cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 690cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Allocate resource for OverrideData if needed 691cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 692cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL != Override) { 693cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 694fb115c61504fe6c4f94be0a87f75e28e1684657ftye OverrideData = AllocateCopyPool (sizeof (IP_IO_OVERRIDE), Override); 695cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == OverrideData) { 696fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto ON_ERROR; 697cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 698cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 699cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 700cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 701fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Set other fields of TxData except the fragment table 702cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 703fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 704cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 705fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData = &TxData->Ip4TxData; 706cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 70735f910f08b58e978bc9251872635075d6f422e48Randy Pawell IP4_COPY_ADDRESS (&Ip4TxData->DestinationAddress, Dest); 708cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 709fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData->OverrideData = &OverrideData->Ip4OverrideData; 710fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData->OptionsLength = 0; 711fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData->OptionsBuffer = NULL; 712fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData->TotalDataLength = Pkt->TotalSize; 713fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip4TxData->FragmentCount = FragmentCount; 714fb115c61504fe6c4f94be0a87f75e28e1684657ftye 715fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 716fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Set the fields of SndToken 717fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 718fb115c61504fe6c4f94be0a87f75e28e1684657ftye SndEntry->SndToken.Ip4Token.Event = Event; 719fb115c61504fe6c4f94be0a87f75e28e1684657ftye SndEntry->SndToken.Ip4Token.Packet.TxData = Ip4TxData; 720fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 721fb115c61504fe6c4f94be0a87f75e28e1684657ftye 722fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData = &TxData->Ip6TxData; 723fb115c61504fe6c4f94be0a87f75e28e1684657ftye 724fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Dest != NULL) { 725fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem (&Ip6TxData->DestinationAddress, Dest, sizeof (EFI_IPv6_ADDRESS)); 726fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 727fb115c61504fe6c4f94be0a87f75e28e1684657ftye ZeroMem (&Ip6TxData->DestinationAddress, sizeof (EFI_IPv6_ADDRESS)); 728fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 729fb115c61504fe6c4f94be0a87f75e28e1684657ftye 730fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData->OverrideData = &OverrideData->Ip6OverrideData; 731fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData->DataLength = Pkt->TotalSize; 732fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData->FragmentCount = FragmentCount; 733fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData->ExtHdrsLength = 0; 734fb115c61504fe6c4f94be0a87f75e28e1684657ftye Ip6TxData->ExtHdrs = NULL; 735fb115c61504fe6c4f94be0a87f75e28e1684657ftye 736fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 737fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Set the fields of SndToken 738fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 739fb115c61504fe6c4f94be0a87f75e28e1684657ftye SndEntry->SndToken.Ip6Token.Event = Event; 740fb115c61504fe6c4f94be0a87f75e28e1684657ftye SndEntry->SndToken.Ip6Token.Packet.TxData = Ip6TxData; 741fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 742cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 743cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 744cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Set the fields of SndEntry 745cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 746cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->IpIo = IpIo; 7476aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu SndEntry->Ip = Sender; 748cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context = Context; 749cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData = NotifyData; 750cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 751cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Pkt = Pkt; 752cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_GET_REF (Pkt); 753cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 754e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry); 755cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 756cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return SndEntry; 757cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 758fb115c61504fe6c4f94be0a87f75e28e1684657ftyeON_ERROR: 759fb115c61504fe6c4f94be0a87f75e28e1684657ftye 760fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (OverrideData != NULL) { 761fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (OverrideData); 762fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 763cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 764fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (TxData != NULL) { 765fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (TxData); 766fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 767cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 768fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (SndEntry != NULL) { 769fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (SndEntry); 770fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 771cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 772fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Event != NULL) { 773fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (Event); 774fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 775cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 776cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 777cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 778cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 779cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 780cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 781cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy the SndEntry. 782e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 783e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoCreateSndEntry(). 784cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 7856aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] SndEntry Pointer to the send entry to be destroyed. 786cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 787cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 788cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 789cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroySndEntry ( 790cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO_SEND_ENTRY *SndEntry 791cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 792cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 793fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_EVENT Event; 794fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_IO_IP_TX_DATA *TxData; 795fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_IO_OVERRIDE *Override; 796fb115c61504fe6c4f94be0a87f75e28e1684657ftye 797fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (SndEntry->IpIo->IpVersion == IP_VERSION_4) { 798fb115c61504fe6c4f94be0a87f75e28e1684657ftye Event = SndEntry->SndToken.Ip4Token.Event; 799fb115c61504fe6c4f94be0a87f75e28e1684657ftye TxData = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip4Token.Packet.TxData; 800fb115c61504fe6c4f94be0a87f75e28e1684657ftye Override = (IP_IO_OVERRIDE *) TxData->Ip4TxData.OverrideData; 801fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (SndEntry->IpIo->IpVersion == IP_VERSION_6) { 802fb115c61504fe6c4f94be0a87f75e28e1684657ftye Event = SndEntry->SndToken.Ip6Token.Event; 803fb115c61504fe6c4f94be0a87f75e28e1684657ftye TxData = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip6Token.Packet.TxData; 804fb115c61504fe6c4f94be0a87f75e28e1684657ftye Override = (IP_IO_OVERRIDE *) TxData->Ip6TxData.OverrideData; 805fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 806fb115c61504fe6c4f94be0a87f75e28e1684657ftye return ; 807fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 808cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 809fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (Event); 810cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 811fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (TxData); 812fb115c61504fe6c4f94be0a87f75e28e1684657ftye 813fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (NULL != Override) { 814fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Override); 815cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 816cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 817cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (SndEntry->Pkt); 818cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 819e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&SndEntry->Entry); 820cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 821fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (SndEntry); 822cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 823cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 824cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 825cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 826cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Notify function for IP transmit token. 827cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8286aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 829cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 830cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 831cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 832cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 83336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandlerDpc ( 834cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 835cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 836cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 837cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 838cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 839fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_STATUS Status; 840cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 841cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = (IP_IO_SEND_ENTRY *) Context; 842cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 843cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo = SndEntry->IpIo; 844cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 845fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 846fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = SndEntry->SndToken.Ip4Token.Status; 847fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpIo->IpVersion == IP_VERSION_6){ 848fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = SndEntry->SndToken.Ip6Token.Status; 849fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 850fb115c61504fe6c4f94be0a87f75e28e1684657ftye return ; 851fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 852fb115c61504fe6c4f94be0a87f75e28e1684657ftye 8538de75da28bbd9a4d3c54fba99d943f9019b52193niry if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) { 854cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify ( 855fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status, 856cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Context, 857cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->Ip, 858cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry->NotifyData 859cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 860cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 861cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 862cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 863cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 864cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8656aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu 86636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 86736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for IP transmit token. 86836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 8696aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 8706aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 87136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 87236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 87336ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 87436ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 87536ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoTransmitHandler ( 87636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 87736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 87836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 87936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 88036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 88136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK 88236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 883d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney QueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context); 88436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 88536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 886cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 887cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 888cbf316f20726bb31b7c37424601643790dbd02d9vanjeff The dummy handler for the dummy IP receive token. 889cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 8906aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 891cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 892cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 893cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 894cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 89536ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandlerDpc ( 896cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 897cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 898cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 899cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 900fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_STATUS Status; 901fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_EVENT RecycleEvent; 902cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 903cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = (IP_IO_IP_INFO *) Context; 904cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 905fb115c61504fe6c4f94be0a87f75e28e1684657ftye if ((IpInfo->IpVersion != IP_VERSION_4) && (IpInfo->IpVersion != IP_VERSION_6)) { 906fb115c61504fe6c4f94be0a87f75e28e1684657ftye return ; 907fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 908fb115c61504fe6c4f94be0a87f75e28e1684657ftye 909fb115c61504fe6c4f94be0a87f75e28e1684657ftye RecycleEvent = NULL; 910fb115c61504fe6c4f94be0a87f75e28e1684657ftye 911fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4) { 912fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = IpInfo->DummyRcvToken.Ip4Token.Status; 913fb115c61504fe6c4f94be0a87f75e28e1684657ftye 914fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->DummyRcvToken.Ip4Token.Packet.RxData != NULL) { 915fb115c61504fe6c4f94be0a87f75e28e1684657ftye RecycleEvent = IpInfo->DummyRcvToken.Ip4Token.Packet.RxData->RecycleSignal; 916fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 917fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 918fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = IpInfo->DummyRcvToken.Ip6Token.Status; 919fb115c61504fe6c4f94be0a87f75e28e1684657ftye 920fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->DummyRcvToken.Ip6Token.Packet.RxData != NULL) { 921fb115c61504fe6c4f94be0a87f75e28e1684657ftye RecycleEvent = IpInfo->DummyRcvToken.Ip6Token.Packet.RxData->RecycleSignal; 922fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 923fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 924fb115c61504fe6c4f94be0a87f75e28e1684657ftye 925fb115c61504fe6c4f94be0a87f75e28e1684657ftye 926fb115c61504fe6c4f94be0a87f75e28e1684657ftye 927fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_ABORTED == Status) { 92836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 92936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 93036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 93136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 932fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (EFI_SUCCESS == Status) { 933fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 934fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Recycle the RxData. 935fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 936fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT (RecycleEvent != NULL); 937cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 938fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->SignalEvent (RecycleEvent); 939cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 940cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 941fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 942fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Continue the receive. 943fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 944fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4) { 9452a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip4->Receive ( 9462a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip4, 9472a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &IpInfo->DummyRcvToken.Ip4Token 9482a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 949fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 9502a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip6->Receive ( 9512a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip6, 9522a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &IpInfo->DummyRcvToken.Ip6Token 9532a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 954fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 955cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 956cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 957cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 958cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 9596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoDummyHandlerDpc to the end of the DPC queue. 960cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 9616aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 9626aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 963cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 964cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 965cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 966cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFIAPI 96736ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoDummyHandler ( 968cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_EVENT Event, 969cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Context 970cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 971cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 97236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 97336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK 97436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 975d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney QueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context); 97636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 97736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 97836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 97936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 98036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff Notify function for the IP receive token, used to process 98136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff the received IP packets. 98236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 9836aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 98436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 98536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 98636ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 98736ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 98836ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandlerDpc ( 98936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 99036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 99136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 992cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 993cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 994fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_IO_IP_RX_DATA *RxData; 995cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_NET_SESSION_DATA Session; 996cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_BUF *Pkt; 997cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 998fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo = (IP_IO *) Context; 999cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1000fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 1001fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = IpIo->RcvToken.Ip4Token.Status; 1002fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip4Token.Packet.RxData; 1003fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpIo->IpVersion == IP_VERSION_6) { 1004fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = IpIo->RcvToken.Ip6Token.Status; 1005fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip6Token.Packet.RxData; 1006fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1007fb115c61504fe6c4f94be0a87f75e28e1684657ftye return; 1008fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1009cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 101036ee91ca3661d3d020a7841aacbf858d885c4728vanjeff if (EFI_ABORTED == Status) { 101136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 101236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // The reception is actively aborted by the consumer, directly return. 101336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 101436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff return; 101536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff } 101636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 1017cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) { 1018cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 10196aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug Only process the normal packets and the icmp error packets, if RxData is NULL 10206aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although 10216aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug this should be a bug of the low layer (IP). 1022cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1023cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 1024cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1025cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1026cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo->PktRcvdNotify) { 1027cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 1028cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1029cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1030fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 1031fb115c61504fe6c4f94be0a87f75e28e1684657ftye if ((EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress) != 0) && 1032f6b7393ceb34c9b3a27434268bf2ce517047641ftye !NetIp4IsUnicast (EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *) RxData)->Header->SourceAddress), 0)) { 1033cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1034cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // The source address is not zero and it's not a unicast IP address, discard it. 1035cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1036cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 1037cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1038cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1039cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1040fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Create a netbuffer representing IPv4 packet 1041cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1042cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Pkt = NetbufFromExt ( 1043fb115c61504fe6c4f94be0a87f75e28e1684657ftye (NET_FRAGMENT *) RxData->Ip4RxData.FragmentTable, 1044fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData->Ip4RxData.FragmentCount, 1045cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 1046cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 0, 1047cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoExtFree, 1048fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData->Ip4RxData.RecycleSignal 1049cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1050cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == Pkt) { 1051cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto CleanUp; 1052cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1053cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1054cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1055cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create a net session 1056cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1057fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.Source.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress); 1058fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.Dest.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->DestinationAddress); 1059fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.IpHdr.Ip4Hdr = RxData->Ip4RxData.Header; 1060a09ee46d9a258ef08a931c0d412c62c98dbdb8aaqouyang Session.IpHdrLen = RxData->Ip4RxData.HeaderLength; 1061fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.IpVersion = IP_VERSION_4; 1062fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1063fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1064f6b7393ceb34c9b3a27434268bf2ce517047641ftye if (!NetIp6IsValidUnicast(&RxData->Ip6RxData.Header->SourceAddress)) { 1065fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto CleanUp; 1066fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1067fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1068fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 1069fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Create a netbuffer representing IPv6 packet 1070fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 1071fb115c61504fe6c4f94be0a87f75e28e1684657ftye Pkt = NetbufFromExt ( 1072fb115c61504fe6c4f94be0a87f75e28e1684657ftye (NET_FRAGMENT *) RxData->Ip6RxData.FragmentTable, 1073fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData->Ip6RxData.FragmentCount, 1074fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0, 1075fb115c61504fe6c4f94be0a87f75e28e1684657ftye 0, 1076fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoExtFree, 1077fb115c61504fe6c4f94be0a87f75e28e1684657ftye RxData->Ip6RxData.RecycleSignal 1078fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1079fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (NULL == Pkt) { 1080fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto CleanUp; 1081fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1082fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1083fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 1084fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Create a net session 1085fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 1086fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1087fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Session.Source, 1088fb115c61504fe6c4f94be0a87f75e28e1684657ftye &RxData->Ip6RxData.Header->SourceAddress, 1089fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof(EFI_IPv6_ADDRESS) 1090fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1091fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1092fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Session.Dest, 1093fb115c61504fe6c4f94be0a87f75e28e1684657ftye &RxData->Ip6RxData.Header->DestinationAddress, 1094fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof(EFI_IPv6_ADDRESS) 1095fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1096fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.IpHdr.Ip6Hdr = RxData->Ip6RxData.Header; 1097a09ee46d9a258ef08a931c0d412c62c98dbdb8aaqouyang Session.IpHdrLen = RxData->Ip6RxData.HeaderLength; 1098fb115c61504fe6c4f94be0a87f75e28e1684657ftye Session.IpVersion = IP_VERSION_6; 1099fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1100cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1101cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_SUCCESS == Status) { 1102cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1103b45b45b2d248892930620c33a9d01d8457ae0e54tye IpIo->PktRcvdNotify (EFI_SUCCESS, 0, &Session, Pkt, IpIo->RcvdContext); 1104cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 1105cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1106cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Status is EFI_ICMP_ERROR 1107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoIcmpHandler (IpIo, Pkt, &Session); 1109cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1110cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NetbufFree (Pkt); 1111cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1112cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1113cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1114cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto Resume; 1115cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1116cbf316f20726bb31b7c37424601643790dbd02d9vanjeffCleanUp: 1117fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1118fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4){ 1119fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->SignalEvent (RxData->Ip4RxData.RecycleSignal); 1120fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1121fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->SignalEvent (RxData->Ip6RxData.RecycleSignal); 1122fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1123cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1124cbf316f20726bb31b7c37424601643790dbd02d9vanjeffResume: 1125cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1126fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4){ 11272a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip4->Receive (IpIo->Ip.Ip4, &(IpIo->RcvToken.Ip4Token)); 1128fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 11292a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip6->Receive (IpIo->Ip.Ip6, &(IpIo->RcvToken.Ip6Token)); 1130fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1131fb115c61504fe6c4f94be0a87f75e28e1684657ftye} 1132cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1133cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 11346aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu This function add IpIoListenHandlerDpc to the end of the DPC queue. 113536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 11366aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Event The event signaled. 11376aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Context The context passed in by the event notifier. 113836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 113936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff**/ 114036ee91ca3661d3d020a7841aacbf858d885c4728vanjeffVOID 114136ee91ca3661d3d020a7841aacbf858d885c4728vanjeffEFIAPI 114236ee91ca3661d3d020a7841aacbf858d885c4728vanjeffIpIoListenHandler ( 114336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN EFI_EVENT Event, 114436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff IN VOID *Context 114536ee91ca3661d3d020a7841aacbf858d885c4728vanjeff ) 114636ee91ca3661d3d020a7841aacbf858d885c4728vanjeff{ 114736ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 114836ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK 114936ee91ca3661d3d020a7841aacbf858d885c4728vanjeff // 1150d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney QueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context); 115136ee91ca3661d3d020a7841aacbf858d885c4728vanjeff} 115236ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 115336ee91ca3661d3d020a7841aacbf858d885c4728vanjeff 115436ee91ca3661d3d020a7841aacbf858d885c4728vanjeff/** 1155cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Create a new IP_IO instance. 1156e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1157fb115c61504fe6c4f94be0a87f75e28e1684657ftye This function uses IP4/IP6 service binding protocol in Controller to create 1158fb115c61504fe6c4f94be0a87f75e28e1684657ftye an IP4/IP6 child (aka IP4/IP6 instance). 1159cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 11606aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Image The image handle of the driver or application that 1161e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong consumes IP_IO. 1162fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Controller The controller handle that has IP4 or IP6 service 1163fb115c61504fe6c4f94be0a87f75e28e1684657ftye binding protocol installed. 1164fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpVersion The version of the IP protocol to use, either 1165fb115c61504fe6c4f94be0a87f75e28e1684657ftye IPv4 or IPv6. 1166cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1167e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to a newly created IP_IO instance, or NULL if failed. 1168cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1169cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1170cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO * 11717b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1172cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCreate ( 1173cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN EFI_HANDLE Image, 1174fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_HANDLE Controller, 1175b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IpVersion 1176cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1177cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1178cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1179cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIo; 1180fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_EVENT Event; 1181fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1182fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1183cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1184e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpIo = AllocateZeroPool (sizeof (IP_IO)); 1185cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == IpIo) { 1186cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1187cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1188cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1189e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->PendingSndList)); 1190e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&(IpIo->IpList)); 1191cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller = Controller; 1192cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image = Image; 1193fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->IpVersion = IpVersion; 1194fb115c61504fe6c4f94be0a87f75e28e1684657ftye Event = NULL; 1195cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1196cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 1197cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 1198e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1199cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoListenHandler, 1200cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo, 1201fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Event 1202cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1203cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1204cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 1205cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1206cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1207fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4) { 1208fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->RcvToken.Ip4Token.Event = Event; 1209fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1210fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->RcvToken.Ip6Token.Event = Event; 1211fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1212fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1213cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1214cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create an IP child and open IP protocol 1215cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1216cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 1217cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Controller, 1218cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Image, 1219cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpIo->ChildHandle, 1220fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpVersion, 1221cbf316f20726bb31b7c37424601643790dbd02d9vanjeff (VOID **)&(IpIo->Ip) 1222cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1223cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1224cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpIo; 1225cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1226cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1227cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpIo; 1228cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1229cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpIo: 1230cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1231fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Event != NULL) { 1232fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (Event); 1233cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1234cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1235e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 1236cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1237cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1238cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1239cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1240cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1241cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1242cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Open an IP_IO instance for use. 1243e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1244e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoCreate(). It is used for configuring the IP 1245e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong instance and register the callbacks and their context data for sending and 1246e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong receiving IP packets. 1247cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12486aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance that needs 12496aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu to open. 12506aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OpenData The configuration data and callbacks for 12516aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu the IP_IO instance. 1252cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 12536aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance opened with OpenData 12546aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu successfully. 12556aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_ACCESS_DENIED The IP_IO instance is configured, avoid to 12566aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu reopen it. 12576aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 1258cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1259cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1260cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 12617b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1262cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoOpen ( 12636aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 12646aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OPEN_DATA *OpenData 1265cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1266cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1267cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1268b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IpVersion; 1269cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1270cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpIo->IsConfigured) { 1271cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_ACCESS_DENIED; 1272cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1273cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1274fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpVersion = IpIo->IpVersion; 1275fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1276fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1277fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1278cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1279cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // configure ip 1280cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1281fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4){ 12822a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip4->Configure ( 12832a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip4, 12842a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &OpenData->IpConfigData.Ip4CfgData 12852a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1286fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1287fb115c61504fe6c4f94be0a87f75e28e1684657ftye 12882a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip6->Configure ( 12892a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip6, 12902a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &OpenData->IpConfigData.Ip6CfgData 12912a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1292fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1293fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1294cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1295cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1296cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1297cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1298cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 12996aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug To delete the default route entry in this Ip, if it is: 13006aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified 13016aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // @bug its code 1302cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1303fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4){ 13042a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip4->Routes ( 13052a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip4, 13062a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang TRUE, 13072a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &mZeroIp4Addr, 13082a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &mZeroIp4Addr, 13092a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &mZeroIp4Addr 13102a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1311fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1312fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) { 1313fb115c61504fe6c4f94be0a87f75e28e1684657ftye return Status; 1314fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1315cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1316cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1317cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktRcvdNotify = OpenData->PktRcvdNotify; 1318cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->PktSentNotify = OpenData->PktSentNotify; 1319cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1320cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->RcvdContext = OpenData->RcvdContext; 1321cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->SndContext = OpenData->SndContext; 1322cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1323fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4){ 1324fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Protocol = OpenData->IpConfigData.Ip4CfgData.DefaultProtocol; 1325cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1326fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 1327fb115c61504fe6c4f94be0a87f75e28e1684657ftye // start to listen incoming packet 1328fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 13292a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip4->Receive ( 13302a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip4, 13312a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &(IpIo->RcvToken.Ip4Token) 13322a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1333fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_ERROR (Status)) { 13342a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL); 1335fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto ErrorExit; 1336fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1337fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1338fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1339fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1340fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Protocol = OpenData->IpConfigData.Ip6CfgData.DefaultProtocol; 13412a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip6->Receive ( 13422a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip6, 13432a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &(IpIo->RcvToken.Ip6Token) 13442a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1345fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_ERROR (Status)) { 13462a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL); 1347fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto ErrorExit; 1348fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1349cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1350cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1351cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = TRUE; 1352e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&mActiveIpIoList, &IpIo->Entry); 1353cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1354cbf316f20726bb31b7c37424601643790dbd02d9vanjeffErrorExit: 1355cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1356cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1357cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1358cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1359cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1360cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1361cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Stop an IP_IO instance. 1362e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1363e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoOpen(). The IP_IO will be unconfigured and all 1364e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong the pending send/receive tokens will be canceled. 1365cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13666aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to stop. 1367cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 13686aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance stopped successfully. 13696aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 1370cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1371cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1372cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 1373e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgongEFIAPI 1374cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoStop ( 13756aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 1376cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1377cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1378cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1379cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1380b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IpVersion; 1381cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1382cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 1383cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1384cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1385cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1386fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpVersion = IpIo->IpVersion; 1387fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1388fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1389fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1390cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1391cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Remove the IpIo from the active IpIo list. 1392cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1393e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpIo->Entry); 1394cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1395cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1396cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Configure NULL Ip 1397cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1398fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4) { 13992a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL); 1400fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 14012a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL); 1402fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1403cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1404cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1405cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1406cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1407cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->IsConfigured = FALSE; 1408cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1409cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1410cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Detroy the Ip List used by IpIo 1411cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 141234edf2ae729941a6203e4e7f614db32204a9c47dvanjeff 1413e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff while (!IsListEmpty (&(IpIo->IpList))) { 1414cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry); 1415cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1416cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoRemoveIp (IpIo, IpInfo); 1417cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1418cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1419cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 14206aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu // All pending send tokens should be flushed by reseting the IP instances. 1421cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1422e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff ASSERT (IsListEmpty (&IpIo->PendingSndList)); 1423cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1424cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1425cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the receive event. 1426cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1427fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4){ 1428fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (IpIo->RcvToken.Ip4Token.Event); 1429fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1430fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (IpIo->RcvToken.Ip6Token.Event); 1431fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1432cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1433cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1434cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1435cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1436cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1437cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1438cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP_IO instance. 1439e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1440e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is paired with IpIoCreate(). The IP_IO will be closed first. 14418f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu Resource will be freed afterwards. See IpIoCloseProtocolDestroyIpChild(). 1442cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 14436aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the IP_IO instance that needs to be 1444e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong destroyed. 1445cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 14466aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP_IO instance destroyed successfully. 14476aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Error condition occurred. 1448cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1449cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1450cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 14517b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1452cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoDestroy ( 14536aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 1454cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1455cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1456cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1457cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Stop the IpIo. 1458cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1459cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoStop (IpIo); 1460cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1461cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1462cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Close the IP protocol and destroy the child. 1463cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1464fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoCloseProtocolDestroyIpChild ( 1465fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Controller, 1466fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Image, 1467fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->ChildHandle, 1468fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->IpVersion 1469fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1470cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1471e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpIo); 1472cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1473cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1474cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1475cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1476cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1477cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1478cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Send out an IP packet. 1479e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1480e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called after IpIoOpen(). The data to be sent are wrapped in 1481e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Pkt. The IP instance wrapped in IpIo is used for sending by default but can be 1482e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong overriden by Sender. Other sending configs, like source address and gateway 1483e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong address etc., are specified in OverrideData. 1484cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 14856aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to an IP_IO instance used for sending IP 14866aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu packet. 14876aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] Pkt Pointer to the IP packet to be sent. 14886aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Sender The IP protocol instance used for sending. 14898f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] Context Optional context data. 14908f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] NotifyData Optional notify data. 14916aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Dest The destination IP address to send this packet to. 14926aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] OverrideData The data to override some configuration of the IP 14936aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance used for sending. 1494cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 14956aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The operation is completed successfully. 14966aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_NOT_STARTED The IpIo is not configured. 14976aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. 1498cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1499cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1500cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 15017b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1502cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoSend ( 15036aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo, 15046aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT NET_BUF *Pkt, 15056aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_IP_INFO *Sender OPTIONAL, 15066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *Context OPTIONAL, 15076aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN VOID *NotifyData OPTIONAL, 1508fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_IP_ADDRESS *Dest, 15096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN IP_IO_OVERRIDE *OverrideData OPTIONAL 1510cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1511cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1512cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 15132a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IP_IO_IP_PROTOCOL Ip; 1514cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 1515cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1516fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpIo->IpVersion != IP_VERSION_4) || (Dest != NULL)); 1517fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1518cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (!IpIo->IsConfigured) { 1519cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_NOT_STARTED; 1520cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1521cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1522cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip; 1523cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1524cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1525cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // create a new SndEntry 1526cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1527cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData); 1528cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (NULL == SndEntry) { 1529cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_OUT_OF_RESOURCES; 1530cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1531cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1532cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1533cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Send this Packet 1534cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1535fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4){ 15362a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip4->Transmit ( 15372a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4, 15382a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &SndEntry->SndToken.Ip4Token 15392a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1540fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 15412a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip6->Transmit ( 15422a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6, 15432a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &SndEntry->SndToken.Ip6Token 15442a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1545fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1546fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1547cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1548cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDestroySndEntry (SndEntry); 1549cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1550cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1551cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1552cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1553cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1554cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1555cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1556cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Cancel the IP transmit token which wraps this Packet. 1557cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 15586aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 15596aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Packet Pointer to the packet of NET_BUF to cancel. 1560cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1561cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1562cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 15637b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1564cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoCancelTxToken ( 1565cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN IP_IO *IpIo, 1566cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IN VOID *Packet 1567cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1568cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1569e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *Node; 1570cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_SEND_ENTRY *SndEntry; 15712a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IP_IO_IP_PROTOCOL Ip; 1572cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1573fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpIo != NULL) && (Packet != NULL)); 1574cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1575cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) { 1576cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1577cbf316f20726bb31b7c37424601643790dbd02d9vanjeff SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry); 1578cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1579cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (SndEntry->Pkt == Packet) { 1580cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1581cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = SndEntry->Ip; 1582fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1583fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpIo->IpVersion == IP_VERSION_4) { 15842a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4->Cancel ( 15852a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4, 15862a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &SndEntry->SndToken.Ip4Token 15872a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1588fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 15892a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6->Cancel ( 15902a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6, 15912a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &SndEntry->SndToken.Ip6Token 15922a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1593fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1594cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1595cbf316f20726bb31b7c37424601643790dbd02d9vanjeff break; 1596cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1597cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1598cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1599cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1600cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1601cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1602cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1603cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Add a new IP instance for sending data. 1604e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1605e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The function is used to add the IP_IO to the IP_IO sending list. The caller 1606e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong can later use IpIoFindSender() to get the IP_IO and call IpIoSend() to send 1607e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong data. 1608cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 16096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to a IP_IO instance to add a new IP 16106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance for sending purpose. 1611cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1612e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong @return Pointer to the created IP_IO_IP_INFO structure, NULL if failed. 1613cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1614cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1615cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 16167b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1617cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoAddIp ( 16186aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO *IpIo 1619cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1620cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1621cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 1622cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1623fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_EVENT Event; 1624cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 16256aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpIo != NULL); 1626cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1627e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO)); 1628cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo == NULL) { 1629fb115c61504fe6c4f94be0a87f75e28e1684657ftye return NULL; 1630cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1631cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1632cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1633cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP 1634cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // instance. 1635cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1636e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InitializeListHead (&IpInfo->Entry); 1637cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo->ChildHandle = NULL; 1638fb115c61504fe6c4f94be0a87f75e28e1684657ftye ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr)); 1639fb115c61504fe6c4f94be0a87f75e28e1684657ftye ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask)); 1640fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1641fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->RefCnt = 1; 1642fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->IpVersion = IpIo->IpVersion; 1643cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1644cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1645fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Create the IP instance and open the IP protocol. 1646cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1647cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = IpIoCreateIpChildOpenProtocol ( 1648cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1649cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1650cbf316f20726bb31b7c37424601643790dbd02d9vanjeff &IpInfo->ChildHandle, 1651fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->IpVersion, 16524eb65aff715faafd9040c6fc85a5d59e22343978vanjeff (VOID **) &IpInfo->Ip 1653cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1654cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1655cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpInfo; 1656cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1657cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1658cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1659cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Create the event for the DummyRcvToken. 1660cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1661cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Status = gBS->CreateEvent ( 1662cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EVT_NOTIFY_SIGNAL, 1663e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1664cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoDummyHandler, 1665cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo, 1666fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Event 1667cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1668cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1669cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto ReleaseIpChild; 1670cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1671cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1672fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4) { 1673fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->DummyRcvToken.Ip4Token.Event = Event; 1674fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1675fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->DummyRcvToken.Ip6Token.Event = Event; 1676fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1677fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1678cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1679cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // Link this IpInfo into the IpIo. 1680cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1681e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff InsertTailList (&IpIo->IpList, &IpInfo->Entry); 1682cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1683cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return IpInfo; 1684cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1685cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpChild: 1686cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1687cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoCloseProtocolDestroyIpChild ( 1688cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Controller, 1689cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIo->Image, 1690fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->ChildHandle, 1691fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->IpVersion 1692cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ); 1693cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1694cbf316f20726bb31b7c37424601643790dbd02d9vanjeffReleaseIpInfo: 1695cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1696e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff gBS->FreePool (IpInfo); 1697cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1698cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1699cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1700cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1701cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1702cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1703fb115c61504fe6c4f94be0a87f75e28e1684657ftye Configure the IP instance of this IpInfo and start the receiving if IpConfigData 1704cbf316f20726bb31b7c37424601643790dbd02d9vanjeff is not NULL. 1705cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 17066aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpInfo Pointer to the IP_IO_IP_INFO instance. 1707fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in, out] IpConfigData The IP configure data used to configure the IP 17086aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu instance, if NULL the IP instance is reset. If 17096aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu UseDefaultAddress is set to TRUE, and the configure 17106aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu operation succeeds, the default address information 1711fb115c61504fe6c4f94be0a87f75e28e1684657ftye is written back in this IpConfigData. 1712cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 17136aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval EFI_SUCCESS The IP instance of this IpInfo is configured successfully 17146aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu or no need to reconfigure it. 17156aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @retval Others Configuration fails. 1716cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1717cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1718cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 17197b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1720cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoConfigIp ( 17216aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu IN OUT IP_IO_IP_INFO *IpInfo, 1722fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN OUT VOID *IpConfigData OPTIONAL 1723cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1724cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1725cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_STATUS Status; 17262a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IP_IO_IP_PROTOCOL Ip; 1727b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IpVersion; 1728cbf316f20726bb31b7c37424601643790dbd02d9vanjeff EFI_IP4_MODE_DATA Ip4ModeData; 1729fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP6_MODE_DATA Ip6ModeData; 1730cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 17316aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu ASSERT (IpInfo != NULL); 1732cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1733cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 1) { 1734cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1735cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // This IP instance is shared, don't reconfigure it until it has only one 1736cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // consumer. Currently, only the tcp children cloned from their passive parent 1737fb115c61504fe6c4f94be0a87f75e28e1684657ftye // will share the same IP. So this cases only happens while IpConfigData is NULL, 1738cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // let the last consumer clean the IP instance. 1739cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1740cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return EFI_SUCCESS; 1741cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1742cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1743fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpVersion = IpInfo->IpVersion; 1744fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1745fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1746cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Ip = IpInfo->Ip; 1747cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1748fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4) { 17492a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip4->Configure (Ip.Ip4, IpConfigData); 1750fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 17512a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip6->Configure (Ip.Ip6, IpConfigData); 1752fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1753fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1754cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 1755cbf316f20726bb31b7c37424601643790dbd02d9vanjeff goto OnExit; 1756cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1757cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1758fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpConfigData != NULL) { 1759fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4){ 1760cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1761fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (((EFI_IP4_CONFIG_DATA *) IpConfigData)->UseDefaultAddress) { 17622a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4->GetModeData ( 17632a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4, 17642a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &Ip4ModeData, 17652a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL, 17662a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL 17672a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1768cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 176935f910f08b58e978bc9251872635075d6f422e48Randy Pawell IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->StationAddress, &Ip4ModeData.ConfigData.StationAddress); 177035f910f08b58e978bc9251872635075d6f422e48Randy Pawell IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->SubnetMask, &Ip4ModeData.ConfigData.SubnetMask); 1771cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1772cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1773fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1774fb115c61504fe6c4f94be0a87f75e28e1684657ftye &IpInfo->Addr.Addr, 1775fb115c61504fe6c4f94be0a87f75e28e1684657ftye &((EFI_IP4_CONFIG_DATA *) IpConfigData)->StationAddress, 1776fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof (IP4_ADDR) 1777fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1778fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1779fb115c61504fe6c4f94be0a87f75e28e1684657ftye &IpInfo->PreMask.SubnetMask, 1780fb115c61504fe6c4f94be0a87f75e28e1684657ftye &((EFI_IP4_CONFIG_DATA *) IpConfigData)->SubnetMask, 1781fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof (IP4_ADDR) 1782fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1783fb115c61504fe6c4f94be0a87f75e28e1684657ftye 17842a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip4->Receive ( 17852a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4, 17862a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &IpInfo->DummyRcvToken.Ip4Token 17872a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1788cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (EFI_ERROR (Status)) { 17892a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip4->Configure (Ip.Ip4, NULL); 1790cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1791cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } else { 17922a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6->GetModeData ( 17932a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6, 17942a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &Ip6ModeData, 17952a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL, 17962a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL 17972a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1798fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1799fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.IsConfigured) { 1800fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1801fb115c61504fe6c4f94be0a87f75e28e1684657ftye &((EFI_IP6_CONFIG_DATA *) IpConfigData)->StationAddress, 1802fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Ip6ModeData.ConfigData.StationAddress, 1803fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof (EFI_IPv6_ADDRESS) 1804fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1805fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1806fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.AddressList != NULL) { 1807fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.AddressList); 1808fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1809fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1810fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.GroupTable != NULL) { 1811fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.GroupTable); 1812fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1813fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1814fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.RouteTable != NULL) { 1815fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.RouteTable); 1816fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1817fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1818fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.NeighborCache != NULL) { 1819fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.NeighborCache); 1820fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1821fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1822fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.PrefixTable != NULL) { 1823fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.PrefixTable); 1824fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1825fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1826fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Ip6ModeData.IcmpTypeList != NULL) { 1827fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (Ip6ModeData.IcmpTypeList); 1828fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1829fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1830fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1831fb115c61504fe6c4f94be0a87f75e28e1684657ftye Status = EFI_NO_MAPPING; 1832fb115c61504fe6c4f94be0a87f75e28e1684657ftye goto OnExit; 1833fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1834fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1835fb115c61504fe6c4f94be0a87f75e28e1684657ftye CopyMem ( 1836fb115c61504fe6c4f94be0a87f75e28e1684657ftye &IpInfo->Addr, 1837fb115c61504fe6c4f94be0a87f75e28e1684657ftye &Ip6ModeData.ConfigData.StationAddress, 1838fb115c61504fe6c4f94be0a87f75e28e1684657ftye sizeof (EFI_IPv6_ADDRESS) 1839fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1840fb115c61504fe6c4f94be0a87f75e28e1684657ftye 18412a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Status = Ip.Ip6->Receive ( 18422a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6, 18432a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang &IpInfo->DummyRcvToken.Ip6Token 18442a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1845fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_ERROR (Status)) { 18462a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip.Ip6->Configure (Ip.Ip6, NULL); 1847fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1848fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1849fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1850cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1851fb115c61504fe6c4f94be0a87f75e28e1684657ftye // The IP instance is reset, set the stored Addr and SubnetMask to zero. 1852cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1853fb115c61504fe6c4f94be0a87f75e28e1684657ftye ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr)); 1854fb115c61504fe6c4f94be0a87f75e28e1684657ftye ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask)); 1855cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1856cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1857cbf316f20726bb31b7c37424601643790dbd02d9vanjeffOnExit: 1858cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1859cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return Status; 1860cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1861cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1862cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1863cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1864cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Destroy an IP instance maintained in IpIo->IpList for 1865cbf316f20726bb31b7c37424601643790dbd02d9vanjeff sending purpose. 1866e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1867e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function pairs with IpIoAddIp(). The IpInfo is previously created by 1868e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IpIoAddIp(). The IP_IO_IP_INFO::RefCnt is decremented and the IP instance 1869e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong will be dstroyed if the RefCnt is zero. 1870cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 18716aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpIo Pointer to the IP_IO instance. 18726aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] IpInfo Pointer to the IpInfo to be removed. 1873cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1874cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1875cbf316f20726bb31b7c37424601643790dbd02d9vanjeffVOID 18767b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1877cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoRemoveIp ( 1878e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO *IpIo, 1879e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong IN IP_IO_IP_INFO *IpInfo 1880cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1881cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1882fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1883b45b45b2d248892930620c33a9d01d8457ae0e54tye UINT8 IpVersion; 1884fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1885cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ASSERT (IpInfo->RefCnt > 0); 1886cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1887cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_PUT_REF (IpInfo); 1888cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1889cbf316f20726bb31b7c37424601643790dbd02d9vanjeff if (IpInfo->RefCnt > 0) { 1890cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1891cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return; 1892cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1893cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1894fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpVersion = IpIo->IpVersion; 1895fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1896fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1897fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1898e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff RemoveEntryList (&IpInfo->Entry); 1899cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1900fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpVersion == IP_VERSION_4){ 19012a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip4->Configure ( 19022a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip4, 19032a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL 19042a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1905fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoCloseProtocolDestroyIpChild ( 1906fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Controller, 1907fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Image, 1908fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->ChildHandle, 1909fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_VERSION_4 1910fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1911fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1912fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (IpInfo->DummyRcvToken.Ip4Token.Event); 1913cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1914fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1915cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 19162a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip6->Configure ( 19172a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang IpInfo->Ip.Ip6, 19182a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang NULL 19192a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang ); 1920cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1921fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIoCloseProtocolDestroyIpChild ( 1922fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Controller, 1923fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpIo->Image, 1924fb115c61504fe6c4f94be0a87f75e28e1684657ftye IpInfo->ChildHandle, 1925fb115c61504fe6c4f94be0a87f75e28e1684657ftye IP_VERSION_6 1926fb115c61504fe6c4f94be0a87f75e28e1684657ftye ); 1927fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1928fb115c61504fe6c4f94be0a87f75e28e1684657ftye gBS->CloseEvent (IpInfo->DummyRcvToken.Ip6Token.Event); 1929fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1930fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1931fb115c61504fe6c4f94be0a87f75e28e1684657ftye FreePool (IpInfo); 1932cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1933cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1934cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1935cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 1936cbf316f20726bb31b7c37424601643790dbd02d9vanjeff Find the first IP protocol maintained in IpIo whose local 1937fb115c61504fe6c4f94be0a87f75e28e1684657ftye address is the same as Src. 1938e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 1939e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong This function is called when the caller needs the IpIo to send data to the 1940e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong specified Src. The IpIo was added previously by IpIoAddIp(). 1941cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 19426aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in, out] IpIo Pointer to the pointer of the IP_IO instance. 1943fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpVersion The version of the IP protocol to use, either 1944fb115c61504fe6c4f94be0a87f75e28e1684657ftye IPv4 or IPv6. 19456aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @param[in] Src The local IP address. 1946cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1947cbf316f20726bb31b7c37424601643790dbd02d9vanjeff @return Pointer to the IP protocol can be used for sending purpose and its local 1948fb115c61504fe6c4f94be0a87f75e28e1684657ftye address is the same with Src. 1949cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1950cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 1951cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIP_IO_IP_INFO * 19527b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 1953cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoFindSender ( 1954fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN OUT IP_IO **IpIo, 1955b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IpVersion, 1956fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_IP_ADDRESS *Src 1957cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 1958cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 1959e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpIoEntry; 1960cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO *IpIoPtr; 1961e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff LIST_ENTRY *IpInfoEntry; 1962cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IP_IO_IP_INFO *IpInfo; 1963cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1964fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); 1965fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1966cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) { 1967cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry); 1968cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1969fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (((*IpIo != NULL) && (*IpIo != IpIoPtr)) || (IpIoPtr->IpVersion != IpVersion)) { 1970cbf316f20726bb31b7c37424601643790dbd02d9vanjeff continue; 1971cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1972cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1973cbf316f20726bb31b7c37424601643790dbd02d9vanjeff NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) { 1974cbf316f20726bb31b7c37424601643790dbd02d9vanjeff IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry); 1975fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IpInfo->IpVersion == IP_VERSION_4){ 1976fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1977fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_IP4_EQUAL (&IpInfo->Addr.v4, &Src->v4)) { 1978fb115c61504fe6c4f94be0a87f75e28e1684657ftye *IpIo = IpIoPtr; 1979fb115c61504fe6c4f94be0a87f75e28e1684657ftye return IpInfo; 1980fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1981fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1982fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 1983fb115c61504fe6c4f94be0a87f75e28e1684657ftye 1984fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (EFI_IP6_EQUAL (&IpInfo->Addr.v6, &Src->v6)) { 1985fb115c61504fe6c4f94be0a87f75e28e1684657ftye *IpIo = IpIoPtr; 1986fb115c61504fe6c4f94be0a87f75e28e1684657ftye return IpInfo; 1987fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1988fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 1989cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1990cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1991cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 1992cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1993cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1994cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // No match. 1995cbf316f20726bb31b7c37424601643790dbd02d9vanjeff // 1996cbf316f20726bb31b7c37424601643790dbd02d9vanjeff return NULL; 1997cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 1998cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 1999cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2000cbf316f20726bb31b7c37424601643790dbd02d9vanjeff/** 2001e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong Get the ICMP error map information. 2002e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong 2003e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong The ErrorStatus will be returned. The IsHard and Notify are optional. If they 2004e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong are not NULL, this routine will fill them. 2005cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 20068f5e6151d506b69e4156eeb401a3bbc9f03a4a8dywu @param[in] IcmpError IcmpError Type. 2007fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpVersion The version of the IP protocol to use, 20083b1464d5ac4e8b917c54b9f29a43ad972d2a2c85rsun either IPv4 or IPv6. 20093b1464d5ac4e8b917c54b9f29a43ad972d2a2c85rsun @param[out] IsHard If TRUE, indicates that it is a hard error. 20103b1464d5ac4e8b917c54b9f29a43ad972d2a2c85rsun @param[out] Notify If TRUE, SockError needs to be notified. 2011cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 20126aac5e5ff0dccb7e2603bb2639c0e271b30301f5ywu @return ICMP Error Status, such as EFI_NETWORK_UNREACHABLE. 2013cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2014cbf316f20726bb31b7c37424601643790dbd02d9vanjeff**/ 2015cbf316f20726bb31b7c37424601643790dbd02d9vanjeffEFI_STATUS 20167b414b4ed6ccdefce8e167ecc7d67ad64118eb94vanjeffEFIAPI 2017cbf316f20726bb31b7c37424601643790dbd02d9vanjeffIpIoGetIcmpErrStatus ( 2018b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IcmpError, 2019b45b45b2d248892930620c33a9d01d8457ae0e54tye IN UINT8 IpVersion, 2020e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *IsHard OPTIONAL, 2021e6ff63a51423a3cbc26bc463ec07ad22fb60e07djgong OUT BOOLEAN *Notify OPTIONAL 2022cbf316f20726bb31b7c37424601643790dbd02d9vanjeff ) 2023cbf316f20726bb31b7c37424601643790dbd02d9vanjeff{ 20243cf888f5f90526fa0d613c2a1486e0c1f416bd67tye if (IpVersion == IP_VERSION_4 ) { 2025b45b45b2d248892930620c33a9d01d8457ae0e54tye ASSERT (IcmpError <= ICMP_ERR_PARAMPROB); 2026687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 20273cf888f5f90526fa0d613c2a1486e0c1f416bd67tye if (IsHard != NULL) { 20283cf888f5f90526fa0d613c2a1486e0c1f416bd67tye *IsHard = mIcmpErrMap[IcmpError].IsHard; 20293cf888f5f90526fa0d613c2a1486e0c1f416bd67tye } 2030687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 20313cf888f5f90526fa0d613c2a1486e0c1f416bd67tye if (Notify != NULL) { 20323cf888f5f90526fa0d613c2a1486e0c1f416bd67tye *Notify = mIcmpErrMap[IcmpError].Notify; 20333cf888f5f90526fa0d613c2a1486e0c1f416bd67tye } 20343cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20353cf888f5f90526fa0d613c2a1486e0c1f416bd67tye switch (IcmpError) { 20363cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_UNREACH_NET: 20373cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_NETWORK_UNREACHABLE; 20383cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20393cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_TIMXCEED_INTRANS: 20403cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_TIMXCEED_REASS: 20413cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_UNREACH_HOST: 20423cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_HOST_UNREACHABLE; 20433cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20443cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_UNREACH_PROTOCOL: 20453cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_PROTOCOL_UNREACHABLE; 20463cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20473cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_UNREACH_PORT: 20483cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_PORT_UNREACHABLE; 20493cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20503cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_MSGSIZE: 20513cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_UNREACH_SRCFAIL: 20523cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_QUENCH: 20533cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP_ERR_PARAMPROB: 20543cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_ICMP_ERROR; 20553cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20563cf888f5f90526fa0d613c2a1486e0c1f416bd67tye default: 20573cf888f5f90526fa0d613c2a1486e0c1f416bd67tye ASSERT (FALSE); 20583cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_UNSUPPORTED; 20593cf888f5f90526fa0d613c2a1486e0c1f416bd67tye } 2060687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 2061fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else if (IpVersion == IP_VERSION_6) { 2062fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2063b45b45b2d248892930620c33a9d01d8457ae0e54tye ASSERT (IcmpError <= ICMP6_ERR_PARAMPROB_IPV6OPTION); 2064687a2e5f6902fa26c7a1d7a7705e0747c4095125vanjeff 2065fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (IsHard != NULL) { 2066fb115c61504fe6c4f94be0a87f75e28e1684657ftye *IsHard = mIcmp6ErrMap[IcmpError].IsHard; 2067fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 2068fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2069fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (Notify != NULL) { 2070fb115c61504fe6c4f94be0a87f75e28e1684657ftye *Notify = mIcmp6ErrMap[IcmpError].Notify; 2071fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 20723cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20733cf888f5f90526fa0d613c2a1486e0c1f416bd67tye switch (IcmpError) { 20743cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_UNREACH_NET: 20753cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_NETWORK_UNREACHABLE; 20763cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20773cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_UNREACH_HOST: 20783cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_TIMXCEED_HOPLIMIT: 20793cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_TIMXCEED_REASS: 20803cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_HOST_UNREACHABLE; 20813cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20823cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_UNREACH_PROTOCOL: 20833cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_PROTOCOL_UNREACHABLE; 20843cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20853cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_UNREACH_PORT: 20863cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_PORT_UNREACHABLE; 20873cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20883cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_PACKAGE_TOOBIG: 20893cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_PARAMPROB_HEADER: 20903cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_PARAMPROB_NEXHEADER: 20913cf888f5f90526fa0d613c2a1486e0c1f416bd67tye case ICMP6_ERR_PARAMPROB_IPV6OPTION: 20923cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_ICMP_ERROR; 20933cf888f5f90526fa0d613c2a1486e0c1f416bd67tye 20943cf888f5f90526fa0d613c2a1486e0c1f416bd67tye default: 20953cf888f5f90526fa0d613c2a1486e0c1f416bd67tye ASSERT (FALSE); 20963cf888f5f90526fa0d613c2a1486e0c1f416bd67tye return EFI_UNSUPPORTED; 20973cf888f5f90526fa0d613c2a1486e0c1f416bd67tye } 2098fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2099fb115c61504fe6c4f94be0a87f75e28e1684657ftye } else { 2100fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 2101fb115c61504fe6c4f94be0a87f75e28e1684657ftye // Should never be here 2102fb115c61504fe6c4f94be0a87f75e28e1684657ftye // 2103fb115c61504fe6c4f94be0a87f75e28e1684657ftye ASSERT (FALSE); 2104fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_UNSUPPORTED; 2105fb115c61504fe6c4f94be0a87f75e28e1684657ftye } 2106fb115c61504fe6c4f94be0a87f75e28e1684657ftye} 2107cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2108cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2109fb115c61504fe6c4f94be0a87f75e28e1684657ftye/** 2110fb115c61504fe6c4f94be0a87f75e28e1684657ftye Refresh the remote peer's Neighbor Cache entries. 2111fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2112fb115c61504fe6c4f94be0a87f75e28e1684657ftye This function is called when the caller needs the IpIo to refresh the existing 2113fb115c61504fe6c4f94be0a87f75e28e1684657ftye IPv6 neighbor cache entries since the neighbor is considered reachable by the 2114fb115c61504fe6c4f94be0a87f75e28e1684657ftye node has recently received a confirmation that packets sent recently to the 2115fb115c61504fe6c4f94be0a87f75e28e1684657ftye neighbor were received by its IP layer. 2116fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2117fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] IpIo Pointer to an IP_IO instance 2118fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Neighbor The IP address of the neighbor 2119fb115c61504fe6c4f94be0a87f75e28e1684657ftye @param[in] Timeout Time in 100-ns units that this entry will 2120fb115c61504fe6c4f94be0a87f75e28e1684657ftye remain in the neighbor cache. A value of 2121fb115c61504fe6c4f94be0a87f75e28e1684657ftye zero means that the entry is permanent. 2122fb115c61504fe6c4f94be0a87f75e28e1684657ftye A value of non-zero means that the entry is 2123fb115c61504fe6c4f94be0a87f75e28e1684657ftye dynamic and will be deleted after Timeout. 2124fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2125fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_SUCCESS The operation is completed successfully. 2126fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_NOT_STARTED The IpIo is not configured. 2127fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_INVALID_PARAMETER Neighbor Address is invalid. 2128fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_NOT_FOUND The neighbor cache entry is not in the 2129fb115c61504fe6c4f94be0a87f75e28e1684657ftye neighbor table. 2130fb115c61504fe6c4f94be0a87f75e28e1684657ftye @retval EFI_OUT_OF_RESOURCES Failed due to resource limit. 2131cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2132fb115c61504fe6c4f94be0a87f75e28e1684657ftye**/ 2133fb115c61504fe6c4f94be0a87f75e28e1684657ftyeEFI_STATUS 2134fb115c61504fe6c4f94be0a87f75e28e1684657ftyeIpIoRefreshNeighbor ( 2135fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN IP_IO *IpIo, 2136fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN EFI_IP_ADDRESS *Neighbor, 2137fb115c61504fe6c4f94be0a87f75e28e1684657ftye IN UINT32 Timeout 2138fb115c61504fe6c4f94be0a87f75e28e1684657ftye ) 2139fb115c61504fe6c4f94be0a87f75e28e1684657ftye{ 2140fb115c61504fe6c4f94be0a87f75e28e1684657ftye EFI_IP6_PROTOCOL *Ip; 2141fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2142fb115c61504fe6c4f94be0a87f75e28e1684657ftye if (!IpIo->IsConfigured || IpIo->IpVersion != IP_VERSION_6) { 2143fb115c61504fe6c4f94be0a87f75e28e1684657ftye return EFI_NOT_STARTED; 2144cbf316f20726bb31b7c37424601643790dbd02d9vanjeff } 2145cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 21462a2e33b20feb245572416333bf26eb8a77e73aa9qianouyang Ip = IpIo->Ip.Ip6; 2147fb115c61504fe6c4f94be0a87f75e28e1684657ftye 2148fb115c61504fe6c4f94be0a87f75e28e1684657ftye return Ip->Neighbors (Ip, FALSE, &Neighbor->v6, NULL, Timeout, TRUE); 2149cbf316f20726bb31b7c37424601643790dbd02d9vanjeff} 2150cbf316f20726bb31b7c37424601643790dbd02d9vanjeff 2151