1dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/** @file 2f737cfb953905f42f3324e8e53ec324a15314210jgong Interface routines for PxeBc. 3e285199897e538523f762cb5b3900e81f872035avanjeff 414e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang LuboCopyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> 5e5eed7d3641d71d7ea539e5379ea9c6a5cd97004hhtianThis program and the accompanying materials 6dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffare licensed and made available under the terms and conditions of the BSD License 7dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffwhich accompanies this distribution. The full text of the license may be found at 8dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffhttp://opensource.org/licenses/bsd-license.php 9dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 10dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 13dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 14dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 15dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 16dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff#include "PxeBcImpl.h" 17dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 18434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeffUINT32 mPxeDhcpTimeout[4] = { 4, 8, 16, 32 }; 19f737cfb953905f42f3324e8e53ec324a15314210jgong 20982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff/** 21f737cfb953905f42f3324e8e53ec324a15314210jgong Get and record the arp cache. 22982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 23982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @param This Pointer to EFI_PXE_BC_PROTOCOL 24982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 25982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @retval EFI_SUCCESS Arp cache updated successfully 26f737cfb953905f42f3324e8e53ec324a15314210jgong @retval others If error occurs when getting arp cache 27982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 28982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff**/ 29982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffEFI_STATUS 30982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffUpdateArpCache ( 31982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN EFI_PXE_BASE_CODE_PROTOCOL * This 32982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ) 33982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff{ 34982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff PXEBC_PRIVATE_DATA *Private; 35982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_PXE_BASE_CODE_MODE *Mode; 36982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_STATUS Status; 37982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT32 EntryLength; 38982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT32 EntryCount; 39982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_ARP_FIND_DATA *Entries; 40982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT32 Index; 41982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 42982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 43982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode = Private->PxeBc.Mode; 44982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 45f737cfb953905f42f3324e8e53ec324a15314210jgong Status = Private->Arp->Find ( 46f737cfb953905f42f3324e8e53ec324a15314210jgong Private->Arp, 47f737cfb953905f42f3324e8e53ec324a15314210jgong TRUE, 48f737cfb953905f42f3324e8e53ec324a15314210jgong NULL, 49f737cfb953905f42f3324e8e53ec324a15314210jgong &EntryLength, 50f737cfb953905f42f3324e8e53ec324a15314210jgong &EntryCount, 51f737cfb953905f42f3324e8e53ec324a15314210jgong &Entries, 52f737cfb953905f42f3324e8e53ec324a15314210jgong TRUE 53f737cfb953905f42f3324e8e53ec324a15314210jgong ); 54982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 55982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return Status; 56982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 57982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 58f737cfb953905f42f3324e8e53ec324a15314210jgong Mode->ArpCacheEntries = MIN ( 59f737cfb953905f42f3324e8e53ec324a15314210jgong EntryCount, 60f737cfb953905f42f3324e8e53ec324a15314210jgong EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 61f737cfb953905f42f3324e8e53ec324a15314210jgong ); 62982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff for (Index = 0; Index < Mode->ArpCacheEntries; Index ++) { 63f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 64e285199897e538523f762cb5b3900e81f872035avanjeff &Mode->ArpCache[Index].IpAddr, 65e285199897e538523f762cb5b3900e81f872035avanjeff Entries + 1, 66f737cfb953905f42f3324e8e53ec324a15314210jgong Entries->SwAddressLength 67f737cfb953905f42f3324e8e53ec324a15314210jgong ); 68f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 69f737cfb953905f42f3324e8e53ec324a15314210jgong &Mode->ArpCache[Index].MacAddr, 70f737cfb953905f42f3324e8e53ec324a15314210jgong (UINT8 *) (Entries + 1) + Entries->SwAddressLength, 71f737cfb953905f42f3324e8e53ec324a15314210jgong Entries->HwAddressLength 72f737cfb953905f42f3324e8e53ec324a15314210jgong ); 73982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 74982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Slip to the next FindData. 75982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 76f737cfb953905f42f3324e8e53ec324a15314210jgong Entries = (EFI_ARP_FIND_DATA *) ((UINT8 *) Entries + EntryLength); 77982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 78982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 79982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return EFI_SUCCESS; 80982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff} 81982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 82982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff/** 83f737cfb953905f42f3324e8e53ec324a15314210jgong Timeout routine to update arp cache. 84982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 85982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @param Event Pointer to EFI_PXE_BC_PROTOCOL 86982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @param Context Context of the timer event 87982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 88982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff**/ 89982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffVOID 90982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffEFIAPI 91982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffArpCacheUpdateTimeout ( 92982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN EFI_EVENT Event, 93982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN VOID *Context 94982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ) 95982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff{ 96982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UpdateArpCache ((EFI_PXE_BASE_CODE_PROTOCOL *) Context); 97982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff} 98982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 99982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff/** 100f737cfb953905f42f3324e8e53ec324a15314210jgong Do arp resolution from arp cache in PxeBcMode. 101e285199897e538523f762cb5b3900e81f872035avanjeff 102f737cfb953905f42f3324e8e53ec324a15314210jgong @param PxeBcMode The PXE BC mode to look into. 103f737cfb953905f42f3324e8e53ec324a15314210jgong @param Ip4Addr The Ip4 address for resolution. 104f737cfb953905f42f3324e8e53ec324a15314210jgong @param MacAddress The resoluted MAC address if the resolution is successful. 105f737cfb953905f42f3324e8e53ec324a15314210jgong The value is undefined if resolution fails. 106e285199897e538523f762cb5b3900e81f872035avanjeff 107f737cfb953905f42f3324e8e53ec324a15314210jgong @retval TRUE The resolution is successful. 108f737cfb953905f42f3324e8e53ec324a15314210jgong @retval FALSE Otherwise. 109982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 110982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff**/ 111982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffBOOLEAN 112982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffFindInArpCache ( 113f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_MODE *PxeBcMode, 114f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_IPv4_ADDRESS *Ip4Addr, 115f737cfb953905f42f3324e8e53ec324a15314210jgong OUT EFI_MAC_ADDRESS *MacAddress 116982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ) 117982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff{ 118982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT32 Index; 119982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 120982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff for (Index = 0; Index < PxeBcMode->ArpCacheEntries; Index ++) { 121982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_IP4_EQUAL (&PxeBcMode->ArpCache[Index].IpAddr.v4, Ip4Addr)) { 122f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 123f737cfb953905f42f3324e8e53ec324a15314210jgong MacAddress, 124f737cfb953905f42f3324e8e53ec324a15314210jgong &PxeBcMode->ArpCache[Index].MacAddr, 125f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_MAC_ADDRESS) 126f737cfb953905f42f3324e8e53ec324a15314210jgong ); 127982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return TRUE; 128982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 129982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 130982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 131982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return FALSE; 132982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff} 133982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 134982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff/** 135982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Notify function for the ICMP receive token, used to process 136982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff the received ICMP packets. 137982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 138f737cfb953905f42f3324e8e53ec324a15314210jgong @param Context The PXEBC private data. 139982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 140982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff**/ 141982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffVOID 142982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffEFIAPI 143982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffIcmpErrorListenHandlerDpc ( 144982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN VOID *Context 145982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ) 146982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff{ 147982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_STATUS Status; 148982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_IP4_RECEIVE_DATA *RxData; 149982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_IP4_PROTOCOL *Ip4; 150982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff PXEBC_PRIVATE_DATA *Private; 151982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_PXE_BASE_CODE_MODE *Mode; 152982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINTN Index; 153982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT32 CopiedLen; 154982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UINT8 *CopiedPointer; 155982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 156982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private = (PXEBC_PRIVATE_DATA *) Context; 157982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode = &Private->Mode; 158982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = Private->IcmpErrorRcvToken.Status; 159982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff RxData = Private->IcmpErrorRcvToken.Packet.RxData; 160982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Ip4 = Private->Ip4; 161982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 162f737cfb953905f42f3324e8e53ec324a15314210jgong if (Status == EFI_ABORTED) { 163982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 164982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // The reception is actively aborted by the consumer, directly return. 165982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 166982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return; 167982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 168982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 169f737cfb953905f42f3324e8e53ec324a15314210jgong if (EFI_ERROR (Status) || (RxData == NULL)) { 170982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 171982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Only process the normal packets and the icmp error packets, if RxData is NULL 172982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although 173982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // this should be a bug of the low layer (IP). 174982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 175982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto Resume; 176982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 177982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 178f737cfb953905f42f3324e8e53ec324a15314210jgong if (EFI_IP4 (RxData->Header->SourceAddress) != 0 && 179f6b7393ceb34c9b3a27434268bf2ce517047641ftye !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), 0)) { 180982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 181982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // The source address is not zero and it's not a unicast IP address, discard it. 182982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 183982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto CleanUp; 184982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 185982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 186982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) { 187982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 188982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // The dest address is not equal to Station Ip address, discard it. 189982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 190982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto CleanUp; 191982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 192982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 193982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 194982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Constructor ICMP error packet 195982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 196982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff CopiedLen = 0; 197982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff CopiedPointer = (UINT8 *) &Mode->IcmpError; 198982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 199982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff for (Index = 0; Index < RxData->FragmentCount; Index ++) { 200982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff CopiedLen += RxData->FragmentTable[Index].FragmentLength; 201982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) { 202f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 203f737cfb953905f42f3324e8e53ec324a15314210jgong CopiedPointer, 204f737cfb953905f42f3324e8e53ec324a15314210jgong RxData->FragmentTable[Index].FragmentBuffer, 205f737cfb953905f42f3324e8e53ec324a15314210jgong RxData->FragmentTable[Index].FragmentLength 206f737cfb953905f42f3324e8e53ec324a15314210jgong ); 207982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } else { 208f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 209f737cfb953905f42f3324e8e53ec324a15314210jgong CopiedPointer, 210f737cfb953905f42f3324e8e53ec324a15314210jgong RxData->FragmentTable[Index].FragmentBuffer, 211f737cfb953905f42f3324e8e53ec324a15314210jgong CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR) 212f737cfb953905f42f3324e8e53ec324a15314210jgong ); 213982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 214982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff CopiedPointer += CopiedLen; 215982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 216982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 217982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto Resume; 218982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 219982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffCleanUp: 220982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->SignalEvent (RxData->RecycleSignal); 221982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 222982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffResume: 223982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Ip4->Receive (Ip4, &(Private->IcmpErrorRcvToken)); 224982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff} 225982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 226982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff/** 227982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Request IcmpErrorListenHandlerDpc as a DPC at TPL_CALLBACK 228982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 229982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @param Event The event signaled. 230982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff @param Context The context passed in by the event notifier. 231982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 232982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff**/ 233982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffVOID 234982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffEFIAPI 235982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffIcmpErrorListenHandler ( 236982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN EFI_EVENT Event, 237982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IN VOID *Context 238982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ) 239982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff{ 240982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 241982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK 242982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 243d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney QueueDpc (TPL_CALLBACK, IcmpErrorListenHandlerDpc, Context); 244982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff} 245dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 246e285199897e538523f762cb5b3900e81f872035avanjeff/** 247f737cfb953905f42f3324e8e53ec324a15314210jgong Enables the use of the PXE Base Code Protocol functions. 248f737cfb953905f42f3324e8e53ec324a15314210jgong 249f737cfb953905f42f3324e8e53ec324a15314210jgong This function enables the use of the PXE Base Code Protocol functions. If the 250f737cfb953905f42f3324e8e53ec324a15314210jgong Started field of the EFI_PXE_BASE_CODE_MODE structure is already TRUE, then 251f737cfb953905f42f3324e8e53ec324a15314210jgong EFI_ALREADY_STARTED will be returned. If UseIpv6 is TRUE, then IPv6 formatted 252f737cfb953905f42f3324e8e53ec324a15314210jgong addresses will be used in this session. If UseIpv6 is FALSE, then IPv4 formatted 253f737cfb953905f42f3324e8e53ec324a15314210jgong addresses will be used in this session. If UseIpv6 is TRUE, and the Ipv6Supported 254f737cfb953905f42f3324e8e53ec324a15314210jgong field of the EFI_PXE_BASE_CODE_MODE structure is FALSE, then EFI_UNSUPPORTED will 255f737cfb953905f42f3324e8e53ec324a15314210jgong be returned. If there is not enough memory or other resources to start the PXE 256f737cfb953905f42f3324e8e53ec324a15314210jgong Base Code Protocol, then EFI_OUT_OF_RESOURCES will be returned. Otherwise, the 257f737cfb953905f42f3324e8e53ec324a15314210jgong PXE Base Code Protocol will be started, and all of the fields of the EFI_PXE_BASE_CODE_MODE 258f737cfb953905f42f3324e8e53ec324a15314210jgong structure will be initialized as follows: 259f737cfb953905f42f3324e8e53ec324a15314210jgong StartedSet to TRUE. 260f737cfb953905f42f3324e8e53ec324a15314210jgong Ipv6SupportedUnchanged. 261f737cfb953905f42f3324e8e53ec324a15314210jgong Ipv6AvailableUnchanged. 262f737cfb953905f42f3324e8e53ec324a15314210jgong UsingIpv6Set to UseIpv6. 263f737cfb953905f42f3324e8e53ec324a15314210jgong BisSupportedUnchanged. 264f737cfb953905f42f3324e8e53ec324a15314210jgong BisDetectedUnchanged. 265f737cfb953905f42f3324e8e53ec324a15314210jgong AutoArpSet to TRUE. 266f737cfb953905f42f3324e8e53ec324a15314210jgong SendGUIDSet to FALSE. 267f737cfb953905f42f3324e8e53ec324a15314210jgong TTLSet to DEFAULT_TTL. 268f737cfb953905f42f3324e8e53ec324a15314210jgong ToSSet to DEFAULT_ToS. 269f737cfb953905f42f3324e8e53ec324a15314210jgong DhcpCompletedSet to FALSE. 270f737cfb953905f42f3324e8e53ec324a15314210jgong ProxyOfferReceivedSet to FALSE. 271f737cfb953905f42f3324e8e53ec324a15314210jgong StationIpSet to an address of all zeros. 272f737cfb953905f42f3324e8e53ec324a15314210jgong SubnetMaskSet to a subnet mask of all zeros. 273f737cfb953905f42f3324e8e53ec324a15314210jgong DhcpDiscoverZero-filled. 274f737cfb953905f42f3324e8e53ec324a15314210jgong DhcpAckZero-filled. 275f737cfb953905f42f3324e8e53ec324a15314210jgong ProxyOfferZero-filled. 276f737cfb953905f42f3324e8e53ec324a15314210jgong PxeDiscoverValidSet to FALSE. 277f737cfb953905f42f3324e8e53ec324a15314210jgong PxeDiscoverZero-filled. 278f737cfb953905f42f3324e8e53ec324a15314210jgong PxeReplyValidSet to FALSE. 279f737cfb953905f42f3324e8e53ec324a15314210jgong PxeReplyZero-filled. 280f737cfb953905f42f3324e8e53ec324a15314210jgong PxeBisReplyValidSet to FALSE. 281f737cfb953905f42f3324e8e53ec324a15314210jgong PxeBisReplyZero-filled. 282f737cfb953905f42f3324e8e53ec324a15314210jgong IpFilterSet the Filters field to 0 and the IpCnt field to 0. 283f737cfb953905f42f3324e8e53ec324a15314210jgong ArpCacheEntriesSet to 0. 284f737cfb953905f42f3324e8e53ec324a15314210jgong ArpCacheZero-filled. 285f737cfb953905f42f3324e8e53ec324a15314210jgong RouteTableEntriesSet to 0. 286f737cfb953905f42f3324e8e53ec324a15314210jgong RouteTableZero-filled. 287f737cfb953905f42f3324e8e53ec324a15314210jgong IcmpErrorReceivedSet to FALSE. 288f737cfb953905f42f3324e8e53ec324a15314210jgong IcmpErrorZero-filled. 289f737cfb953905f42f3324e8e53ec324a15314210jgong TftpErroReceivedSet to FALSE. 290f737cfb953905f42f3324e8e53ec324a15314210jgong TftpErrorZero-filled. 291f737cfb953905f42f3324e8e53ec324a15314210jgong MakeCallbacksSet to TRUE if the PXE Base Code Callback Protocol is available. 292f737cfb953905f42f3324e8e53ec324a15314210jgong Set to FALSE if the PXE Base Code Callback Protocol is not available. 293e285199897e538523f762cb5b3900e81f872035avanjeff 294f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 295f737cfb953905f42f3324e8e53ec324a15314210jgong @param UseIpv6 Specifies the type of IP addresses that are to be used during the session 296e285199897e538523f762cb5b3900e81f872035avanjeff that is being started. Set to TRUE for IPv6 addresses, and FALSE for 297e285199897e538523f762cb5b3900e81f872035avanjeff IPv4 addresses. 298e285199897e538523f762cb5b3900e81f872035avanjeff 299f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The PXE Base Code Protocol was started. 300e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this oper 301f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_UNSUPPORTED UseIpv6 is TRUE, but the Ipv6Supported field of the 302e285199897e538523f762cb5b3900e81f872035avanjeff EFI_PXE_BASE_CODE_MODE structure is FALSE. 303e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_ALREADY_STARTED The PXE Base Code Protocol is already in the started state. 304f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid 305e285199897e538523f762cb5b3900e81f872035avanjeff EFI_PXE_BASE_CODE_PROTOCOL structure. 306e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory or other resources to start the 307e285199897e538523f762cb5b3900e81f872035avanjeff PXE Base Code Protocol. 308e285199897e538523f762cb5b3900e81f872035avanjeff 309dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 310dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 311dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 312dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcStart ( 313dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 314dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN UseIpv6 315dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 316dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 317dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 318dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 319dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 320dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 321dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 322dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 323dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 324dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 325dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 326dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 327dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 328dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Mode->Started) { 329dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_ALREADY_STARTED; 330dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 331dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 332dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (UseIpv6) { 333dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 334dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // IPv6 is not supported now. 335dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 336dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_UNSUPPORTED; 337dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 338dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 339dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 340dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Configure the udp4 instance to let it receive data 341dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 342f737cfb953905f42f3324e8e53ec324a15314210jgong Status = Private->Udp4Read->Configure ( 343e285199897e538523f762cb5b3900e81f872035avanjeff Private->Udp4Read, 344f737cfb953905f42f3324e8e53ec324a15314210jgong &Private->Udp4CfgData 345f737cfb953905f42f3324e8e53ec324a15314210jgong ); 346dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 347dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 348dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 349dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 350cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan 351cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // 352cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // Configure block size for TFTP as a default value to handle all link layers. 353cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // 354cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan Private->BlockSize = (UINTN) (MIN (Private->Ip4MaxPacketSize, PXEBC_DEFAULT_PACKET_SIZE) - 355cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan PXEBC_DEFAULT_UDP_OVERHEAD_SIZE - PXEBC_DEFAULT_TFTP_OVERHEAD_SIZE); 356cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // 357cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // If PcdTftpBlockSize is set to non-zero, override the default value. 358cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan // 359cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan if (PcdGet64 (PcdTftpBlockSize) != 0) { 360cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan Private->BlockSize = (UINTN) PcdGet64 (PcdTftpBlockSize); 361cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan } 362cfbc1a7537d55ff0066b5635855f5739d02d15dchhuan 363dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->AddressIsOk = FALSE; 364dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 365dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ZeroMem (Mode, sizeof (EFI_PXE_BASE_CODE_MODE)); 366dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 367dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->Started = TRUE; 368dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->TTL = DEFAULT_TTL; 369dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->ToS = DEFAULT_ToS; 370dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->AutoArp = TRUE; 371dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 372982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 373982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Create the event for Arp Cache checking. 374982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 375982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = gBS->CreateEvent ( 376982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EVT_TIMER | EVT_NOTIFY_SIGNAL, 377982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff TPL_CALLBACK, 378982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ArpCacheUpdateTimeout, 379982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff This, 380982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff &Private->GetArpCacheEvent 381982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ); 382982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 383982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto ON_EXIT; 384982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 385982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 386982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 387982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Start the timeout timer event. 388982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 389982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = gBS->SetTimer ( 390982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private->GetArpCacheEvent, 391982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff TimerPeriodic, 392982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff TICKS_PER_SECOND 393982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ); 394982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 395982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 396982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto ON_EXIT; 397982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 398982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 399982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 400982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Create ICMP error receiving event 401982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 402982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = gBS->CreateEvent ( 403982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EVT_NOTIFY_SIGNAL, 404982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff TPL_NOTIFY, 405982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IcmpErrorListenHandler, 406982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private, 407982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff &(Private->IcmpErrorRcvToken.Event) 408982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff ); 409982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 410982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto ON_EXIT; 411982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 412982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 41314e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo // 41414e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo //DHCP4 service allows only one of its children to be configured in 41514e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo //the active state, If the DHCP4 D.O.R.A started by IP4 auto 41614e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo //configuration and has not been completed, the Dhcp4 state machine 41714e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo //will not be in the right state for the PXE to start a new round D.O.R.A. 41814e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo //so we need to switch it's policy to static. 41914e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo // 42014e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo Status = PxeBcSetIp4Policy (Private); 42114e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo if (EFI_ERROR (Status)) { 42214e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo goto ON_EXIT; 42314e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo } 42414e84fd8888bfcc0f0d8fae8b69c6428b4226d1dZhang Lubo 425982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4ConfigData); 426982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 427982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff goto ON_EXIT; 428982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 429982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 430982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 431982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // start to listen incoming packet 432982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 433982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpErrorRcvToken); 434982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!EFI_ERROR (Status)) { 435982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return Status; 436982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 437982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 438982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeffON_EXIT: 439982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private->Ip4->Configure (Private->Ip4, NULL); 440982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 441982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Private->IcmpErrorRcvToken.Event != NULL) { 442982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->CloseEvent (Private->IcmpErrorRcvToken.Event); 443982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 444982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 445982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Private->GetArpCacheEvent != NULL) { 446982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->SetTimer (Private->GetArpCacheEvent, TimerCancel, 0); 447982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->CloseEvent (Private->GetArpCacheEvent); 448982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 449982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 450982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->Started = FALSE; 451982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->TTL = 0; 452982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->ToS = 0; 453982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->AutoArp = FALSE; 454982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 455982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return Status; 456dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 457dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 458dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 459e285199897e538523f762cb5b3900e81f872035avanjeff/** 460f737cfb953905f42f3324e8e53ec324a15314210jgong Disables the use of the PXE Base Code Protocol functions. 461f737cfb953905f42f3324e8e53ec324a15314210jgong 462f737cfb953905f42f3324e8e53ec324a15314210jgong This function stops all activity on the network device. All the resources allocated 463f737cfb953905f42f3324e8e53ec324a15314210jgong in Start() are released, the Started field of the EFI_PXE_BASE_CODE_MODE structure is 464f737cfb953905f42f3324e8e53ec324a15314210jgong set to FALSE and EFI_SUCCESS is returned. If the Started field of the EFI_PXE_BASE_CODE_MODE 465f737cfb953905f42f3324e8e53ec324a15314210jgong structure is already FALSE, then EFI_NOT_STARTED will be returned. 466e285199897e538523f762cb5b3900e81f872035avanjeff 467f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 468e285199897e538523f762cb5b3900e81f872035avanjeff 469f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The PXE Base Code Protocol was stopped. 470e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_NOT_STARTED The PXE Base Code Protocol is already in the stopped state. 471f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid 472e285199897e538523f762cb5b3900e81f872035avanjeff EFI_PXE_BASE_CODE_PROTOCOL structure. 473e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 474e285199897e538523f762cb5b3900e81f872035avanjeff 475dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 476dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 477dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 478dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcStop ( 479dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This 480dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 481dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 482dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 483dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 484dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 485dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 486dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 487dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 488dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 489dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 490dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 491dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 492dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 493dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 494dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 495dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 496982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private->Ip4->Cancel (Private->Ip4, NULL); 497982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 498982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's 499982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // events. 500982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 501d8d26fb207e02aa5ef57e2bcb213f9dda16166ccmdkinney DispatchDpc (); 502982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 503982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Private->Ip4->Configure (Private->Ip4, NULL); 504982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 505982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 506982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Close the ICMP error receiving event. 507982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 508982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->CloseEvent (Private->IcmpErrorRcvToken.Event); 509982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 510982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 511982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Cancel the TimeoutEvent timer. 512982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 513982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->SetTimer (Private->GetArpCacheEvent, TimerCancel, 0); 514982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 515982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 516982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Close the TimeoutEvent event. 517982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 518982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff gBS->CloseEvent (Private->GetArpCacheEvent); 519982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 520dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->Started = FALSE; 521dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 5228792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Private->CurrentUdpSrcPort = 0; 5238792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Private->Udp4Write->Configure (Private->Udp4Write, NULL); 524434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Private->Udp4Read->Groups (Private->Udp4Read, FALSE, NULL); 5258792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Private->Udp4Read->Configure (Private->Udp4Read, NULL); 526dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 527dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Dhcp4->Stop (Private->Dhcp4); 528dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Dhcp4->Configure (Private->Dhcp4, NULL); 529dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 530dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->FileSize = 0; 531dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 532dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_SUCCESS; 533dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 534dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 535dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 536e285199897e538523f762cb5b3900e81f872035avanjeff/** 537f737cfb953905f42f3324e8e53ec324a15314210jgong Attempts to complete a DHCPv4 D.O.R.A. (discover / offer / request / acknowledge) or DHCPv6 538f737cfb953905f42f3324e8e53ec324a15314210jgong S.A.R.R (solicit / advertise / request / reply) sequence. 539f737cfb953905f42f3324e8e53ec324a15314210jgong 540f737cfb953905f42f3324e8e53ec324a15314210jgong This function attempts to complete the DHCP sequence. If this sequence is completed, 541f737cfb953905f42f3324e8e53ec324a15314210jgong then EFI_SUCCESS is returned, and the DhcpCompleted, ProxyOfferReceived, StationIp, 542f737cfb953905f42f3324e8e53ec324a15314210jgong SubnetMask, DhcpDiscover, DhcpAck, and ProxyOffer fields of the EFI_PXE_BASE_CODE_MODE 543f737cfb953905f42f3324e8e53ec324a15314210jgong structure are filled in. 544f737cfb953905f42f3324e8e53ec324a15314210jgong If SortOffers is TRUE, then the cached DHCP offer packets will be sorted before 545f737cfb953905f42f3324e8e53ec324a15314210jgong they are tried. If SortOffers is FALSE, then the cached DHCP offer packets will 546f737cfb953905f42f3324e8e53ec324a15314210jgong be tried in the order in which they are received. Please see the Preboot Execution 547f737cfb953905f42f3324e8e53ec324a15314210jgong Environment (PXE) Specification for additional details on the implementation of DHCP. 548f737cfb953905f42f3324e8e53ec324a15314210jgong This function can take at least 31 seconds to timeout and return control to the 549f737cfb953905f42f3324e8e53ec324a15314210jgong caller. If the DHCP sequence does not complete, then EFI_TIMEOUT will be returned. 550f737cfb953905f42f3324e8e53ec324a15314210jgong If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, 551f737cfb953905f42f3324e8e53ec324a15314210jgong then the DHCP sequence will be stopped and EFI_ABORTED will be returned. 552e285199897e538523f762cb5b3900e81f872035avanjeff 553f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 554f737cfb953905f42f3324e8e53ec324a15314210jgong @param SortOffers TRUE if the offers received should be sorted. Set to FALSE to try the 555e285199897e538523f762cb5b3900e81f872035avanjeff offers in the order that they are received. 556e285199897e538523f762cb5b3900e81f872035avanjeff 557f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS Valid DHCP has completed. 558f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 559f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid 560e285199897e538523f762cb5b3900e81f872035avanjeff EFI_PXE_BASE_CODE_PROTOCOL structure. 561e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 562f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete the DHCP Protocol. 563f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The callback function aborted the DHCP Protocol. 564f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TIMEOUT The DHCP Protocol timed out. 565f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ICMP_ERROR An ICMP error packet was received during the DHCP session. 566f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NO_RESPONSE Valid PXE offer was not received. 567e285199897e538523f762cb5b3900e81f872035avanjeff 568dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 569dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 570dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 571dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcDhcp ( 572dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 573dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN SortOffers 574dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 575dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 5768730386e6d669ded738c6f846aa26bf1c96228bfhhuan PXEBC_PRIVATE_DATA *Private; 5778730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_PXE_BASE_CODE_MODE *Mode; 5788730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_DHCP4_PROTOCOL *Dhcp4; 5798730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_DHCP4_CONFIG_DATA Dhcp4CfgData; 5808730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_DHCP4_MODE_DATA Dhcp4Mode; 5818730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_DHCP4_PACKET_OPTION *OptList[PXEBC_DHCP4_MAX_OPTION_NUM]; 5828730386e6d669ded738c6f846aa26bf1c96228bfhhuan UINT32 OptCount; 5838730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_STATUS Status; 5848730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_ARP_CONFIG_DATA ArpConfigData; 5858730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_PXE_BASE_CODE_IP_FILTER IpFilter; 586dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 587dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 588dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 589dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 590dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 591dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_SUCCESS; 592dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 593dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 594dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4 = Private->Dhcp4; 595dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP; 596dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->SortOffers = SortOffers; 597dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 598dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 599dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 600dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 601982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 602982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 603982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 604dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 6058730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Stop Udp4Read instance 6068730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 6078730386e6d669ded738c6f846aa26bf1c96228bfhhuan Private->Udp4Read->Configure (Private->Udp4Read, NULL); 6088730386e6d669ded738c6f846aa26bf1c96228bfhhuan 6098730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 610dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Initialize the DHCP options and build the option list 611dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 612dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff OptCount = PxeBcBuildDhcpOptions (Private, OptList, TRUE); 613dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 614dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 615dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Set the DHCP4 config data. 616434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // The four discovery timeouts are 4, 8, 16, 32 seconds respectively. 617dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 618e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA)); 619dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4CfgData.OptionCount = OptCount; 620dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4CfgData.OptionList = OptList; 621dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4CfgData.Dhcp4Callback = PxeBcDhcpCallBack; 622dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4CfgData.CallbackContext = Private; 623434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Dhcp4CfgData.DiscoverTryCount = 4; 624434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Dhcp4CfgData.DiscoverTimeout = mPxeDhcpTimeout; 625dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 626434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); 627434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff if (EFI_ERROR (Status)) { 628434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff goto ON_EXIT; 629434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff } 630e285199897e538523f762cb5b3900e81f872035avanjeff 631434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // 632434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // Zero those arrays to record the varies numbers of DHCP OFFERS. 633434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // 634434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Private->GotProxyOffer = FALSE; 635434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Private->NumOffers = 0; 636434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Private->BootpIndex = 0; 637434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff ZeroMem (Private->ServerCount, sizeof (Private->ServerCount)); 638434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex)); 639dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 640434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Status = Dhcp4->Start (Dhcp4, NULL); 641cbfb9e5eaf51aa351842aaa58efd1c2a8a38ef3aZhang Lubo if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { 642434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff if (Status == EFI_ICMP_ERROR) { 643434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Mode->IcmpErrorReceived = TRUE; 644dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 645434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff goto ON_EXIT; 646434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff } 647dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 648434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode); 649434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff if (EFI_ERROR (Status)) { 650434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff goto ON_EXIT; 651434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff } 652dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 653434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff ASSERT (Dhcp4Mode.State == Dhcp4Bound); 654dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 655434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS)); 656434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 657434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS)); 658319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff 659434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff CopyMem (&Mode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); 660434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff CopyMem (&Mode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 661dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 662434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // 663434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // Check the selected offer to see whether BINL is required, if no or BINL is 664434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // finished, set the various Mode members. 665434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff // 666434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff Status = PxeBcCheckSelectedOffer (Private); 667dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 668434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeffON_EXIT: 669dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 670dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4->Stop (Dhcp4); 671dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4->Configure (Dhcp4, NULL); 672dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 673dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 674dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Remove the previously configured option list and callback function 675dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 676e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA)); 677dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); 678dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 679dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->AddressIsOk = TRUE; 6808d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 6818d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (!Mode->UsingIpv6) { 6828d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 6838d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // If in IPv4 mode, configure the corresponding ARP with this new 6848d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // station IP address. 6858d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 6868d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA)); 6878d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 6888d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ArpConfigData.SwAddressType = 0x0800; 689c9325700d0ef25eaf45077928af3f93b15ac5fe0ydong ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS); 6908d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ArpConfigData.StationAddress = &Private->StationIp.v4; 6918d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 6928d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private->Arp->Configure (Private->Arp, NULL); 6938d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private->Arp->Configure (Private->Arp, &ArpConfigData); 694982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 695982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 696982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Updated the route table. Fill the first entry. 697982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 698982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTableEntries = 1; 699982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].IpAddr.Addr[0] = Private->StationIp.Addr[0] & Private->SubnetMask.Addr[0]; 700982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].SubnetMask.Addr[0] = Private->SubnetMask.Addr[0]; 701982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].GwAddr.Addr[0] = 0; 702982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 703982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 704982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Create the default route entry if there is a default router. 705982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 706982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Private->GatewayIp.Addr[0] != 0) { 707982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTableEntries = 2; 708982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[1].IpAddr.Addr[0] = 0; 709982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[1].SubnetMask.Addr[0] = 0; 710982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[1].GwAddr.Addr[0] = Private->GatewayIp.Addr[0]; 711982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 7128730386e6d669ded738c6f846aa26bf1c96228bfhhuan 7138730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7148730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Flush new station IP address into Udp4CfgData and Ip4ConfigData 7158730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7168730386e6d669ded738c6f846aa26bf1c96228bfhhuan CopyMem (&Private->Udp4CfgData.StationAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); 7178730386e6d669ded738c6f846aa26bf1c96228bfhhuan CopyMem (&Private->Udp4CfgData.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 7188730386e6d669ded738c6f846aa26bf1c96228bfhhuan CopyMem (&Private->Ip4ConfigData.StationAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); 7198730386e6d669ded738c6f846aa26bf1c96228bfhhuan CopyMem (&Private->Ip4ConfigData.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 7208730386e6d669ded738c6f846aa26bf1c96228bfhhuan 7218730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7228730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address. 7238730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7248730386e6d669ded738c6f846aa26bf1c96228bfhhuan Private->Ip4->Cancel (Private->Ip4, &Private->IcmpErrorRcvToken); 7258730386e6d669ded738c6f846aa26bf1c96228bfhhuan Private->Ip4->Configure (Private->Ip4, NULL); 7268730386e6d669ded738c6f846aa26bf1c96228bfhhuan 7278730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4ConfigData); 7288730386e6d669ded738c6f846aa26bf1c96228bfhhuan if (EFI_ERROR (Status)) { 7298730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 7308730386e6d669ded738c6f846aa26bf1c96228bfhhuan } 7318730386e6d669ded738c6f846aa26bf1c96228bfhhuan 7328730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpErrorRcvToken); 7338730386e6d669ded738c6f846aa26bf1c96228bfhhuan if (EFI_ERROR (Status)) { 7348730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 7358730386e6d669ded738c6f846aa26bf1c96228bfhhuan } 7368d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 737dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 738dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 739357af28525c3a5be6ca0a201f2533dc0a372dbfbsfu Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); 740c82291bc3108c948a66d659da0fd76731351f530hhuan 7418730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7428730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP 7438730386e6d669ded738c6f846aa26bf1c96228bfhhuan // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. 7448730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 7458730386e6d669ded738c6f846aa26bf1c96228bfhhuan ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER)); 7468730386e6d669ded738c6f846aa26bf1c96228bfhhuan IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP; 7478730386e6d669ded738c6f846aa26bf1c96228bfhhuan This->SetIpFilter (This, &IpFilter); 7488730386e6d669ded738c6f846aa26bf1c96228bfhhuan 749dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 750dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 751dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 752dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 753e285199897e538523f762cb5b3900e81f872035avanjeff/** 754f737cfb953905f42f3324e8e53ec324a15314210jgong Attempts to complete the PXE Boot Server and/or boot image discovery sequence. 755f737cfb953905f42f3324e8e53ec324a15314210jgong 756f737cfb953905f42f3324e8e53ec324a15314210jgong This function attempts to complete the PXE Boot Server and/or boot image discovery 757f737cfb953905f42f3324e8e53ec324a15314210jgong sequence. If this sequence is completed, then EFI_SUCCESS is returned, and the 758f737cfb953905f42f3324e8e53ec324a15314210jgong PxeDiscoverValid, PxeDiscover, PxeReplyReceived, and PxeReply fields of the 759f737cfb953905f42f3324e8e53ec324a15314210jgong EFI_PXE_BASE_CODE_MODE structure are filled in. If UseBis is TRUE, then the 760f737cfb953905f42f3324e8e53ec324a15314210jgong PxeBisReplyReceived and PxeBisReply fields of the EFI_PXE_BASE_CODE_MODE structure 761f737cfb953905f42f3324e8e53ec324a15314210jgong will also be filled in. If UseBis is FALSE, then PxeBisReplyValid will be set to FALSE. 762f737cfb953905f42f3324e8e53ec324a15314210jgong In the structure referenced by parameter Info, the PXE Boot Server list, SrvList[], 763f737cfb953905f42f3324e8e53ec324a15314210jgong has two uses: It is the Boot Server IP address list used for unicast discovery 764f737cfb953905f42f3324e8e53ec324a15314210jgong (if the UseUCast field is TRUE), and it is the list used for Boot Server verification 765f737cfb953905f42f3324e8e53ec324a15314210jgong (if the MustUseList field is TRUE). Also, if the MustUseList field in that structure 766f737cfb953905f42f3324e8e53ec324a15314210jgong is TRUE and the AcceptAnyResponse field in the SrvList[] array is TRUE, any Boot 767f737cfb953905f42f3324e8e53ec324a15314210jgong Server reply of that type will be accepted. If the AcceptAnyResponse field is 768f737cfb953905f42f3324e8e53ec324a15314210jgong FALSE, only responses from Boot Servers with matching IP addresses will be accepted. 769f737cfb953905f42f3324e8e53ec324a15314210jgong This function can take at least 10 seconds to timeout and return control to the 770f737cfb953905f42f3324e8e53ec324a15314210jgong caller. If the Discovery sequence does not complete, then EFI_TIMEOUT will be 771f737cfb953905f42f3324e8e53ec324a15314210jgong returned. Please see the Preboot Execution Environment (PXE) Specification for 772f737cfb953905f42f3324e8e53ec324a15314210jgong additional details on the implementation of the Discovery sequence. 773f737cfb953905f42f3324e8e53ec324a15314210jgong If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, 774f737cfb953905f42f3324e8e53ec324a15314210jgong then the Discovery sequence is stopped and EFI_ABORTED will be returned. 775e285199897e538523f762cb5b3900e81f872035avanjeff 776f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 777f737cfb953905f42f3324e8e53ec324a15314210jgong @param Type The type of bootstrap to perform. 778f737cfb953905f42f3324e8e53ec324a15314210jgong @param Layer Pointer to the boot server layer number to discover, which must be 779e285199897e538523f762cb5b3900e81f872035avanjeff PXE_BOOT_LAYER_INITIAL when a new server type is being 780e285199897e538523f762cb5b3900e81f872035avanjeff discovered. 781e285199897e538523f762cb5b3900e81f872035avanjeff @param UseBis TRUE if Boot Integrity Services are to be used. FALSE otherwise. 782f737cfb953905f42f3324e8e53ec324a15314210jgong @param Info Pointer to a data structure that contains additional information on the 783e285199897e538523f762cb5b3900e81f872035avanjeff type of discovery operation that is to be performed. 784e285199897e538523f762cb5b3900e81f872035avanjeff 785f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The Discovery sequence has been completed. 786f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 787e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 788e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 789f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete Discovery. 790f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The callback function aborted the Discovery sequence. 791f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TIMEOUT The Discovery sequence timed out. 792f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ICMP_ERROR An ICMP error packet was received during the PXE discovery 793e285199897e538523f762cb5b3900e81f872035avanjeff session. 794e285199897e538523f762cb5b3900e81f872035avanjeff 795dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 796dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 797dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 798dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcDiscover ( 799dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 800dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINT16 Type, 801dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINT16 *Layer, 802dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN UseBis, 803dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL 804dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 805dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 806dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 807dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 808dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_DISCOVER_INFO DefaultInfo; 80929a4f92d814896a7c15e5fd0559defa4d7232c53hhuan EFI_PXE_BASE_CODE_DISCOVER_INFO *CreatedInfo; 810dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_SRVLIST *SrvList; 811dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_SRVLIST DefaultSrvList; 812dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_CACHED_DHCP4_PACKET *Packet; 813f737cfb953905f42f3324e8e53ec324a15314210jgong PXEBC_VENDOR_OPTION *VendorOpt; 814dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT16 Index; 815dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 816dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_BOOT_SVR_ENTRY *BootSvrEntry; 8178730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_PXE_BASE_CODE_IP_FILTER IpFilter; 818dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 819dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 820dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 821dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 822dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 823dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 824dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 825dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BootSvrEntry = NULL; 826dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff SrvList = NULL; 82729a4f92d814896a7c15e5fd0559defa4d7232c53hhuan CreatedInfo = NULL; 828dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_DEVICE_ERROR; 829dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER; 830dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 831dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Private->AddressIsOk) { 832dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 833dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 834dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 835dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 836dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 837dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 838dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 8398730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 8408730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Stop Udp4Read instance 8418730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 8428730386e6d669ded738c6f846aa26bf1c96228bfhhuan Private->Udp4Read->Configure (Private->Udp4Read, NULL); 8438730386e6d669ded738c6f846aa26bf1c96228bfhhuan 844982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 845982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 846dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 847dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // If layer isn't EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL, 848dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // use the previous setting; 849dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // If info isn't offered, 850dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // use the cached DhcpAck and ProxyOffer packets. 851dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 852f402291bf98d9e380f00d35033570e851f5318b2sfu ZeroMem (&DefaultInfo, sizeof (EFI_PXE_BASE_CODE_DISCOVER_INFO)); 853dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (*Layer != EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL) { 854dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 855dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->PxeDiscoverValid || !Mode->PxeReplyReceived || (!Mode->PxeBisReplyReceived && UseBis)) { 856dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 8578730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = EFI_INVALID_PARAMETER; 8588730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 859dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 860dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 861dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.IpCnt = 1; 862dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.UseUCast = TRUE; 863dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 864dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultSrvList.Type = Type; 865dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultSrvList.AcceptAnyResponse = FALSE; 866dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultSrvList.IpAddr.Addr[0] = Private->ServerIp.Addr[0]; 867dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 868dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff SrvList = &DefaultSrvList; 869dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Info = &DefaultInfo; 870dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else if (Info == NULL) { 871dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 872dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Create info by the cached packet before 873dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 874dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Packet = (Mode->ProxyOfferReceived) ? &Private->ProxyOffer : &Private->Dhcp4Ack; 875dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff VendorOpt = &Packet->PxeVendorOption; 876dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 877dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->DhcpAckReceived || !IS_VALID_DISCOVER_VENDOR_OPTION (VendorOpt->BitMap)) { 878dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 879dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Address is not acquired or no discovery options. 880dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 8818730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = EFI_INVALID_PARAMETER; 8828730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 883dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 884dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 885dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.UseMCast = (BOOLEAN)!IS_DISABLE_MCAST_DISCOVER (VendorOpt->DiscoverCtrl); 886dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.UseBCast = (BOOLEAN)!IS_DISABLE_BCAST_DISCOVER (VendorOpt->DiscoverCtrl); 887dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.MustUseList = (BOOLEAN) IS_ENABLE_USE_SERVER_LIST (VendorOpt->DiscoverCtrl); 888dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.UseUCast = DefaultInfo.MustUseList; 889dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 890dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (DefaultInfo.UseMCast) { 891dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 892dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Get the multicast discover ip address from vendor option. 893dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 894f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 895e285199897e538523f762cb5b3900e81f872035avanjeff &DefaultInfo.ServerMCastIp.Addr, 896e285199897e538523f762cb5b3900e81f872035avanjeff &VendorOpt->DiscoverMcastIp, 897f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 898f737cfb953905f42f3324e8e53ec324a15314210jgong ); 899dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 900dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 901dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.IpCnt = 0; 90229a4f92d814896a7c15e5fd0559defa4d7232c53hhuan Info = &DefaultInfo; 90329a4f92d814896a7c15e5fd0559defa4d7232c53hhuan SrvList = Info->SrvList; 904dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 905dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (DefaultInfo.MustUseList) { 906dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BootSvrEntry = VendorOpt->BootSvr; 907dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_INVALID_PARAMETER; 908dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 909dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff while (((UINT8) (BootSvrEntry - VendorOpt->BootSvr)) < VendorOpt->BootSvrLen) { 910dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 911dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (BootSvrEntry->Type == HTONS (Type)) { 912dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_SUCCESS; 913dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 914dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 915dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 916dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BootSvrEntry = GET_NEXT_BOOT_SVR_ENTRY (BootSvrEntry); 917dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 918dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 919dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 9208730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 921dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 922dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 923dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DefaultInfo.IpCnt = BootSvrEntry->IpCnt; 92429a4f92d814896a7c15e5fd0559defa4d7232c53hhuan 92529a4f92d814896a7c15e5fd0559defa4d7232c53hhuan if (DefaultInfo.IpCnt >= 1) { 92629a4f92d814896a7c15e5fd0559defa4d7232c53hhuan CreatedInfo = AllocatePool (sizeof (DefaultInfo) + (DefaultInfo.IpCnt - 1) * sizeof (*SrvList)); 92729a4f92d814896a7c15e5fd0559defa4d7232c53hhuan if (CreatedInfo == NULL) { 9288730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = EFI_OUT_OF_RESOURCES; 9298730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 9308730386e6d669ded738c6f846aa26bf1c96228bfhhuan 93129a4f92d814896a7c15e5fd0559defa4d7232c53hhuan } 93229a4f92d814896a7c15e5fd0559defa4d7232c53hhuan 93329a4f92d814896a7c15e5fd0559defa4d7232c53hhuan CopyMem (CreatedInfo, &DefaultInfo, sizeof (DefaultInfo)); 93429a4f92d814896a7c15e5fd0559defa4d7232c53hhuan Info = CreatedInfo; 93529a4f92d814896a7c15e5fd0559defa4d7232c53hhuan SrvList = Info->SrvList; 93629a4f92d814896a7c15e5fd0559defa4d7232c53hhuan } 93729a4f92d814896a7c15e5fd0559defa4d7232c53hhuan 93829a4f92d814896a7c15e5fd0559defa4d7232c53hhuan for (Index = 0; Index < DefaultInfo.IpCnt; Index++) { 93929a4f92d814896a7c15e5fd0559defa4d7232c53hhuan CopyMem (&SrvList[Index].IpAddr, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); 94029a4f92d814896a7c15e5fd0559defa4d7232c53hhuan SrvList[Index].AcceptAnyResponse = FALSE; 94129a4f92d814896a7c15e5fd0559defa4d7232c53hhuan SrvList[Index].Type = BootSvrEntry->Type; 94229a4f92d814896a7c15e5fd0559defa4d7232c53hhuan } 943dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 944dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 945dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 946dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 947dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff SrvList = Info->SrvList; 948dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 949dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!SrvList[0].AcceptAnyResponse) { 950dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 951dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff for (Index = 1; Index < Info->IpCnt; Index++) { 952dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (SrvList[Index].AcceptAnyResponse) { 953dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 954dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 955dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 956dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 957dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Index != Info->IpCnt) { 9588730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = EFI_INVALID_PARAMETER; 9598730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 960dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 961dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 962dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 963dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 964dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if ((!Info->UseUCast && !Info->UseBCast && !Info->UseMCast) || (Info->MustUseList && Info->IpCnt == 0)) { 965dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 9668730386e6d669ded738c6f846aa26bf1c96228bfhhuan Status = EFI_INVALID_PARAMETER; 9678730386e6d669ded738c6f846aa26bf1c96228bfhhuan goto ON_EXIT; 968dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 969dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 970dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Execute discover by UniCast/BroadCast/MultiCast 971dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 972dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Info->UseUCast) { 973dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 974dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff for (Index = 0; Index < Info->IpCnt; Index++) { 975dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 976dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (BootSvrEntry == NULL) { 977dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->ServerIp.Addr[0] = SrvList[Index].IpAddr.Addr[0]; 978dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 979f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 980e285199897e538523f762cb5b3900e81f872035avanjeff &Private->ServerIp, 981e285199897e538523f762cb5b3900e81f872035avanjeff &BootSvrEntry->IpAddr[Index], 982f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 983f737cfb953905f42f3324e8e53ec324a15314210jgong ); 984dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 985dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 986dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcDiscvBootService ( 987dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 988dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Type, 989dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Layer, 990dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UseBis, 991dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &SrvList[Index].IpAddr, 992dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 0, 993dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL, 994dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff TRUE, 995dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->PxeReply.Packet.Ack 996dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 99729a4f92d814896a7c15e5fd0559defa4d7232c53hhuan if (!EFI_ERROR (Status)) { 99829a4f92d814896a7c15e5fd0559defa4d7232c53hhuan break; 99929a4f92d814896a7c15e5fd0559defa4d7232c53hhuan } 1000dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1001dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1002dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else if (Info->UseMCast) { 1003dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1004dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcDiscvBootService ( 1005dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1006dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Type, 1007dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Layer, 1008dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UseBis, 1009dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Info->ServerMCastIp, 1010dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 0, 1011dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL, 1012dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff TRUE, 1013dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->PxeReply.Packet.Ack 1014dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1015dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1016dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else if (Info->UseBCast) { 1017dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1018dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcDiscvBootService ( 1019dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1020dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Type, 1021dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Layer, 1022dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UseBis, 1023dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL, 1024dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Info->IpCnt, 1025dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff SrvList, 1026dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff TRUE, 1027dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->PxeReply.Packet.Ack 1028dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1029dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1030dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1031dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status) || !Mode->PxeReplyReceived || (!Mode->PxeBisReplyReceived && UseBis)) { 1032982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Status == EFI_ICMP_ERROR) { 1033982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = TRUE; 1034982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } else { 1035982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = EFI_DEVICE_ERROR; 1036982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1037357af28525c3a5be6ca0a201f2533dc0a372dbfbsfu goto ON_EXIT; 1038dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1039dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBcParseCachedDhcpPacket (&Private->PxeReply); 1040dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1041dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1042dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Mode->PxeBisReplyReceived) { 1043f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1044e285199897e538523f762cb5b3900e81f872035avanjeff &Private->ServerIp, 1045e285199897e538523f762cb5b3900e81f872035avanjeff &Mode->PxeReply.Dhcpv4.BootpSiAddr, 1046f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 1047f737cfb953905f42f3324e8e53ec324a15314210jgong ); 1048dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1049dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 105029a4f92d814896a7c15e5fd0559defa4d7232c53hhuan if (CreatedInfo != NULL) { 105129a4f92d814896a7c15e5fd0559defa4d7232c53hhuan FreePool (CreatedInfo); 105229a4f92d814896a7c15e5fd0559defa4d7232c53hhuan } 10538730386e6d669ded738c6f846aa26bf1c96228bfhhuan 10548730386e6d669ded738c6f846aa26bf1c96228bfhhuanON_EXIT: 10558730386e6d669ded738c6f846aa26bf1c96228bfhhuan 1056357af28525c3a5be6ca0a201f2533dc0a372dbfbsfu Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); 1057c82291bc3108c948a66d659da0fd76731351f530hhuan 10588730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 10598730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP 10608730386e6d669ded738c6f846aa26bf1c96228bfhhuan // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. 10618730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 10628730386e6d669ded738c6f846aa26bf1c96228bfhhuan ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER)); 10638730386e6d669ded738c6f846aa26bf1c96228bfhhuan IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP; 10648730386e6d669ded738c6f846aa26bf1c96228bfhhuan This->SetIpFilter (This, &IpFilter); 106529a4f92d814896a7c15e5fd0559defa4d7232c53hhuan 1066dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 1067dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 1068dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1069dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1070e285199897e538523f762cb5b3900e81f872035avanjeff/** 1071f737cfb953905f42f3324e8e53ec324a15314210jgong Used to perform TFTP and MTFTP services. 1072f737cfb953905f42f3324e8e53ec324a15314210jgong 1073f737cfb953905f42f3324e8e53ec324a15314210jgong This function is used to perform TFTP and MTFTP services. This includes the 1074f737cfb953905f42f3324e8e53ec324a15314210jgong TFTP operations to get the size of a file, read a directory, read a file, and 1075f737cfb953905f42f3324e8e53ec324a15314210jgong write a file. It also includes the MTFTP operations to get the size of a file, 1076f737cfb953905f42f3324e8e53ec324a15314210jgong read a directory, and read a file. The type of operation is specified by Operation. 1077f737cfb953905f42f3324e8e53ec324a15314210jgong If the callback function that is invoked during the TFTP/MTFTP operation does 1078f737cfb953905f42f3324e8e53ec324a15314210jgong not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will 1079f737cfb953905f42f3324e8e53ec324a15314210jgong be returned. 1080f737cfb953905f42f3324e8e53ec324a15314210jgong For read operations, the return data will be placed in the buffer specified by 1081f737cfb953905f42f3324e8e53ec324a15314210jgong BufferPtr. If BufferSize is too small to contain the entire downloaded file, 1082f737cfb953905f42f3324e8e53ec324a15314210jgong then EFI_BUFFER_TOO_SMALL will be returned and BufferSize will be set to zero 1083f737cfb953905f42f3324e8e53ec324a15314210jgong or the size of the requested file (the size of the requested file is only returned 1084f737cfb953905f42f3324e8e53ec324a15314210jgong if the TFTP server supports TFTP options). If BufferSize is large enough for the 1085f737cfb953905f42f3324e8e53ec324a15314210jgong read operation, then BufferSize will be set to the size of the downloaded file, 1086f737cfb953905f42f3324e8e53ec324a15314210jgong and EFI_SUCCESS will be returned. Applications using the PxeBc.Mtftp() services 1087f737cfb953905f42f3324e8e53ec324a15314210jgong should use the get-file-size operations to determine the size of the downloaded 1088f737cfb953905f42f3324e8e53ec324a15314210jgong file prior to using the read-file operations-especially when downloading large 1089f737cfb953905f42f3324e8e53ec324a15314210jgong (greater than 64 MB) files-instead of making two calls to the read-file operation. 1090f737cfb953905f42f3324e8e53ec324a15314210jgong Following this recommendation will save time if the file is larger than expected 1091f737cfb953905f42f3324e8e53ec324a15314210jgong and the TFTP server does not support TFTP option extensions. Without TFTP option 1092f737cfb953905f42f3324e8e53ec324a15314210jgong extension support, the client has to download the entire file, counting and discarding 1093f737cfb953905f42f3324e8e53ec324a15314210jgong the received packets, to determine the file size. 1094f737cfb953905f42f3324e8e53ec324a15314210jgong For write operations, the data to be sent is in the buffer specified by BufferPtr. 1095f737cfb953905f42f3324e8e53ec324a15314210jgong BufferSize specifies the number of bytes to send. If the write operation completes 1096f737cfb953905f42f3324e8e53ec324a15314210jgong successfully, then EFI_SUCCESS will be returned. 1097f737cfb953905f42f3324e8e53ec324a15314210jgong For TFTP "get file size" operations, the size of the requested file or directory 1098f737cfb953905f42f3324e8e53ec324a15314210jgong is returned in BufferSize, and EFI_SUCCESS will be returned. If the TFTP server 1099f737cfb953905f42f3324e8e53ec324a15314210jgong does not support options, the file will be downloaded into a bit bucket and the 1100f737cfb953905f42f3324e8e53ec324a15314210jgong length of the downloaded file will be returned. For MTFTP "get file size" operations, 1101f737cfb953905f42f3324e8e53ec324a15314210jgong if the MTFTP server does not support the "get file size" option, EFI_UNSUPPORTED 1102f737cfb953905f42f3324e8e53ec324a15314210jgong will be returned. 1103f737cfb953905f42f3324e8e53ec324a15314210jgong This function can take up to 10 seconds to timeout and return control to the caller. 1104f737cfb953905f42f3324e8e53ec324a15314210jgong If the TFTP sequence does not complete, EFI_TIMEOUT will be returned. 1105f737cfb953905f42f3324e8e53ec324a15314210jgong If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, 1106f737cfb953905f42f3324e8e53ec324a15314210jgong then the TFTP sequence is stopped and EFI_ABORTED will be returned. 1107f737cfb953905f42f3324e8e53ec324a15314210jgong The format of the data returned from a TFTP read directory operation is a null-terminated 1108f737cfb953905f42f3324e8e53ec324a15314210jgong filename followed by a null-terminated information string, of the form 1109f737cfb953905f42f3324e8e53ec324a15314210jgong "size year-month-day hour:minute:second" (i.e. %d %d-%d-%d %d:%d:%f - note that 1110f737cfb953905f42f3324e8e53ec324a15314210jgong the seconds field can be a decimal number), where the date and time are UTC. For 1111f737cfb953905f42f3324e8e53ec324a15314210jgong an MTFTP read directory command, there is additionally a null-terminated multicast 1112f737cfb953905f42f3324e8e53ec324a15314210jgong IP address preceding the filename of the form %d.%d.%d.%d for IP v4. The final 1113f737cfb953905f42f3324e8e53ec324a15314210jgong entry is itself null-terminated, so that the final information string is terminated 1114f737cfb953905f42f3324e8e53ec324a15314210jgong with two null octets. 1115e285199897e538523f762cb5b3900e81f872035avanjeff 1116f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 1117f737cfb953905f42f3324e8e53ec324a15314210jgong @param Operation The type of operation to perform. 1118e285199897e538523f762cb5b3900e81f872035avanjeff @param BufferPtr A pointer to the data buffer. 1119f737cfb953905f42f3324e8e53ec324a15314210jgong @param Overwrite Only used on write file operations. TRUE if a file on a remote server can 1120e285199897e538523f762cb5b3900e81f872035avanjeff be overwritten. 1121f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferSize For get-file-size operations, *BufferSize returns the size of the 1122e285199897e538523f762cb5b3900e81f872035avanjeff requested file. 1123f737cfb953905f42f3324e8e53ec324a15314210jgong @param BlockSize The requested block size to be used during a TFTP transfer. 1124f737cfb953905f42f3324e8e53ec324a15314210jgong @param ServerIp The TFTP / MTFTP server IP address. 1125f737cfb953905f42f3324e8e53ec324a15314210jgong @param Filename A Null-terminated ASCII string that specifies a directory name or a file 1126e285199897e538523f762cb5b3900e81f872035avanjeff name. 1127f737cfb953905f42f3324e8e53ec324a15314210jgong @param Info Pointer to the MTFTP information. 1128e285199897e538523f762cb5b3900e81f872035avanjeff @param DontUseBuffer Set to FALSE for normal TFTP and MTFTP read file operation. 1129e285199897e538523f762cb5b3900e81f872035avanjeff 1130f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The TFTP/MTFTP operation was completed. 1131f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 1132e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 1133e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 1134e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_BUFFER_TOO_SMALL The buffer is not large enough to complete the read operation. 1135f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The callback function aborted the TFTP/MTFTP operation. 1136f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TIMEOUT The TFTP/MTFTP operation timed out. 1137f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ICMP_ERROR An ICMP error packet was received during the MTFTP session. 1138f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TFTP_ERROR A TFTP error packet was received during the MTFTP session. 1139e285199897e538523f762cb5b3900e81f872035avanjeff 1140dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 1141dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 1142dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 1143dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcMtftp ( 1144dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 1145dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, 1146dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN OUT VOID *BufferPtr, 1147dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN Overwrite, 1148dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN OUT UINT64 *BufferSize, 1149dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINTN *BlockSize OPTIONAL, 1150dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS *ServerIp, 1151dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINT8 *Filename, 1152dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, 1153dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN DontUseBuffer 1154dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 1155dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 11568730386e6d669ded738c6f846aa26bf1c96228bfhhuan PXEBC_PRIVATE_DATA *Private; 11578730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_MTFTP4_CONFIG_DATA Mtftp4Config; 11588730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_STATUS Status; 11598730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_PXE_BASE_CODE_MODE *Mode; 11608730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_MAC_ADDRESS TempMacAddr; 11618730386e6d669ded738c6f846aa26bf1c96228bfhhuan EFI_PXE_BASE_CODE_IP_FILTER IpFilter; 1162dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1163f6b7393ceb34c9b3a27434268bf2ce517047641ftye if ((This == NULL) || 1164f6b7393ceb34c9b3a27434268bf2ce517047641ftye (Filename == NULL) || 1165f6b7393ceb34c9b3a27434268bf2ce517047641ftye (BufferSize == NULL) || 1166f6b7393ceb34c9b3a27434268bf2ce517047641ftye ((ServerIp == NULL) || !NetIp4IsUnicast (NTOHL (ServerIp->Addr[0]), 0)) || 1167f6b7393ceb34c9b3a27434268bf2ce517047641ftye ((BufferPtr == NULL) && DontUseBuffer) || 1168dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ((BlockSize != NULL) && (*BlockSize < 512))) { 1169dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1170dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1171dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1172dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1173dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_DEVICE_ERROR; 1174dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 1175982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode = &Private->Mode; 1176982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 1177982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!Mode->AutoArp) { 1178982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 1179982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // If AutoArp is set false, check arp cache 1180982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 1181982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UpdateArpCache (This); 1182982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!FindInArpCache (Mode, &ServerIp->v4, &TempMacAddr)) { 1183982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return EFI_DEVICE_ERROR; 1184982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1185982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1186982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 11878730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 11888730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Stop Udp4Read instance 11898730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 11908730386e6d669ded738c6f846aa26bf1c96228bfhhuan Private->Udp4Read->Configure (Private->Udp4Read, NULL); 11918730386e6d669ded738c6f846aa26bf1c96228bfhhuan 1192982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->TftpErrorReceived = FALSE; 1193982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 1194dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1195dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mtftp4Config.UseDefaultSetting = FALSE; 1196dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mtftp4Config.TimeoutValue = PXEBC_MTFTP_TIMEOUT; 1197dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mtftp4Config.TryCount = PXEBC_MTFTP_RETRIES; 1198dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1199f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1200e285199897e538523f762cb5b3900e81f872035avanjeff &Mtftp4Config.StationIp, 1201e285199897e538523f762cb5b3900e81f872035avanjeff &Private->StationIp, 1202f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 1203f737cfb953905f42f3324e8e53ec324a15314210jgong ); 1204f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1205e285199897e538523f762cb5b3900e81f872035avanjeff &Mtftp4Config.SubnetMask, 1206e285199897e538523f762cb5b3900e81f872035avanjeff &Private->SubnetMask, 1207f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 1208f737cfb953905f42f3324e8e53ec324a15314210jgong ); 1209f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1210e285199897e538523f762cb5b3900e81f872035avanjeff &Mtftp4Config.GatewayIp, 1211e285199897e538523f762cb5b3900e81f872035avanjeff &Private->GatewayIp, 1212f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 1213f737cfb953905f42f3324e8e53ec324a15314210jgong ); 1214f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1215e285199897e538523f762cb5b3900e81f872035avanjeff &Mtftp4Config.ServerIp, 1216e285199897e538523f762cb5b3900e81f872035avanjeff ServerIp, 1217f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (EFI_IPv4_ADDRESS) 1218f737cfb953905f42f3324e8e53ec324a15314210jgong ); 1219dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1220dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff switch (Operation) { 1221dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1222dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE: 1223dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1224dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcTftpGetFileSize ( 1225dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1226dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Mtftp4Config, 1227dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Filename, 1228dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BlockSize, 1229dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferSize 1230dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1231dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1232dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1233dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1234dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_TFTP_READ_FILE: 1235dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1236dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcTftpReadFile ( 1237dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1238dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Mtftp4Config, 1239dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Filename, 1240dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BlockSize, 1241dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferPtr, 1242dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferSize, 1243dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DontUseBuffer 1244dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1245dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1246dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1247dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1248dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_TFTP_WRITE_FILE: 1249dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1250dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcTftpWriteFile ( 1251dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1252dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Mtftp4Config, 1253dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Filename, 1254dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Overwrite, 1255dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BlockSize, 1256dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferPtr, 1257dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferSize 1258dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1259dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1260dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1261dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1262dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY: 1263dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1264dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcTftpReadDirectory ( 1265dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private, 1266dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Mtftp4Config, 1267dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Filename, 1268dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BlockSize, 1269dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferPtr, 1270dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferSize, 1271dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DontUseBuffer 1272dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1273dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1274dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1275dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1276dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE: 1277dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_MTFTP_READ_FILE: 1278dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY: 1279dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_UNSUPPORTED; 1280dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1281dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1282dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff default: 1283dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1284dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_INVALID_PARAMETER; 1285dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 1286dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1287dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1288982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Status == EFI_ICMP_ERROR) { 1289982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = TRUE; 1290982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1291982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 12920bc17488fe1e70a9fce92503739bc60e7471ad29sfu if (EFI_ERROR (Status)) { 1293357af28525c3a5be6ca0a201f2533dc0a372dbfbsfu goto ON_EXIT; 12940bc17488fe1e70a9fce92503739bc60e7471ad29sfu } 12950bc17488fe1e70a9fce92503739bc60e7471ad29sfu 1296357af28525c3a5be6ca0a201f2533dc0a372dbfbsfuON_EXIT: 1297357af28525c3a5be6ca0a201f2533dc0a372dbfbsfu Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); 12988730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 12998730386e6d669ded738c6f846aa26bf1c96228bfhhuan // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP 13008730386e6d669ded738c6f846aa26bf1c96228bfhhuan // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. 13018730386e6d669ded738c6f846aa26bf1c96228bfhhuan // 13028730386e6d669ded738c6f846aa26bf1c96228bfhhuan ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER)); 13038730386e6d669ded738c6f846aa26bf1c96228bfhhuan IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP; 13048730386e6d669ded738c6f846aa26bf1c96228bfhhuan This->SetIpFilter (This, &IpFilter); 13058730386e6d669ded738c6f846aa26bf1c96228bfhhuan 1306dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 1307dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 1308dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1309dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1310e285199897e538523f762cb5b3900e81f872035avanjeff/** 1311f737cfb953905f42f3324e8e53ec324a15314210jgong Writes a UDP packet to the network interface. 1312f737cfb953905f42f3324e8e53ec324a15314210jgong 1313f737cfb953905f42f3324e8e53ec324a15314210jgong This function writes a UDP packet specified by the (optional HeaderPtr and) 1314f737cfb953905f42f3324e8e53ec324a15314210jgong BufferPtr parameters to the network interface. The UDP header is automatically 1315f737cfb953905f42f3324e8e53ec324a15314210jgong built by this routine. It uses the parameters OpFlags, DestIp, DestPort, GatewayIp, 1316f737cfb953905f42f3324e8e53ec324a15314210jgong SrcIp, and SrcPort to build this header. If the packet is successfully built and 1317f737cfb953905f42f3324e8e53ec324a15314210jgong transmitted through the network interface, then EFI_SUCCESS will be returned. 1318f737cfb953905f42f3324e8e53ec324a15314210jgong If a timeout occurs during the transmission of the packet, then EFI_TIMEOUT will 1319f737cfb953905f42f3324e8e53ec324a15314210jgong be returned. If an ICMP error occurs during the transmission of the packet, then 1320f737cfb953905f42f3324e8e53ec324a15314210jgong the IcmpErrorReceived field is set to TRUE, the IcmpError field is filled in and 1321f737cfb953905f42f3324e8e53ec324a15314210jgong EFI_ICMP_ERROR will be returned. If the Callback Protocol does not return 1322f737cfb953905f42f3324e8e53ec324a15314210jgong EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will be returned. 1323e285199897e538523f762cb5b3900e81f872035avanjeff 1324f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 1325e285199897e538523f762cb5b3900e81f872035avanjeff @param OpFlags The UDP operation flags. 1326f737cfb953905f42f3324e8e53ec324a15314210jgong @param DestIp The destination IP address. 1327e285199897e538523f762cb5b3900e81f872035avanjeff @param DestPort The destination UDP port number. 1328e285199897e538523f762cb5b3900e81f872035avanjeff @param GatewayIp The gateway IP address. 1329f737cfb953905f42f3324e8e53ec324a15314210jgong @param SrcIp The source IP address. 1330f737cfb953905f42f3324e8e53ec324a15314210jgong @param SrcPort The source UDP port number. 1331f737cfb953905f42f3324e8e53ec324a15314210jgong @param HeaderSize An optional field which may be set to the length of a header at 1332e285199897e538523f762cb5b3900e81f872035avanjeff HeaderPtr to be prefixed to the data at BufferPtr. 1333f737cfb953905f42f3324e8e53ec324a15314210jgong @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the 1334e285199897e538523f762cb5b3900e81f872035avanjeff data at BufferPtr. 1335f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferSize A pointer to the size of the data at BufferPtr. 1336f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferPtr A pointer to the data to be written. 1337e285199897e538523f762cb5b3900e81f872035avanjeff 1338f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The UDP Write operation was completed. 1339f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 1340e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 1341e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_BAD_BUFFER_SIZE The buffer is too long to be transmitted. 1342f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The callback function aborted the UDP Write operation. 1343f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TIMEOUT The UDP Write operation timed out. 1344e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_ICMP_ERROR An ICMP error packet was received during the UDP write session. 1345e285199897e538523f762cb5b3900e81f872035avanjeff 1346dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 1347dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 1348dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 1349dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcUdpWrite ( 1350dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 1351dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINT16 OpFlags, 1352dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS *DestIp, 1353dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, 1354dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, 1355dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS *SrcIp OPTIONAL, 1356dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, 1357dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINTN *HeaderSize OPTIONAL, 1358dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN VOID *HeaderPtr OPTIONAL, 1359dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINTN *BufferSize, 1360dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN VOID *BufferPtr 1361dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 1362dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 1363dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 1364dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_PROTOCOL *Udp4; 1365dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_COMPLETION_TOKEN Token; 1366dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_TRANSMIT_DATA *Udp4TxData; 1367dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT32 FragCount; 1368dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT32 DataLength; 1369dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_SESSION_DATA Udp4Session; 1370dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 1371dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BOOLEAN IsDone; 1372982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_PXE_BASE_CODE_MODE *Mode; 1373982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_MAC_ADDRESS TempMacAddr; 1374dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1375dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IsDone = FALSE; 1376dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1377dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if ((This == NULL) || (DestIp == NULL) || (DestPort == NULL)) { 1378dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1379dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1380dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1381f6b7393ceb34c9b3a27434268bf2ce517047641ftye if ((GatewayIp != NULL) && !NetIp4IsUnicast (NTOHL (GatewayIp->Addr[0]), 0)) { 1382dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1383dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Gateway is provided but it's not a unicast IP address. 1384dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1385dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1386dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1387dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1388dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if ((HeaderSize != NULL) && ((*HeaderSize == 0) || (HeaderPtr == NULL))) { 1389dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1390dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // The HeaderSize ptr isn't NULL and: 1. the value is zero; or 2. the HeaderPtr 1391dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // is NULL. 1392dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1393dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1394dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1395dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1396dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if ((BufferSize == NULL) || ((*BufferSize != 0) && (BufferPtr == NULL))) { 1397dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1398dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1399dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1400dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 14018792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Udp4 = Private->Udp4Write; 1402982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode = &Private->Mode; 14038792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (!Mode->Started) { 14048792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff return EFI_NOT_STARTED; 14058792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff } 1406dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1407dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Private->AddressIsOk && (SrcIp == NULL)) { 1408dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1409dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1410dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1411982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!Mode->AutoArp) { 1412982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 1413982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // If AutoArp is set false, check arp cache 1414982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 1415982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UpdateArpCache (This); 1416982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!FindInArpCache (Mode, &DestIp->v4, &TempMacAddr)) { 1417982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return EFI_DEVICE_ERROR; 1418982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1419982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1420982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 1421982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 1422982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 14238792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if ((Private->CurrentUdpSrcPort == 0) || 1424f737cfb953905f42f3324e8e53ec324a15314210jgong ((SrcPort != NULL) && (*SrcPort != Private->CurrentUdpSrcPort))) { 14258792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff // 14268792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff // Port is changed, (re)configure the Udp4Write instance 14278792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff // 14288792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (SrcPort != NULL) { 14298792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Private->CurrentUdpSrcPort = *SrcPort; 1430dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1431dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1432dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 14332e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan Status = PxeBcConfigureUdpWriteInstance ( 14342e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan Udp4, 14352e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan &Private->StationIp.v4, 14362e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan &Private->SubnetMask.v4, 14372e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan &Private->GatewayIp.v4, 14382e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan &Private->CurrentUdpSrcPort 14392e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan ); 14402e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan if (EFI_ERROR (Status)) { 14412e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan Private->CurrentUdpSrcPort = 0; 14422e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan return EFI_INVALID_PARAMETER; 14432e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan } 14442e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan 1445dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ZeroMem (&Token, sizeof (EFI_UDP4_COMPLETION_TOKEN)); 1446dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ZeroMem (&Udp4Session, sizeof (EFI_UDP4_SESSION_DATA)); 1447dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1448e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Udp4Session.DestinationAddress, DestIp, sizeof (EFI_IPv4_ADDRESS)); 1449dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4Session.DestinationPort = *DestPort; 14508792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (SrcIp != NULL) { 14518792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff CopyMem (&Udp4Session.SourceAddress, SrcIp, sizeof (EFI_IPv4_ADDRESS)); 14528792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff } 14538792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (SrcPort != NULL) { 14548792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Udp4Session.SourcePort = *SrcPort; 14558792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff } 1456dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1457dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff FragCount = (HeaderSize != NULL) ? 2 : 1; 145805c0e3cb8ad921c94ef51fc972e117baa32ce82fvanjeff Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) AllocateZeroPool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA)); 1459dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Udp4TxData == NULL) { 1460dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_OUT_OF_RESOURCES; 1461dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1462dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1463dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->FragmentCount = FragCount; 1464dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32) *BufferSize; 1465dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr; 1466dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DataLength = (UINT32) *BufferSize; 1467dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1468dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (FragCount == 2) { 1469dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1470dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->FragmentTable[0].FragmentLength = (UINT32) *HeaderSize; 1471dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->FragmentTable[0].FragmentBuffer = HeaderPtr; 1472dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff DataLength += (UINT32) *HeaderSize; 1473dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1474dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 14758792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (GatewayIp != NULL) { 14768792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Udp4TxData->GatewayAddress = (EFI_IPv4_ADDRESS *) GatewayIp; 14778792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff } 1478dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->UdpSessionData = &Udp4Session; 1479dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4TxData->DataLength = DataLength; 1480dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Token.Packet.TxData = Udp4TxData; 1481dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1482dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->CreateEvent ( 1483dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EVT_NOTIFY_SIGNAL, 1484e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1485dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBcCommonNotify, 1486dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &IsDone, 1487dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Token.Event 1488dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1489dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 1490dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 1491dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1492dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1493dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = Udp4->Transmit (Udp4, &Token); 1494dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 1495982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Status == EFI_ICMP_ERROR) { 1496982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = TRUE; 1497982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1498dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 1499dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1500dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1501dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff while (!IsDone) { 1502dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1503dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4->Poll (Udp4); 1504dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1505dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1506dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = Token.Status; 1507dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1508dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffON_EXIT: 1509dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1510dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Token.Event != NULL) { 1511dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff gBS->CloseEvent (Token.Event); 1512dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1513dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1514766c7483c335931b190a78d78d62e5a5e69dc8b9xdu FreePool (Udp4TxData); 1515dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 15162e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan // 15172e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan // Reset the instance. 15182e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan // 15192e4c2a049be0cfebb2caa79884f22e80ee96eca7hhuan Udp4->Configure (Udp4, NULL); 1520dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 1521dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 1522dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 15238d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff/** 1524f737cfb953905f42f3324e8e53ec324a15314210jgong Decide whether the incoming UDP packet is acceptable per IP filter settings 1525f737cfb953905f42f3324e8e53ec324a15314210jgong in provided PxeBcMode. 15268d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1527f737cfb953905f42f3324e8e53ec324a15314210jgong @param PxeBcMode Pointer to EFI_PXE_BASE_CODE_MODE. 1528f737cfb953905f42f3324e8e53ec324a15314210jgong @param Session Received UDP session. 15298d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1530f737cfb953905f42f3324e8e53ec324a15314210jgong @retval TRUE The UDP package matches IP filters. 1531f737cfb953905f42f3324e8e53ec324a15314210jgong @retval FALSE The UDP package doesn't matches IP filters. 15328d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 15338d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff**/ 15348d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeffBOOLEAN 15358d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeffCheckIpByFilter ( 1536f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_MODE *PxeBcMode, 1537f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_UDP4_SESSION_DATA *Session 15388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) 15398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff{ 15408d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff UINTN Index; 15418d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_IPv4_ADDRESS Ip4Address; 15428d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_IPv4_ADDRESS DestIp4Address; 15438d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1544f737cfb953905f42f3324e8e53ec324a15314210jgong if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0) { 15458d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return TRUE; 15468d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15478d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 15488d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff CopyMem (&DestIp4Address, &Session->DestinationAddress, sizeof (DestIp4Address)); 1549e285199897e538523f762cb5b3900e81f872035avanjeff if (((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0) && 1550982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff IP4_IS_MULTICAST (EFI_NTOHL (DestIp4Address)) 15518d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) { 15528d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return TRUE; 15538d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15548d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1555e285199897e538523f762cb5b3900e81f872035avanjeff if (((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) && 15568d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff IP4_IS_LOCAL_BROADCAST (EFI_NTOHL (DestIp4Address)) 15578d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) { 15588d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return TRUE; 15598d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15608d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 15618d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff CopyMem (&Ip4Address, &PxeBcMode->StationIp.v4, sizeof (Ip4Address)); 1562e285199897e538523f762cb5b3900e81f872035avanjeff if (((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) && 1563982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff EFI_IP4_EQUAL (&Ip4Address, &DestIp4Address) 15648d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) { 15658d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return TRUE; 15668d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15678d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1568894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff ASSERT (PxeBcMode->IpFilter.IpCnt < EFI_PXE_BASE_CODE_MAX_IPCNT); 1569894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff 1570f737cfb953905f42f3324e8e53ec324a15314210jgong for (Index = 0; Index < PxeBcMode->IpFilter.IpCnt; Index++) { 1571f737cfb953905f42f3324e8e53ec324a15314210jgong CopyMem ( 1572e285199897e538523f762cb5b3900e81f872035avanjeff &Ip4Address, 1573e285199897e538523f762cb5b3900e81f872035avanjeff &PxeBcMode->IpFilter.IpList[Index].v4, 1574f737cfb953905f42f3324e8e53ec324a15314210jgong sizeof (Ip4Address) 1575f737cfb953905f42f3324e8e53ec324a15314210jgong ); 15768d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (EFI_IP4_EQUAL (&Ip4Address, &DestIp4Address)) { 15778d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return TRUE; 15788d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15798d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 15808d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 15818d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return FALSE; 15828d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff} 1583dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1584e285199897e538523f762cb5b3900e81f872035avanjeff/** 1585f737cfb953905f42f3324e8e53ec324a15314210jgong Reads a UDP packet from the network interface. 1586f737cfb953905f42f3324e8e53ec324a15314210jgong 1587f737cfb953905f42f3324e8e53ec324a15314210jgong This function reads a UDP packet from a network interface. The data contents 1588f737cfb953905f42f3324e8e53ec324a15314210jgong are returned in (the optional HeaderPtr and) BufferPtr, and the size of the 1589f737cfb953905f42f3324e8e53ec324a15314210jgong buffer received is returned in BufferSize . If the input BufferSize is smaller 1590f737cfb953905f42f3324e8e53ec324a15314210jgong than the UDP packet received (less optional HeaderSize), it will be set to the 1591f737cfb953905f42f3324e8e53ec324a15314210jgong required size, and EFI_BUFFER_TOO_SMALL will be returned. In this case, the 1592f737cfb953905f42f3324e8e53ec324a15314210jgong contents of BufferPtr are undefined, and the packet is lost. If a UDP packet is 1593f737cfb953905f42f3324e8e53ec324a15314210jgong successfully received, then EFI_SUCCESS will be returned, and the information 1594f737cfb953905f42f3324e8e53ec324a15314210jgong from the UDP header will be returned in DestIp, DestPort, SrcIp, and SrcPort if 1595e285199897e538523f762cb5b3900e81f872035avanjeff they are not NULL. Depending on the values of OpFlags and the DestIp, DestPort, 1596e285199897e538523f762cb5b3900e81f872035avanjeff SrcIp, and SrcPort input values, different types of UDP packet receive filtering 1597f737cfb953905f42f3324e8e53ec324a15314210jgong will be performed. The following tables summarize these receive filter operations. 1598e285199897e538523f762cb5b3900e81f872035avanjeff 1599f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 1600e285199897e538523f762cb5b3900e81f872035avanjeff @param OpFlags The UDP operation flags. 1601f737cfb953905f42f3324e8e53ec324a15314210jgong @param DestIp The destination IP address. 1602f737cfb953905f42f3324e8e53ec324a15314210jgong @param DestPort The destination UDP port number. 1603f737cfb953905f42f3324e8e53ec324a15314210jgong @param SrcIp The source IP address. 1604f737cfb953905f42f3324e8e53ec324a15314210jgong @param SrcPort The source UDP port number. 1605f737cfb953905f42f3324e8e53ec324a15314210jgong @param HeaderSize An optional field which may be set to the length of a header at 1606e285199897e538523f762cb5b3900e81f872035avanjeff HeaderPtr to be prefixed to the data at BufferPtr. 1607f737cfb953905f42f3324e8e53ec324a15314210jgong @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the 1608e285199897e538523f762cb5b3900e81f872035avanjeff data at BufferPtr. 1609f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferSize A pointer to the size of the data at BufferPtr. 1610f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferPtr A pointer to the data to be read. 1611e285199897e538523f762cb5b3900e81f872035avanjeff 1612f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The UDP Read operation was completed. 1613f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 1614e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 1615f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 1616f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_BUFFER_TOO_SMALL The packet is larger than Buffer can hold. 1617f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The callback function aborted the UDP Read operation. 1618e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_TIMEOUT The UDP Read operation timed out. 1619e285199897e538523f762cb5b3900e81f872035avanjeff 1620dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 1621dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 1622dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 1623dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcUdpRead ( 1624f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PROTOCOL *This, 1625f737cfb953905f42f3324e8e53ec324a15314210jgong IN UINT16 OpFlags, 1626f737cfb953905f42f3324e8e53ec324a15314210jgong IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, 1627f737cfb953905f42f3324e8e53ec324a15314210jgong IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, 1628f737cfb953905f42f3324e8e53ec324a15314210jgong IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, 1629f737cfb953905f42f3324e8e53ec324a15314210jgong IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, 1630f737cfb953905f42f3324e8e53ec324a15314210jgong IN UINTN *HeaderSize OPTIONAL, 1631f737cfb953905f42f3324e8e53ec324a15314210jgong IN VOID *HeaderPtr OPTIONAL, 1632f737cfb953905f42f3324e8e53ec324a15314210jgong IN OUT UINTN *BufferSize, 1633f737cfb953905f42f3324e8e53ec324a15314210jgong IN VOID *BufferPtr 1634dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 1635dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 1636dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 1637dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 1638dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_PROTOCOL *Udp4; 1639dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_COMPLETION_TOKEN Token; 1640dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_RECEIVE_DATA *RxData; 1641dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_UDP4_SESSION_DATA *Session; 1642dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 1643dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BOOLEAN IsDone; 1644dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BOOLEAN Matched; 1645c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINTN CopiedLen; 1646c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINTN HeaderLen; 1647c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINTN HeaderCopiedLen; 1648c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINTN BufferCopiedLen; 1649c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINT32 FragmentLength; 1650c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINTN FragmentIndex; 1651c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu UINT8 *FragmentBuffer; 1652dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1653dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL || DestIp == NULL || DestPort == NULL) { 1654dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1655dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1656dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1657f737cfb953905f42f3324e8e53ec324a15314210jgong if (((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) == 0 && (DestPort == NULL)) || 1658f737cfb953905f42f3324e8e53ec324a15314210jgong ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) == 0 && (SrcIp == NULL)) || 1659f737cfb953905f42f3324e8e53ec324a15314210jgong ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) == 0 && (SrcPort == NULL))) { 1660dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1661dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1662dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 16638792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (((HeaderSize != NULL) && (*HeaderSize == 0)) || ((HeaderSize != NULL) && (HeaderPtr == NULL))) { 1664dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1665dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1666dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 166729a4f92d814896a7c15e5fd0559defa4d7232c53hhuan if ((BufferSize == NULL) || (BufferPtr == NULL)) { 1668dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 1669dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1670dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1671dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 1672dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 16738792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Udp4 = Private->Udp4Read; 1674dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1675dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 1676dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 1677dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1678dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1679982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 1680982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 1681dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->CreateEvent ( 1682dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EVT_NOTIFY_SIGNAL, 1683e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff TPL_NOTIFY, 1684dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBcCommonNotify, 1685dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &IsDone, 1686dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Token.Event 1687dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 1688dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 1689dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_OUT_OF_RESOURCES; 1690dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1691dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 16928792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeffTRY_AGAIN: 16938792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff 1694dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IsDone = FALSE; 1695dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = Udp4->Receive (Udp4, &Token); 1696dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 1697982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Status == EFI_ICMP_ERROR) { 1698982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = TRUE; 1699982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 1700dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 1701dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1702dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1703dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4->Poll (Udp4); 1704dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1705dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!IsDone) { 1706dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_TIMEOUT; 1707dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1708dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1709dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1710dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // check whether this packet matches the filters 1711dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1712dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Token.Status)){ 1713dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 1714dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1715dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1716dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff RxData = Token.Packet.RxData; 1717dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Session = &RxData->UdpSession; 1718dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1719319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff Matched = TRUE; 1720dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1721f737cfb953905f42f3324e8e53ec324a15314210jgong if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) != 0) { 1722319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff Matched = FALSE; 17238d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 17248d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // Check UDP package by IP filter settings 17258d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 17268d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (CheckIpByFilter (Mode, Session)) { 17278d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Matched = TRUE; 1728dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 17298d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 17308d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 17318d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (Matched) { 17328792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Matched = FALSE; 17338792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff 17348d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 17358d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // Match the destination ip of the received udp dgram 17368d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 1737f737cfb953905f42f3324e8e53ec324a15314210jgong if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) != 0) { 17388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Matched = TRUE; 17398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 17408d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (DestIp != NULL) { 17418d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff CopyMem (DestIp, &Session->DestinationAddress, sizeof (EFI_IPv4_ADDRESS)); 1742dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1743dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 17448d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (DestIp != NULL) { 17458d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (EFI_IP4_EQUAL (DestIp, &Session->DestinationAddress)) { 17468d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Matched = TRUE; 17478d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 17488d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } else { 17498d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (EFI_IP4_EQUAL (&Private->StationIp, &Session->DestinationAddress)) { 17508d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Matched = TRUE; 17518d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 1752dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1753dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1754dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1755dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1756dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Matched) { 1757dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1758dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Match the destination port of the received udp dgram 1759dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1760f737cfb953905f42f3324e8e53ec324a15314210jgong if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) != 0) { 1761dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1762dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (DestPort != NULL) { 1763dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *DestPort = Session->DestinationPort; 1764dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1765dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1766dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1767dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (*DestPort != Session->DestinationPort) { 1768dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Matched = FALSE; 1769dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1770dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1771dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1772dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1773dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Matched) { 1774dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1775dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Match the source ip of the received udp dgram 1776dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1777f737cfb953905f42f3324e8e53ec324a15314210jgong if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) != 0) { 1778dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1779dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (SrcIp != NULL) { 1780e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (SrcIp, &Session->SourceAddress, sizeof (EFI_IPv4_ADDRESS)); 1781dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1782dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1783dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1784dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!EFI_IP4_EQUAL (SrcIp, &Session->SourceAddress)) { 1785dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Matched = FALSE; 1786dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1787dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1788dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1789dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1790dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Matched) { 1791dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1792dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Match the source port of the received udp dgram 1793dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1794f737cfb953905f42f3324e8e53ec324a15314210jgong if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) != 0) { 1795dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1796dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (SrcPort != NULL) { 1797dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *SrcPort = Session->SourcePort; 1798dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1799dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1800dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1801dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (*SrcPort != Session->SourcePort) { 1802dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Matched = FALSE; 1803dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1804dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1805dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1806dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1807dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Matched) { 1808c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu ASSERT (RxData != NULL); 1809dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1810c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu HeaderLen = 0; 1811dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (HeaderSize != NULL) { 1812c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu HeaderLen = MIN (*HeaderSize, RxData->DataLength); 1813dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1814dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1815c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu if (RxData->DataLength - HeaderLen > *BufferSize) { 1816dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_BUFFER_TOO_SMALL; 1817dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1818c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu *HeaderSize = HeaderLen; 1819c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu *BufferSize = RxData->DataLength - HeaderLen; 1820c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu 1821c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu HeaderCopiedLen = 0; 1822c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu BufferCopiedLen = 0; 1823c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu for (FragmentIndex = 0; FragmentIndex < RxData->FragmentCount; FragmentIndex++) { 1824c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu FragmentLength = RxData->FragmentTable[FragmentIndex].FragmentLength; 1825c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu FragmentBuffer = RxData->FragmentTable[FragmentIndex].FragmentBuffer; 1826c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu if (HeaderCopiedLen + FragmentLength < HeaderLen) { 1827c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1828c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // Copy the header part of received data. 1829c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1830c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength); 1831c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu HeaderCopiedLen += FragmentLength; 1832c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu } else if (HeaderCopiedLen < HeaderLen) { 1833c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1834c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // Copy the header part of received data. 1835c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1836c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu CopiedLen = HeaderLen - HeaderCopiedLen; 1837c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen); 1838c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu HeaderCopiedLen += CopiedLen; 1839c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu 1840c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1841c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // Copy the other part of received data. 1842c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1843c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen); 1844c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu BufferCopiedLen += (FragmentLength - CopiedLen); 1845c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu } else { 1846c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1847c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // Copy the other part of received data. 1848c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu // 1849c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength); 1850c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu BufferCopiedLen += FragmentLength; 1851c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu } 1852c3cd46d421cef32077ae6caf860b50d00ba2aa7fsfu } 1853dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1854dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 1855dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1856dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_TIMEOUT; 1857dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1858dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1859dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1860dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Recycle the RxData 1861dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 1862dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff gBS->SignalEvent (RxData->RecycleSignal); 18638792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff 18648792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff if (!Matched) { 18658792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff goto TRY_AGAIN; 18668792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff } 1867dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 1868dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1869dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffON_EXIT: 1870dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1871dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Udp4->Cancel (Udp4, &Token); 1872dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1873dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff gBS->CloseEvent (Token.Event); 1874dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1875dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 1876dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 1877dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 1878e285199897e538523f762cb5b3900e81f872035avanjeff/** 1879f737cfb953905f42f3324e8e53ec324a15314210jgong Updates the IP receive filters of a network device and enables software filtering. 1880e285199897e538523f762cb5b3900e81f872035avanjeff 1881f737cfb953905f42f3324e8e53ec324a15314210jgong The NewFilter field is used to modify the network device's current IP receive 1882f737cfb953905f42f3324e8e53ec324a15314210jgong filter settings and to enable a software filter. This function updates the IpFilter 1883f737cfb953905f42f3324e8e53ec324a15314210jgong field of the EFI_PXE_BASE_CODE_MODE structure with the contents of NewIpFilter. 1884f737cfb953905f42f3324e8e53ec324a15314210jgong The software filter is used when the USE_FILTER in OpFlags is set to UdpRead(). 1885f737cfb953905f42f3324e8e53ec324a15314210jgong The current hardware filter remains in effect no matter what the settings of OpFlags 1886f737cfb953905f42f3324e8e53ec324a15314210jgong are, so that the meaning of ANY_DEST_IP set in OpFlags to UdpRead() is from those 1887f737cfb953905f42f3324e8e53ec324a15314210jgong packets whose reception is enabled in hardware-physical NIC address (unicast), 1888f737cfb953905f42f3324e8e53ec324a15314210jgong broadcast address, logical address or addresses (multicast), or all (promiscuous). 1889f737cfb953905f42f3324e8e53ec324a15314210jgong UdpRead() does not modify the IP filter settings. 1890f737cfb953905f42f3324e8e53ec324a15314210jgong Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP receive 1891f737cfb953905f42f3324e8e53ec324a15314210jgong filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. 1892f737cfb953905f42f3324e8e53ec324a15314210jgong If an application or driver wishes to preserve the IP receive filter settings, 1893f737cfb953905f42f3324e8e53ec324a15314210jgong it will have to preserve the IP receive filter settings before these calls, and 1894f737cfb953905f42f3324e8e53ec324a15314210jgong use SetIpFilter() to restore them after the calls. If incompatible filtering is 1895f737cfb953905f42f3324e8e53ec324a15314210jgong requested (for example, PROMISCUOUS with anything else) or if the device does not 1896f737cfb953905f42f3324e8e53ec324a15314210jgong support a requested filter setting and it cannot be accommodated in software 1897f737cfb953905f42f3324e8e53ec324a15314210jgong (for example, PROMISCUOUS not supported), EFI_INVALID_PARAMETER will be returned. 1898f737cfb953905f42f3324e8e53ec324a15314210jgong The IPlist field is used to enable IPs other than the StationIP. They may be 1899f737cfb953905f42f3324e8e53ec324a15314210jgong multicast or unicast. If IPcnt is set as well as EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP, 1900f737cfb953905f42f3324e8e53ec324a15314210jgong then both the StationIP and the IPs from the IPlist will be used. 1901e285199897e538523f762cb5b3900e81f872035avanjeff 1902f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 1903f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewFilter Pointer to the new set of IP receive filters. 1904e285199897e538523f762cb5b3900e81f872035avanjeff 1905f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The IP receive filter settings were updated. 1906f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 1907e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 1908e285199897e538523f762cb5b3900e81f872035avanjeff 1909dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 1910dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 1911dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 1912dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcSetIpFilter ( 1913dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 1914dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter 1915dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 1916dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 19178d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_STATUS Status; 19188d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff PXEBC_PRIVATE_DATA *Private; 19198d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_PXE_BASE_CODE_MODE *Mode; 19208d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff UINTN Index; 1921c82291bc3108c948a66d659da0fd76731351f530hhuan EFI_UDP4_CONFIG_DATA *Udp4Cfg; 19228d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff BOOLEAN PromiscuousNeed; 1923c82291bc3108c948a66d659da0fd76731351f530hhuan BOOLEAN AcceptPromiscuous; 1924c82291bc3108c948a66d659da0fd76731351f530hhuan BOOLEAN AcceptBroadcast; 1925c82291bc3108c948a66d659da0fd76731351f530hhuan BOOLEAN MultiCastUpdate; 19268d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 19278d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (This == NULL) { 1928894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff DEBUG ((EFI_D_ERROR, "This == NULL.\n")); 19298d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 19308d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19318d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 19328d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 19338d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Mode = Private->PxeBc.Mode; 19348d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1935894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff if (NewFilter == NULL) { 1936894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff DEBUG ((EFI_D_ERROR, "NewFilter == NULL.\n")); 19378d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 19388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1940894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff if (NewFilter->IpCnt > EFI_PXE_BASE_CODE_MAX_IPCNT) { 1941894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff DEBUG ((EFI_D_ERROR, "NewFilter->IpCnt > %d.\n", EFI_PXE_BASE_CODE_MAX_IPCNT)); 19428d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 19438d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19448d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 19458d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (!Mode->Started) { 19468d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff DEBUG ((EFI_D_ERROR, "BC was not started.\n")); 19478d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_NOT_STARTED; 19488d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19498d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1950c82291bc3108c948a66d659da0fd76731351f530hhuan if (Mode->UsingIpv6) { 1951c82291bc3108c948a66d659da0fd76731351f530hhuan DEBUG ((EFI_D_ERROR, "This driver is PXE for IPv4 Only.\n")); 1952c82291bc3108c948a66d659da0fd76731351f530hhuan return EFI_INVALID_PARAMETER; 1953c82291bc3108c948a66d659da0fd76731351f530hhuan } 1954c82291bc3108c948a66d659da0fd76731351f530hhuan 19558d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff PromiscuousNeed = FALSE; 1956894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff 19578d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff for (Index = 0; Index < NewFilter->IpCnt; ++Index) { 19588d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (IP4_IS_LOCAL_BROADCAST (EFI_IP4 (NewFilter->IpList[Index].v4))) { 19598d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 19608d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // The IP is a broadcast address. 19618d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 19628d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff DEBUG ((EFI_D_ERROR, "There is broadcast address in NewFilter.\n")); 19638d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 19648d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 1965f6b7393ceb34c9b3a27434268bf2ce517047641ftye if (NetIp4IsUnicast (EFI_IP4 (NewFilter->IpList[Index].v4), 0) && 1966e285199897e538523f762cb5b3900e81f872035avanjeff ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) 19678d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) { 19688d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 19698d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // If EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP is set and IP4 address is in IpList, 19708d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // promiscuous mode is needed. 19718d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 19728d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff PromiscuousNeed = TRUE; 19738d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19748d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 19758d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1976c82291bc3108c948a66d659da0fd76731351f530hhuan AcceptPromiscuous = FALSE; 1977c82291bc3108c948a66d659da0fd76731351f530hhuan AcceptBroadcast = FALSE; 1978c82291bc3108c948a66d659da0fd76731351f530hhuan MultiCastUpdate = FALSE; 19798d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 19808d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (PromiscuousNeed || 1981e285199897e538523f762cb5b3900e81f872035avanjeff ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0) || 1982e285199897e538523f762cb5b3900e81f872035avanjeff ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0) 19838d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ) { 19848d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 1985c82291bc3108c948a66d659da0fd76731351f530hhuan // Configure the udp4 filter to receive all packages. 19868d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 1987c82291bc3108c948a66d659da0fd76731351f530hhuan AcceptPromiscuous = TRUE; 1988c82291bc3108c948a66d659da0fd76731351f530hhuan } else if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) { 19898d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 1990c82291bc3108c948a66d659da0fd76731351f530hhuan // Configure the udp4 filter to receive all broadcast packages. 19918d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 1992c82291bc3108c948a66d659da0fd76731351f530hhuan AcceptBroadcast = TRUE; 1993c82291bc3108c948a66d659da0fd76731351f530hhuan } 19948d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 1995c82291bc3108c948a66d659da0fd76731351f530hhuan // 1996c82291bc3108c948a66d659da0fd76731351f530hhuan // In multicast condition when Promiscuous FALSE and IpCnt no-zero. 1997c82291bc3108c948a66d659da0fd76731351f530hhuan // Here check if there is any update of the multicast ip address. If yes, 1998c82291bc3108c948a66d659da0fd76731351f530hhuan // we need leave the old multicast group (by Config UDP instance to NULL), 1999c82291bc3108c948a66d659da0fd76731351f530hhuan // and join the new multicast group. 2000c82291bc3108c948a66d659da0fd76731351f530hhuan // 2001c82291bc3108c948a66d659da0fd76731351f530hhuan if (!AcceptPromiscuous) { 2002c82291bc3108c948a66d659da0fd76731351f530hhuan if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) { 2003c82291bc3108c948a66d659da0fd76731351f530hhuan if (Mode->IpFilter.IpCnt != NewFilter->IpCnt) { 2004c82291bc3108c948a66d659da0fd76731351f530hhuan MultiCastUpdate = TRUE; 2005c82291bc3108c948a66d659da0fd76731351f530hhuan } else if (CompareMem (Mode->IpFilter.IpList, NewFilter->IpList, NewFilter->IpCnt * sizeof (EFI_IP_ADDRESS)) != 0 ) { 2006c82291bc3108c948a66d659da0fd76731351f530hhuan MultiCastUpdate = TRUE; 2007c82291bc3108c948a66d659da0fd76731351f530hhuan } 20088d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 2009c82291bc3108c948a66d659da0fd76731351f530hhuan } 2010c82291bc3108c948a66d659da0fd76731351f530hhuan 2011c82291bc3108c948a66d659da0fd76731351f530hhuan // 2012c82291bc3108c948a66d659da0fd76731351f530hhuan // Check whether we need reconfigure the UDP instance. 2013c82291bc3108c948a66d659da0fd76731351f530hhuan // 2014c82291bc3108c948a66d659da0fd76731351f530hhuan Udp4Cfg = &Private->Udp4CfgData; 2015c82291bc3108c948a66d659da0fd76731351f530hhuan if ((AcceptPromiscuous != Udp4Cfg->AcceptPromiscuous) || 2016c82291bc3108c948a66d659da0fd76731351f530hhuan (AcceptBroadcast != Udp4Cfg->AcceptBroadcast) || MultiCastUpdate) { 2017c82291bc3108c948a66d659da0fd76731351f530hhuan // 2018c82291bc3108c948a66d659da0fd76731351f530hhuan // Clear the UDP instance configuration, all joined groups will be left 2019c82291bc3108c948a66d659da0fd76731351f530hhuan // during the operation. 2020c82291bc3108c948a66d659da0fd76731351f530hhuan // 2021c82291bc3108c948a66d659da0fd76731351f530hhuan Private->Udp4Read->Configure (Private->Udp4Read, NULL); 20228d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 20238d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 20248d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // Configure the UDP instance with the new configuration. 20258d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 2026c82291bc3108c948a66d659da0fd76731351f530hhuan Udp4Cfg->AcceptPromiscuous = AcceptPromiscuous; 2027c82291bc3108c948a66d659da0fd76731351f530hhuan Udp4Cfg->AcceptBroadcast = AcceptBroadcast; 2028c82291bc3108c948a66d659da0fd76731351f530hhuan Status = Private->Udp4Read->Configure (Private->Udp4Read, Udp4Cfg); 20298d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (EFI_ERROR (Status)) { 20308d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return Status; 20318d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20328d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 2033c82291bc3108c948a66d659da0fd76731351f530hhuan // 2034c82291bc3108c948a66d659da0fd76731351f530hhuan // In not Promiscuous mode, need to join the new multicast group. 2035c82291bc3108c948a66d659da0fd76731351f530hhuan // 2036c82291bc3108c948a66d659da0fd76731351f530hhuan if (!AcceptPromiscuous) { 20378d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff for (Index = 0; Index < NewFilter->IpCnt; ++Index) { 20388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (IP4_IS_MULTICAST (EFI_NTOHL (NewFilter->IpList[Index].v4))) { 20398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 2040c82291bc3108c948a66d659da0fd76731351f530hhuan // Join the mutilcast group. 20418d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 20428792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff Status = Private->Udp4Read->Groups (Private->Udp4Read, TRUE, &NewFilter->IpList[Index].v4); 20438d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (EFI_ERROR (Status)) { 20448d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return Status; 20458d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20468d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20478d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20488d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20498d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 20508d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 20518d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 20528d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 20538d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // Save the new filter. 20548d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 20558d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff CopyMem (&Mode->IpFilter, NewFilter, sizeof (Mode->IpFilter)); 20568d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 20578d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_SUCCESS; 2058dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2059dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2060dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2061e285199897e538523f762cb5b3900e81f872035avanjeff/** 2062f737cfb953905f42f3324e8e53ec324a15314210jgong Uses the ARP protocol to resolve a MAC address. 2063e285199897e538523f762cb5b3900e81f872035avanjeff 2064f737cfb953905f42f3324e8e53ec324a15314210jgong This function uses the ARP protocol to resolve a MAC address. The UsingIpv6 field 2065f737cfb953905f42f3324e8e53ec324a15314210jgong of the EFI_PXE_BASE_CODE_MODE structure is used to determine if IPv4 or IPv6 2066f737cfb953905f42f3324e8e53ec324a15314210jgong addresses are being used. The IP address specified by IpAddr is used to resolve 2067f737cfb953905f42f3324e8e53ec324a15314210jgong a MAC address. If the ARP protocol succeeds in resolving the specified address, 2068f737cfb953905f42f3324e8e53ec324a15314210jgong then the ArpCacheEntries and ArpCache fields of the EFI_PXE_BASE_CODE_MODE structure 2069f737cfb953905f42f3324e8e53ec324a15314210jgong are updated, and EFI_SUCCESS is returned. If MacAddr is not NULL, the resolved 2070e285199897e538523f762cb5b3900e81f872035avanjeff MAC address is placed there as well. If the PXE Base Code protocol is in the 2071e285199897e538523f762cb5b3900e81f872035avanjeff stopped state, then EFI_NOT_STARTED is returned. If the ARP protocol encounters 2072e285199897e538523f762cb5b3900e81f872035avanjeff a timeout condition while attempting to resolve an address, then EFI_TIMEOUT is 2073e285199897e538523f762cb5b3900e81f872035avanjeff returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, 2074f737cfb953905f42f3324e8e53ec324a15314210jgong then EFI_ABORTED is returned. 2075e285199897e538523f762cb5b3900e81f872035avanjeff 2076f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 2077f737cfb953905f42f3324e8e53ec324a15314210jgong @param IpAddr Pointer to the IP address that is used to resolve a MAC address. 2078f737cfb953905f42f3324e8e53ec324a15314210jgong @param MacAddr If not NULL, a pointer to the MAC address that was resolved with the 2079e285199897e538523f762cb5b3900e81f872035avanjeff ARP protocol. 2080e285199897e538523f762cb5b3900e81f872035avanjeff 2081f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The IP or MAC address was resolved. 2082f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 2083e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 2084e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. 2085e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_ICMP_ERROR Something error occur with the ICMP packet message. 2086e285199897e538523f762cb5b3900e81f872035avanjeff 2087dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2088dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2089dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2090dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcArp ( 2091dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL * This, 2092dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS * IpAddr, 2093dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_MAC_ADDRESS * MacAddr OPTIONAL 2094dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2095dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 20968d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff PXEBC_PRIVATE_DATA *Private; 20978d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_PXE_BASE_CODE_MODE *Mode; 20988d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_STATUS Status; 20998d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_MAC_ADDRESS TempMacAddr; 21008d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21018d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (This == NULL || IpAddr == NULL) { 21028d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 21038d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 21048d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21058d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 21068d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Mode = Private->PxeBc.Mode; 21078d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21088d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (!Mode->Started) { 21098d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_NOT_STARTED; 21108d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 21118d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21128d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (!Private->AddressIsOk || Mode->UsingIpv6) { 21138d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 21148d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // We can't resolve the IP address if we don't have a local address now. 21158d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // Don't have ARP for IPv6. 21168d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 21178d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_INVALID_PARAMETER; 21188d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 21198d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 2120982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = FALSE; 2121982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 2122982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!Mode->AutoArp) { 2123982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 2124982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // If AutoArp is set false, check arp cache 2125982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 2126982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff UpdateArpCache (This); 2127982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (!FindInArpCache (Mode, &IpAddr->v4, &TempMacAddr)) { 2128982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return EFI_DEVICE_ERROR; 2129982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 2130982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } else { 2131982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Status = Private->Arp->Request (Private->Arp, &IpAddr->v4, NULL, &TempMacAddr); 2132982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (EFI_ERROR (Status)) { 2133982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff if (Status == EFI_ICMP_ERROR) { 2134982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->IcmpErrorReceived = TRUE; 2135982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 2136982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff return Status; 2137982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff } 21388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 21398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21408d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (MacAddr != NULL) { 21418d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff CopyMem (MacAddr, &TempMacAddr, sizeof (EFI_MAC_ADDRESS)); 21428d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 21438d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 21448d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff return EFI_SUCCESS; 2145dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2146dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2147e285199897e538523f762cb5b3900e81f872035avanjeff/** 2148f737cfb953905f42f3324e8e53ec324a15314210jgong Updates the parameters that affect the operation of the PXE Base Code Protocol. 2149e285199897e538523f762cb5b3900e81f872035avanjeff 2150f737cfb953905f42f3324e8e53ec324a15314210jgong This function sets parameters that affect the operation of the PXE Base Code Protocol. 2151f737cfb953905f42f3324e8e53ec324a15314210jgong The parameter specified by NewAutoArp is used to control the generation of ARP 2152f737cfb953905f42f3324e8e53ec324a15314210jgong protocol packets. If NewAutoArp is TRUE, then ARP Protocol packets will be generated 2153f737cfb953905f42f3324e8e53ec324a15314210jgong as required by the PXE Base Code Protocol. If NewAutoArp is FALSE, then no ARP 2154f737cfb953905f42f3324e8e53ec324a15314210jgong Protocol packets will be generated. In this case, the only mappings that are 2155f737cfb953905f42f3324e8e53ec324a15314210jgong available are those stored in the ArpCache of the EFI_PXE_BASE_CODE_MODE structure. 2156f737cfb953905f42f3324e8e53ec324a15314210jgong If there are not enough mappings in the ArpCache to perform a PXE Base Code Protocol 2157f737cfb953905f42f3324e8e53ec324a15314210jgong service, then the service will fail. This function updates the AutoArp field of 2158f737cfb953905f42f3324e8e53ec324a15314210jgong the EFI_PXE_BASE_CODE_MODE structure to NewAutoArp. 2159f737cfb953905f42f3324e8e53ec324a15314210jgong The SetParameters() call must be invoked after a Callback Protocol is installed 2160f737cfb953905f42f3324e8e53ec324a15314210jgong to enable the use of callbacks. 2161e285199897e538523f762cb5b3900e81f872035avanjeff 2162f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 2163f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewAutoArp If not NULL, a pointer to a value that specifies whether to replace the 2164e285199897e538523f762cb5b3900e81f872035avanjeff current value of AutoARP. 2165f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewSendGUID If not NULL, a pointer to a value that specifies whether to replace the 2166e285199897e538523f762cb5b3900e81f872035avanjeff current value of SendGUID. 2167f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewTTL If not NULL, a pointer to be used in place of the current value of TTL, 2168e285199897e538523f762cb5b3900e81f872035avanjeff the "time to live" field of the IP header. 2169f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewToS If not NULL, a pointer to be used in place of the current value of ToS, 2170e285199897e538523f762cb5b3900e81f872035avanjeff the "type of service" field of the IP header. 2171f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewMakeCallback If not NULL, a pointer to a value that specifies whether to replace the 2172e285199897e538523f762cb5b3900e81f872035avanjeff current value of the MakeCallback field of the Mode structure. 2173e285199897e538523f762cb5b3900e81f872035avanjeff 2174f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The new parameters values were updated. 2175f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 2176e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 2177e285199897e538523f762cb5b3900e81f872035avanjeff 2178dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2179dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2180dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2181dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcSetParameters ( 2182dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL *This, 2183f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN *NewAutoArp OPTIONAL, 2184f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN *NewSendGUID OPTIONAL, 2185f737cfb953905f42f3324e8e53ec324a15314210jgong IN UINT8 *NewTTL OPTIONAL, 2186f737cfb953905f42f3324e8e53ec324a15314210jgong IN UINT8 *NewToS OPTIONAL, 2187dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN *NewMakeCallback // OPTIONAL 2188dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2189dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2190dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 2191dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 2192dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 2193dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2194dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_SUCCESS; 2195dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2196dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 2197dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_INVALID_PARAMETER; 2198dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 2199dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2200dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2201dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 2202dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 2203dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2204f737cfb953905f42f3324e8e53ec324a15314210jgong if (NewSendGUID != NULL && *NewSendGUID) { 2205dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2206dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // FixMe, cann't locate SendGuid 2207dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2208dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2209dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2210f737cfb953905f42f3324e8e53ec324a15314210jgong if (NewMakeCallback != NULL && *NewMakeCallback) { 2211dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2212dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->HandleProtocol ( 2213dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Controller, 2214dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &gEfiPxeBaseCodeCallbackProtocolGuid, 2215dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff (VOID **) &Private->PxeBcCallback 2216dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2217dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status) || (Private->PxeBcCallback->Callback == NULL)) { 2218dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2219dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_INVALID_PARAMETER; 2220dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 2221dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2222dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2223dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2224dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 2225dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_NOT_STARTED; 2226dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 2227dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2228dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2229dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewMakeCallback != NULL) { 2230dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2231dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (*NewMakeCallback) { 2232dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2233dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Update the Callback protocol. 2234dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2235dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->HandleProtocol ( 2236dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Controller, 2237dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &gEfiPxeBaseCodeCallbackProtocolGuid, 2238dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff (VOID **) &Private->PxeBcCallback 2239dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2240dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2241dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status) || (Private->PxeBcCallback->Callback == NULL)) { 2242dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_INVALID_PARAMETER; 2243dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff goto ON_EXIT; 2244dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2245dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 2246dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->PxeBcCallback = NULL; 2247dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2248dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2249dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->MakeCallbacks = *NewMakeCallback; 2250dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2251dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2252dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewAutoArp != NULL) { 2253dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->AutoArp = *NewAutoArp; 2254dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2255dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2256dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewSendGUID != NULL) { 2257dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->SendGUID = *NewSendGUID; 2258dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2259dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2260dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewTTL != NULL) { 2261dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->TTL = *NewTTL; 2262dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2263dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2264dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewToS != NULL) { 2265dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->ToS = *NewToS; 2266dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2267dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2268dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffON_EXIT: 2269dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2270dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2271dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2272e285199897e538523f762cb5b3900e81f872035avanjeff/** 2273f737cfb953905f42f3324e8e53ec324a15314210jgong Updates the station IP address and/or subnet mask values of a network device. 2274e285199897e538523f762cb5b3900e81f872035avanjeff 2275f737cfb953905f42f3324e8e53ec324a15314210jgong This function updates the station IP address and/or subnet mask values of a network 2276f737cfb953905f42f3324e8e53ec324a15314210jgong device. The NewStationIp field is used to modify the network device's current IP address. 2277f737cfb953905f42f3324e8e53ec324a15314210jgong If NewStationIP is NULL, then the current IP address will not be modified. Otherwise, 2278f737cfb953905f42f3324e8e53ec324a15314210jgong this function updates the StationIp field of the EFI_PXE_BASE_CODE_MODE structure 2279f737cfb953905f42f3324e8e53ec324a15314210jgong with NewStationIp. The NewSubnetMask field is used to modify the network device's current subnet 2280f737cfb953905f42f3324e8e53ec324a15314210jgong mask. If NewSubnetMask is NULL, then the current subnet mask will not be modified. 2281f737cfb953905f42f3324e8e53ec324a15314210jgong Otherwise, this function updates the SubnetMask field of the EFI_PXE_BASE_CODE_MODE 2282f737cfb953905f42f3324e8e53ec324a15314210jgong structure with NewSubnetMask. 2283e285199897e538523f762cb5b3900e81f872035avanjeff 2284f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 2285e285199897e538523f762cb5b3900e81f872035avanjeff @param NewStationIp Pointer to the new IP address to be used by the network device. 2286e285199897e538523f762cb5b3900e81f872035avanjeff @param NewSubnetMask Pointer to the new subnet mask to be used by the network device. 2287e285199897e538523f762cb5b3900e81f872035avanjeff 2288f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The new station IP address and/or subnet mask were updated. 2289f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 2290e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 2291e285199897e538523f762cb5b3900e81f872035avanjeff 2292dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2293dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2294dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2295dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcSetStationIP ( 2296dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL * This, 2297f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_IP_ADDRESS * NewStationIp OPTIONAL, 2298dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_IP_ADDRESS * NewSubnetMask OPTIONAL 2299dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2300dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2301dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 2302dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 23038d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff EFI_ARP_CONFIG_DATA ArpConfigData; 2304dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2305dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 2306dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 2307dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2308dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2309f6b7393ceb34c9b3a27434268bf2ce517047641ftye if (NewStationIp != NULL && !NetIp4IsUnicast (NTOHL (NewStationIp->Addr[0]), 0)) { 2310dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 2311dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2312dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2313dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewSubnetMask != NULL && !IP4_IS_VALID_NETMASK (NTOHL (NewSubnetMask->Addr[0]))) { 2314dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 2315dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2316dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2317dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 2318dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 2319dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2320dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 2321dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 2322dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2323dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2324dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewStationIp != NULL) { 2325555e76f83f0ccf60434d3c72720f0a79f5ff4639xli CopyMem (&Mode->StationIp, NewStationIp, sizeof (EFI_IP_ADDRESS)); 2326555e76f83f0ccf60434d3c72720f0a79f5ff4639xli CopyMem (&Private->StationIp, NewStationIp, sizeof (EFI_IP_ADDRESS)); 2327dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2328dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2329dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewSubnetMask != NULL) { 2330555e76f83f0ccf60434d3c72720f0a79f5ff4639xli CopyMem (&Mode->SubnetMask, NewSubnetMask, sizeof (EFI_IP_ADDRESS)); 2331555e76f83f0ccf60434d3c72720f0a79f5ff4639xli CopyMem (&Private->SubnetMask ,NewSubnetMask, sizeof (EFI_IP_ADDRESS)); 2332dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2333dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2334dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->AddressIsOk = TRUE; 2335dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 23368d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff if (!Mode->UsingIpv6) { 23378d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 23388d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // If in IPv4 mode, configure the corresponding ARP with this new 23398d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // station IP address. 23408d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff // 23418d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA)); 23428d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 23438d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ArpConfigData.SwAddressType = 0x0800; 2344c9325700d0ef25eaf45077928af3f93b15ac5fe0ydong ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS); 23458d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff ArpConfigData.StationAddress = &Private->StationIp.v4; 23468d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 23478d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private->Arp->Configure (Private->Arp, NULL); 23488d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff Private->Arp->Configure (Private->Arp, &ArpConfigData); 2349982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff 2350982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 2351982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // Update the route table. 2352982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff // 2353982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTableEntries = 1; 2354982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].IpAddr.Addr[0] = Private->StationIp.Addr[0] & Private->SubnetMask.Addr[0]; 2355982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].SubnetMask.Addr[0] = Private->SubnetMask.Addr[0]; 2356982a9eaea270fdc05d60d570e3d0e4d168654c05vanjeff Mode->RouteTable[0].GwAddr.Addr[0] = 0; 23578d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff } 23588d285ec0ce8b4c85f8e98b98ed95cbc801817fb9vanjeff 2359dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_SUCCESS; 2360dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2361dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2362e285199897e538523f762cb5b3900e81f872035avanjeff/** 2363f737cfb953905f42f3324e8e53ec324a15314210jgong Updates the contents of the cached DHCP and Discover packets. 2364e285199897e538523f762cb5b3900e81f872035avanjeff 2365f737cfb953905f42f3324e8e53ec324a15314210jgong The pointers to the new packets are used to update the contents of the cached 2366f737cfb953905f42f3324e8e53ec324a15314210jgong packets in the EFI_PXE_BASE_CODE_MODE structure. 2367e285199897e538523f762cb5b3900e81f872035avanjeff 2368f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. 2369f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewDhcpDiscoverValid Pointer to a value that will replace the current 2370e285199897e538523f762cb5b3900e81f872035avanjeff DhcpDiscoverValid field. 2371f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewDhcpAckReceived Pointer to a value that will replace the current 2372e285199897e538523f762cb5b3900e81f872035avanjeff DhcpAckReceived field. 2373f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewProxyOfferReceived Pointer to a value that will replace the current 2374e285199897e538523f762cb5b3900e81f872035avanjeff ProxyOfferReceived field. 2375e285199897e538523f762cb5b3900e81f872035avanjeff @param NewPxeDiscoverValid Pointer to a value that will replace the current 2376e285199897e538523f762cb5b3900e81f872035avanjeff ProxyOfferReceived field. 2377f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewPxeReplyReceived Pointer to a value that will replace the current 2378e285199897e538523f762cb5b3900e81f872035avanjeff PxeReplyReceived field. 2379f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewPxeBisReplyReceived Pointer to a value that will replace the current 2380e285199897e538523f762cb5b3900e81f872035avanjeff PxeBisReplyReceived field. 2381e285199897e538523f762cb5b3900e81f872035avanjeff @param NewDhcpDiscover Pointer to the new cached DHCP Discover packet contents. 2382f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewDhcpAck Pointer to the new cached DHCP Ack packet contents. 2383f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewProxyOffer Pointer to the new cached Proxy Offer packet contents. 2384f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewPxeDiscover Pointer to the new cached PXE Discover packet contents. 2385f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewPxeReply Pointer to the new cached PXE Reply packet contents. 2386f737cfb953905f42f3324e8e53ec324a15314210jgong @param NewPxeBisReply Pointer to the new cached PXE BIS Reply packet contents. 2387e285199897e538523f762cb5b3900e81f872035avanjeff 2388f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The cached packet contents were updated. 2389f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. 2390f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_INVALID_PARAMETER This is NULL or not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. 2391e285199897e538523f762cb5b3900e81f872035avanjeff 2392dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2393dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2394dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2395dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeBcSetPackets ( 2396dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PROTOCOL * This, 2397f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewDhcpDiscoverValid OPTIONAL, 2398f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewDhcpAckReceived OPTIONAL, 2399f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewProxyOfferReceived OPTIONAL, 2400f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewPxeDiscoverValid OPTIONAL, 2401f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewPxeReplyReceived OPTIONAL, 2402f737cfb953905f42f3324e8e53ec324a15314210jgong IN BOOLEAN * NewPxeBisReplyReceived OPTIONAL, 2403f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PACKET * NewDhcpDiscover OPTIONAL, 2404f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PACKET * NewDhcpAck OPTIONAL, 2405f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PACKET * NewProxyOffer OPTIONAL, 2406f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PACKET * NewPxeDiscover OPTIONAL, 2407f737cfb953905f42f3324e8e53ec324a15314210jgong IN EFI_PXE_BASE_CODE_PACKET * NewPxeReply OPTIONAL, 2408dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PACKET * NewPxeBisReply OPTIONAL 2409dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2410dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2411dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 2412dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 2413dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2414dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL) { 2415dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 2416dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2417dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2418dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This); 2419dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = Private->PxeBc.Mode; 2420dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2421dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!Mode->Started) { 2422dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_NOT_STARTED; 2423dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2424dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2425dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewDhcpDiscoverValid != NULL) { 2426dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->DhcpDiscoverValid = *NewDhcpDiscoverValid; 2427dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2428dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2429dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewDhcpAckReceived != NULL) { 2430dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->DhcpAckReceived = *NewDhcpAckReceived; 2431dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2432dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2433dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewProxyOfferReceived != NULL) { 2434dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->ProxyOfferReceived = *NewProxyOfferReceived; 2435dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2436dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2437dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeDiscoverValid != NULL) { 2438dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->PxeDiscoverValid = *NewPxeDiscoverValid; 2439dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2440dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2441dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeReplyReceived != NULL) { 2442dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->PxeReplyReceived = *NewPxeReplyReceived; 2443dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2444dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2445dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeBisReplyReceived != NULL) { 2446dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode->PxeBisReplyReceived = *NewPxeBisReplyReceived; 2447dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2448dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2449dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewDhcpDiscover != NULL) { 2450e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->DhcpDiscover, NewDhcpDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2451dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2452dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2453dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewDhcpAck != NULL) { 2454e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->DhcpAck, NewDhcpAck, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2455dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2456dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2457dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewProxyOffer != NULL) { 2458e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->ProxyOffer, NewProxyOffer, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2459dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2460dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2461dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeDiscover != NULL) { 2462e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->PxeDiscover, NewPxeDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2463dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2464dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2465dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeReply != NULL) { 2466e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->PxeReply, NewPxeReply, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2467dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2468dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2469dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewPxeBisReply != NULL) { 2470e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Mode->PxeBisReply, NewPxeBisReply, sizeof (EFI_PXE_BASE_CODE_PACKET)); 2471dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2472dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2473dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_SUCCESS; 2474dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2475dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2476dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_PXE_BASE_CODE_PROTOCOL mPxeBcProtocolTemplate = { 2477dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_PROTOCOL_REVISION, 2478dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcStart, 2479dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcStop, 2480dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcDhcp, 2481dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcDiscover, 2482dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcMtftp, 2483dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcUdpWrite, 2484dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcUdpRead, 2485dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcSetIpFilter, 2486dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcArp, 2487dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcSetParameters, 2488dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcSetStationIP, 2489dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeBcSetPackets, 2490dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL 2491dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}; 2492dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2493e285199897e538523f762cb5b3900e81f872035avanjeff/** 2494f737cfb953905f42f3324e8e53ec324a15314210jgong Callback function that is invoked when the PXE Base Code Protocol is about to transmit, has 2495e285199897e538523f762cb5b3900e81f872035avanjeff received, or is waiting to receive a packet. 2496e285199897e538523f762cb5b3900e81f872035avanjeff 2497f737cfb953905f42f3324e8e53ec324a15314210jgong This function is invoked when the PXE Base Code Protocol is about to transmit, has received, 2498f737cfb953905f42f3324e8e53ec324a15314210jgong or is waiting to receive a packet. Parameters Function and Received specify the type of event. 2499f737cfb953905f42f3324e8e53ec324a15314210jgong Parameters PacketLen and Packet specify the packet that generated the event. If these fields 2500f737cfb953905f42f3324e8e53ec324a15314210jgong are zero and NULL respectively, then this is a status update callback. If the operation specified 2501f737cfb953905f42f3324e8e53ec324a15314210jgong by Function is to continue, then CALLBACK_STATUS_CONTINUE should be returned. If the operation 2502f737cfb953905f42f3324e8e53ec324a15314210jgong specified by Function should be aborted, then CALLBACK_STATUS_ABORT should be returned. Due to 2503f737cfb953905f42f3324e8e53ec324a15314210jgong the polling nature of UEFI device drivers, a callback function should not execute for more than 5 ms. 2504f737cfb953905f42f3324e8e53ec324a15314210jgong The SetParameters() function must be called after a Callback Protocol is installed to enable the 2505f737cfb953905f42f3324e8e53ec324a15314210jgong use of callbacks. 2506e285199897e538523f762cb5b3900e81f872035avanjeff 2507f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Pointer to the EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL instance. 2508e285199897e538523f762cb5b3900e81f872035avanjeff @param Function The PXE Base Code Protocol function that is waiting for an event. 2509f737cfb953905f42f3324e8e53ec324a15314210jgong @param Received TRUE if the callback is being invoked due to a receive event. FALSE if 2510e285199897e538523f762cb5b3900e81f872035avanjeff the callback is being invoked due to a transmit event. 2511f737cfb953905f42f3324e8e53ec324a15314210jgong @param PacketLength The length, in bytes, of Packet. This field will have a value of zero if 2512e285199897e538523f762cb5b3900e81f872035avanjeff this is a wait for receive event. 2513f737cfb953905f42f3324e8e53ec324a15314210jgong @param PacketPtr If Received is TRUE, a pointer to the packet that was just received; 2514e285199897e538523f762cb5b3900e81f872035avanjeff otherwise a pointer to the packet that is about to be transmitted. 2515e285199897e538523f762cb5b3900e81f872035avanjeff 2516e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE if Function specifies a continue operation 2517f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT if Function specifies an abort operation 2518e285199897e538523f762cb5b3900e81f872035avanjeff 2519dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2520dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_PXE_BASE_CODE_CALLBACK_STATUS 2521dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2522dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeLoadFileCallback ( 2523dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL * This, 2524dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_FUNCTION Function, 2525dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN Received, 2526dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN UINT32 PacketLength, 2527dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_PXE_BASE_CODE_PACKET * PacketPtr OPTIONAL 2528dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2529dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2530dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_INPUT_KEY Key; 2531dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 2532dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2533dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2534dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Catch Ctrl-C or ESC to abort. 2535dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2536dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); 2537dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2538dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!EFI_ERROR (Status)) { 2539dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2540dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Key.ScanCode == SCAN_ESC || Key.UnicodeChar == (0x1F & 'c')) { 2541dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2542dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT; 2543dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2544dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2545dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2546dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // No print if receive packet 2547dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2548dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Received) { 2549dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE; 2550dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2551dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2552dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Print only for three functions 2553dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2554dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff switch (Function) { 2555dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2556dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_FUNCTION_MTFTP: 2557dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2558dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Print only for open MTFTP packets, not every MTFTP packets 2559dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2560dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (PacketLength != 0 && PacketPtr != NULL) { 2561dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (PacketPtr->Raw[0x1C] != 0x00 || PacketPtr->Raw[0x1D] != 0x01) { 2562dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE; 2563dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2564dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2565dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 2566dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2567dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_FUNCTION_DHCP: 2568dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff case EFI_PXE_BASE_CODE_FUNCTION_DISCOVER: 2569dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff break; 2570dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2571dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff default: 2572dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE; 2573dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2574dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2575dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (PacketLength != 0 && PacketPtr != NULL) { 2576dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2577dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Print '.' when transmit a packet 2578dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2579dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("."); 2580dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2581dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2582dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2583dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE; 2584dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2585dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2586dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_PXE_BASE_CODE_CALLBACK_PROTOCOL mPxeBcCallBackTemplate = { 2587dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION, 2588dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EfiPxeLoadFileCallback 2589dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}; 2590dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2591dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2592dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/** 2593f737cfb953905f42f3324e8e53ec324a15314210jgong Find the boot file. 2594dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2595e285199897e538523f762cb5b3900e81f872035avanjeff @param Private Pointer to PxeBc private data. 2596e285199897e538523f762cb5b3900e81f872035avanjeff @param BufferSize Pointer to buffer size. 2597e285199897e538523f762cb5b3900e81f872035avanjeff @param Buffer Pointer to buffer. 2598dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2599f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS Discover the boot file successfully. 2600f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_TIMEOUT The TFTP/MTFTP operation timed out. 2601f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED PXE bootstrap server, so local boot need abort. 2602f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_BUFFER_TOO_SMALL The buffer is too small to load the boot file. 2603e285199897e538523f762cb5b3900e81f872035avanjeff 2604dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2605dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2606dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffDiscoverBootFile ( 2607dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN PXEBC_PRIVATE_DATA *Private, 2608dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN OUT UINT64 *BufferSize, 2609dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN VOID *Buffer 2610dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2611dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2612dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; 2613dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_MODE *Mode; 2614dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 2615dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT16 Type; 2616dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT16 Layer; 2617dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BOOLEAN UseBis; 2618dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_CACHED_DHCP4_PACKET *Packet; 2619dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT16 Value; 2620dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2621dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc = &Private->PxeBc; 2622dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Mode = PxeBc->Mode; 2623dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Type = EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP; 2624dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Layer = EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL; 2625dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2626dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2627dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // do DHCP. 2628dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2629dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->Dhcp (PxeBc, TRUE); 2630dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 2631dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2632dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2633dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2634dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2635dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Select a boot server 2636dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2637dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcSelectBootPrompt (Private); 2638dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2639dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Status == EFI_SUCCESS) { 2640dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcSelectBootMenu (Private, &Type, TRUE); 2641dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else if (Status == EFI_TIMEOUT) { 2642dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBcSelectBootMenu (Private, &Type, FALSE); 2643dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2644dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2645dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!EFI_ERROR (Status)) { 2646dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2647dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Type == EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP) { 2648dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2649dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Local boot(PXE bootstrap server) need abort 2650dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2651dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_ABORTED; 2652dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2653dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2654dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UseBis = (BOOLEAN) (Mode->BisSupported && Mode->BisDetected); 2655dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->Discover (PxeBc, Type, &Layer, UseBis, NULL); 2656dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 2657dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2658dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2659dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2660dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2661dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *BufferSize = 0; 2662dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2663dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2664dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Get bootfile name and (m)tftp server ip addresss 2665dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2666dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Mode->PxeReplyReceived) { 2667dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Packet = &Private->PxeReply; 2668dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else if (Mode->ProxyOfferReceived) { 2669dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Packet = &Private->ProxyOffer; 2670dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 2671dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Packet = &Private->Dhcp4Ack; 2672dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2673dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2674319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff // 26752ce5c88a7adaea3eeeccc932b18da5f02440f8cdvanjeff // Use siaddr(next server) in DHCPOFFER packet header, if zero, use option 54(server identifier) 26762ce5c88a7adaea3eeeccc932b18da5f02440f8cdvanjeff // in DHCPOFFER packet. 26772ce5c88a7adaea3eeeccc932b18da5f02440f8cdvanjeff // (It does not comply with PXE Spec, Ver2.1) 2678319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff // 26792ce5c88a7adaea3eeeccc932b18da5f02440f8cdvanjeff if (EFI_IP4_EQUAL (&Packet->Packet.Offer.Dhcp4.Header.ServerAddr, &mZeroIp4Addr)) { 2680e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem ( 2681dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->ServerIp, 2682dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data, 2683dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff sizeof (EFI_IPv4_ADDRESS) 2684dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2685319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff } else { 2686319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff CopyMem ( 2687e285199897e538523f762cb5b3900e81f872035avanjeff &Private->ServerIp, 2688e285199897e538523f762cb5b3900e81f872035avanjeff &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, 2689319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff sizeof (EFI_IPv4_ADDRESS) 2690319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff ); 2691319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff } 2692319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff if (Private->ServerIp.Addr[0] == 0) { 2693319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff return EFI_DEVICE_ERROR; 2694dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2695dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2696dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ASSERT (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL); 2697dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2698dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2699dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // bootlfile name 2700dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2701dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->BootFileName = (CHAR8 *) (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data); 2702dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2703dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN] != NULL) { 2704dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2705dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Already have the bootfile length option, compute the file size 2706dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2707e48e37fce2611df7a52aff271835ff72ee396d9bvanjeff CopyMem (&Value, Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value)); 2708dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Value = NTOHS (Value); 2709dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *BufferSize = 512 * Value; 2710dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_BUFFER_TOO_SMALL; 2711dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 2712dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2713dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Get the bootfile size from tftp 2714dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2715dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->Mtftp ( 2716dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc, 2717dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, 2718dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Buffer, 2719dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff FALSE, 2720dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BufferSize, 2721fa6d3ee4913eaf3b0fd9ddb8a4e3b618584bd965ljin &Private->BlockSize, 2722dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->ServerIp, 2723dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff (UINT8 *) Private->BootFileName, 2724dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL, 2725dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff FALSE 2726dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2727dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2728dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2729dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->FileSize = (UINTN) *BufferSize; 2730dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2731dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2732dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2733dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2734dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/** 2735f737cfb953905f42f3324e8e53ec324a15314210jgong Causes the driver to load a specified file. 2736f737cfb953905f42f3324e8e53ec324a15314210jgong 2737f737cfb953905f42f3324e8e53ec324a15314210jgong @param This Protocol instance pointer. 2738f737cfb953905f42f3324e8e53ec324a15314210jgong @param FilePath The device specific path of the file to load. 2739e285199897e538523f762cb5b3900e81f872035avanjeff @param BootPolicy If TRUE, indicates that the request originates from the 2740f737cfb953905f42f3324e8e53ec324a15314210jgong boot manager is attempting to load FilePath as a boot 2741f737cfb953905f42f3324e8e53ec324a15314210jgong selection. If FALSE, then FilePath must match as exact file 2742f737cfb953905f42f3324e8e53ec324a15314210jgong to be loaded. 2743f737cfb953905f42f3324e8e53ec324a15314210jgong @param BufferSize On input the size of Buffer in bytes. On output with a return 2744e285199897e538523f762cb5b3900e81f872035avanjeff code of EFI_SUCCESS, the amount of data transferred to 2745f737cfb953905f42f3324e8e53ec324a15314210jgong Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, 2746f737cfb953905f42f3324e8e53ec324a15314210jgong the size of Buffer required to retrieve the requested file. 2747f737cfb953905f42f3324e8e53ec324a15314210jgong @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL, 2748e285199897e538523f762cb5b3900e81f872035avanjeff then no the size of the requested file is returned in 2749f737cfb953905f42f3324e8e53ec324a15314210jgong BufferSize. 2750f737cfb953905f42f3324e8e53ec324a15314210jgong 2751f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_SUCCESS The file was loaded. 2752f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_UNSUPPORTED The device does not support the provided BootPolicy 2753e285199897e538523f762cb5b3900e81f872035avanjeff @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or 2754f737cfb953905f42f3324e8e53ec324a15314210jgong BufferSize is NULL. 2755f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NO_MEDIA No medium was present to load the file. 2756f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_DEVICE_ERROR The file was not loaded due to a device error. 2757f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NO_RESPONSE The remote system did not respond. 2758f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_NOT_FOUND The file was not found. 2759f737cfb953905f42f3324e8e53ec324a15314210jgong @retval EFI_ABORTED The file load process was manually cancelled. 2760dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2761dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/ 2762dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFI_STATUS 2763dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEFIAPI 2764dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffEfiPxeLoadFile ( 2765dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_LOAD_FILE_PROTOCOL * This, 2766dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN EFI_DEVICE_PATH_PROTOCOL * FilePath, 2767dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN BOOLEAN BootPolicy, 2768dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN OUT UINTN *BufferSize, 2769dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff IN VOID *Buffer OPTIONAL 2770dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ) 2771dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{ 2772dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PXEBC_PRIVATE_DATA *Private; 2773dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; 2774dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff BOOLEAN NewMakeCallback; 2775dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_STATUS Status; 2776dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff UINT64 TmpBufSize; 2777dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu BOOLEAN MediaPresent; 2778dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 27796758032da90bda58cb49e1823637bc19a1f4cc32Zhang Lubo if (FilePath == NULL || !IsDevicePathEnd (FilePath)) { 27806758032da90bda58cb49e1823637bc19a1f4cc32Zhang Lubo return EFI_INVALID_PARAMETER; 27816758032da90bda58cb49e1823637bc19a1f4cc32Zhang Lubo } 27826758032da90bda58cb49e1823637bc19a1f4cc32Zhang Lubo 2783dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private = PXEBC_PRIVATE_DATA_FROM_LOADFILE (This); 2784dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc = &Private->PxeBc; 2785dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NewMakeCallback = FALSE; 2786dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_DEVICE_ERROR; 2787dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2788dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (This == NULL || BufferSize == NULL) { 2789dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2790dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_INVALID_PARAMETER; 2791dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2792dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2793dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2794dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Only support BootPolicy 2795dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2796dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (!BootPolicy) { 2797dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return EFI_UNSUPPORTED; 2798dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2799dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2800dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu // 2801dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu // Check media status before PXE start 2802dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu // 2803dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu MediaPresent = TRUE; 2804dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu NetLibDetectMedia (Private->Controller, &MediaPresent); 2805dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu if (!MediaPresent) { 2806dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu return EFI_NO_MEDIA; 2807dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu } 2808dd29f3edb9849b7bb51f0ae4be8941a760846ef3xdu 2809dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->Start (PxeBc, FALSE); 2810dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { 2811dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2812dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2813dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2814dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->HandleProtocol ( 2815dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Controller, 2816dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &gEfiPxeBaseCodeCallbackProtocolGuid, 2817dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff (VOID **) &Private->PxeBcCallback 2818dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2819dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Status == EFI_UNSUPPORTED) { 2820dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2821dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff CopyMem (&Private->LoadFileCallback, &mPxeBcCallBackTemplate, sizeof (Private->LoadFileCallback)); 2822dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2823dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = gBS->InstallProtocolInterface ( 2824dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->Controller, 2825dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &gEfiPxeBaseCodeCallbackProtocolGuid, 2826dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_NATIVE_INTERFACE, 2827dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->LoadFileCallback 2828dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2829dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2830dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NewMakeCallback = (BOOLEAN) (Status == EFI_SUCCESS); 2831dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2832dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, &NewMakeCallback); 2833dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (EFI_ERROR (Status)) { 2834dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc->Stop (PxeBc); 2835dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2836dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2837dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2838dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2839dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Private->FileSize == 0) { 2840dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff TmpBufSize = 0; 2841dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = DiscoverBootFile (Private, &TmpBufSize, Buffer); 2842dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2843dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (sizeof (UINTN) < sizeof (UINT64) && (TmpBufSize > 0xFFFFFFFF)) { 2844dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_DEVICE_ERROR; 284539941daf90572c818328de50fbcb7a5e5e0e7eb2gikidy } else if (TmpBufSize > 0 && *BufferSize >= (UINTN) TmpBufSize && Buffer != NULL) { 2846319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff *BufferSize = (UINTN) TmpBufSize; 2847319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff Status = PxeBc->Mtftp ( 2848319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff PxeBc, 2849319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff EFI_PXE_BASE_CODE_TFTP_READ_FILE, 2850319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff Buffer, 2851319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff FALSE, 2852319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff &TmpBufSize, 2853fa6d3ee4913eaf3b0fd9ddb8a4e3b618584bd965ljin &Private->BlockSize, 2854319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff &Private->ServerIp, 2855319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff (UINT8 *) Private->BootFileName, 2856319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff NULL, 2857319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff FALSE 2858319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff ); 285939941daf90572c818328de50fbcb7a5e5e0e7eb2gikidy } else if (TmpBufSize > 0) { 2860dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *BufferSize = (UINTN) TmpBufSize; 2861319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff Status = EFI_BUFFER_TOO_SMALL; 2862dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2863319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff } else if (Buffer == NULL || Private->FileSize > *BufferSize) { 2864dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff *BufferSize = Private->FileSize; 2865dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = EFI_BUFFER_TOO_SMALL; 2866dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 2867dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2868dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Download the file. 2869dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2870dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff TmpBufSize = (UINT64) (*BufferSize); 2871dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Status = PxeBc->Mtftp ( 2872dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc, 2873dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff EFI_PXE_BASE_CODE_TFTP_READ_FILE, 2874dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Buffer, 2875dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff FALSE, 2876dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &TmpBufSize, 2877fa6d3ee4913eaf3b0fd9ddb8a4e3b618584bd965ljin &Private->BlockSize, 2878dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->ServerIp, 2879dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff (UINT8 *) Private->BootFileName, 2880dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NULL, 2881dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff FALSE 2882dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2883dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2884dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2885dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // If we added a callback protocol, now is the time to remove it. 2886dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2887dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (NewMakeCallback) { 2888dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2889dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff NewMakeCallback = FALSE; 2890dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2891dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, &NewMakeCallback); 2892dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2893dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff gBS->UninstallProtocolInterface ( 2894dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff Private->Controller, 2895dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &gEfiPxeBaseCodeCallbackProtocolGuid, 2896dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff &Private->LoadFileCallback 2897dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff ); 2898dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2899619eff3f290c7e893d858c16e70b641471a5a704vanjeff 2900dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2901dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // Check download status 2902dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff // 2903619eff3f290c7e893d858c16e70b641471a5a704vanjeff if (Status == EFI_SUCCESS) { 29046ee21b60a8adb82452a15afef4bf4938e3eec4b0vanjeff // 290530268f29bd38a8e07b9914a1be00583c172c4c40Fu Siyuan // The DHCP4 can have only one configured child instance so we need to stop 290630268f29bd38a8e07b9914a1be00583c172c4c40Fu Siyuan // reset the DHCP4 child before we return. Otherwise the other programs which 290730268f29bd38a8e07b9914a1be00583c172c4c40Fu Siyuan // also need to use DHCP4 will be impacted. 29086ee21b60a8adb82452a15afef4bf4938e3eec4b0vanjeff // The functionality of PXE Base Code protocol will not be stopped, 29096ee21b60a8adb82452a15afef4bf4938e3eec4b0vanjeff // when downloading is successfully. 29106ee21b60a8adb82452a15afef4bf4938e3eec4b0vanjeff // 291130268f29bd38a8e07b9914a1be00583c172c4c40Fu Siyuan Private->Dhcp4->Stop (Private->Dhcp4); 291230268f29bd38a8e07b9914a1be00583c172c4c40Fu Siyuan Private->Dhcp4->Configure (Private->Dhcp4, NULL); 29138792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff return EFI_SUCCESS; 2914dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2915619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_BUFFER_TOO_SMALL) { 2916dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff if (Buffer != NULL) { 2917dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E05: Download buffer is smaller than requested file.\n"); 2918dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } else { 2919ee6e8714a08e845e3d4b46c022e7da717dd7fbacvanjeff // 2920ee6e8714a08e845e3d4b46c022e7da717dd7fbacvanjeff // The functionality of PXE Base Code protocol will not be stopped. 2921ee6e8714a08e845e3d4b46c022e7da717dd7fbacvanjeff // 2922dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2923dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2924dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2925619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_DEVICE_ERROR) { 2926dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E07: Network device error.\n"); 2927dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2928619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_OUT_OF_RESOURCES) { 2929dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E09: Could not allocate I/O buffers.\n"); 2930dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2931619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_NO_MEDIA) { 2932dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E12: Could not detect network connection.\n"); 2933dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2934619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_NO_RESPONSE) { 2935dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E16: No offer received.\n"); 2936dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2937619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_TIMEOUT) { 2938dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E18: Server response timeout.\n"); 2939dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2940619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_ABORTED) { 2941dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E21: Remote boot cancelled.\n"); 2942dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2943619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_ICMP_ERROR) { 2944dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E22: Client received ICMP error from server.\n"); 2945dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2946619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else if (Status == EFI_TFTP_ERROR) { 2947dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E23: Client received TFTP error from server.\n"); 2948dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2949619eff3f290c7e893d858c16e70b641471a5a704vanjeff } else { 2950dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff AsciiPrint ("PXE-E99: Unexpected network error.\n"); 2951dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff } 2952dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2953dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff PxeBc->Stop (PxeBc); 2954dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2955dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff return Status; 2956dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff} 2957dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff 2958434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeffEFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile }; 2959434ce3feca7f5a430db3d5853c54a06343d02ed2vanjeff 2960