123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539 |
- /** @file
- Support functions implementation for UefiPxeBc Driver.
- Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "PxeBcImpl.h"
- /**
- Flush the previous configuration using the new station Ip address.
- @param[in] Private The pointer to the PxeBc private data.
- @param[in] StationIp The pointer to the station Ip address.
- @param[in] SubnetMask The pointer to the subnet mask address for v4.
- @retval EFI_SUCCESS Successfully flushed the previous configuration.
- @retval Others Failed to flush using the new station Ip.
- **/
- EFI_STATUS
- PxeBcFlushStationIp (
- PXEBC_PRIVATE_DATA *Private,
- EFI_IP_ADDRESS *StationIp OPTIONAL,
- EFI_IP_ADDRESS *SubnetMask OPTIONAL
- )
- {
- EFI_PXE_BASE_CODE_MODE *Mode;
- EFI_STATUS Status;
- EFI_ARP_CONFIG_DATA ArpConfigData;
- Mode = Private->PxeBc.Mode;
- Status = EFI_SUCCESS;
- ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));
- if (Mode->UsingIpv6 && (StationIp != NULL)) {
- //
- // Overwrite Udp6CfgData/Ip6CfgData StationAddress.
- //
- CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
- CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
- //
- // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.
- //
- Private->Ip6->Cancel (Private->Ip6, &Private->Icmp6Token);
- Private->Ip6->Configure (Private->Ip6, NULL);
- Status = Private->Ip6->Configure (Private->Ip6, &Private->Ip6CfgData);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);
- } else {
- if (StationIp != NULL) {
- //
- // Reconfigure the ARP instance with station Ip address.
- //
- ArpConfigData.SwAddressType = 0x0800;
- ArpConfigData.SwAddressLength = (UINT8)sizeof (EFI_IPv4_ADDRESS);
- ArpConfigData.StationAddress = StationIp;
- Private->Arp->Configure (Private->Arp, NULL);
- Private->Arp->Configure (Private->Arp, &ArpConfigData);
- //
- // Overwrite Udp4CfgData/Ip4CfgData StationAddress.
- //
- CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
- }
- if (SubnetMask != NULL) {
- //
- // Overwrite Udp4CfgData/Ip4CfgData SubnetMask.
- //
- CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
- }
- if ((StationIp != NULL) && (SubnetMask != NULL)) {
- //
- // Updated the route table.
- //
- Mode->RouteTableEntries = 1;
- Mode->RouteTable[0].IpAddr.Addr[0] = StationIp->Addr[0] & SubnetMask->Addr[0];
- Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];
- Mode->RouteTable[0].GwAddr.Addr[0] = 0;
- }
- if ((StationIp != NULL) || (SubnetMask != NULL)) {
- //
- // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.
- //
- Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);
- Private->Ip4->Configure (Private->Ip4, NULL);
- Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);
- }
- }
- ON_EXIT:
- return Status;
- }
- /**
- Notify the callback function when an event is triggered.
- @param[in] Event The triggered event.
- @param[in] Context The opaque parameter to the function.
- **/
- VOID
- EFIAPI
- PxeBcCommonNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- *((BOOLEAN *)Context) = TRUE;
- }
- /**
- Do arp resolution from arp cache in PxeBcMode.
- @param Mode The pointer to EFI_PXE_BASE_CODE_MODE.
- @param Ip4Addr The Ip4 address for resolution.
- @param MacAddress The resolved MAC address if the resolution is successful.
- The value is undefined if the resolution fails.
- @retval TRUE Found an matched entry.
- @retval FALSE Did not find a matched entry.
- **/
- BOOLEAN
- PxeBcCheckArpCache (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN EFI_IPv4_ADDRESS *Ip4Addr,
- OUT EFI_MAC_ADDRESS *MacAddress
- )
- {
- UINT32 Index;
- ASSERT (!Mode->UsingIpv6);
- //
- // Check whether the current Arp cache in mode data contains this information or not.
- //
- for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
- if (EFI_IP4_EQUAL (&Mode->ArpCache[Index].IpAddr.v4, Ip4Addr)) {
- CopyMem (
- MacAddress,
- &Mode->ArpCache[Index].MacAddr,
- sizeof (EFI_MAC_ADDRESS)
- );
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- Update the arp cache periodically.
- @param Event The pointer to EFI_PXE_BC_PROTOCOL.
- @param Context Context of the timer event.
- **/
- VOID
- EFIAPI
- PxeBcArpCacheUpdate (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- PXEBC_PRIVATE_DATA *Private;
- EFI_PXE_BASE_CODE_MODE *Mode;
- EFI_ARP_FIND_DATA *ArpEntry;
- UINT32 EntryLength;
- UINT32 EntryCount;
- UINT32 Index;
- EFI_STATUS Status;
- Private = (PXEBC_PRIVATE_DATA *)Context;
- Mode = Private->PxeBc.Mode;
- ASSERT (!Mode->UsingIpv6);
- //
- // Get the current Arp cache from Arp driver.
- //
- Status = Private->Arp->Find (
- Private->Arp,
- TRUE,
- NULL,
- &EntryLength,
- &EntryCount,
- &ArpEntry,
- TRUE
- );
- if (EFI_ERROR (Status)) {
- return;
- }
- //
- // Update the Arp cache in mode data.
- //
- Mode->ArpCacheEntries = MIN (EntryCount, EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES);
- for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
- CopyMem (
- &Mode->ArpCache[Index].IpAddr,
- ArpEntry + 1,
- ArpEntry->SwAddressLength
- );
- CopyMem (
- &Mode->ArpCache[Index].MacAddr,
- (UINT8 *)(ArpEntry + 1) + ArpEntry->SwAddressLength,
- ArpEntry->HwAddressLength
- );
- ArpEntry = (EFI_ARP_FIND_DATA *)((UINT8 *)ArpEntry + EntryLength);
- }
- }
- /**
- Notify function to handle the received ICMP message in DPC.
- @param Context The PXEBC private data.
- **/
- VOID
- EFIAPI
- PxeBcIcmpErrorDpcHandle (
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- EFI_IP4_RECEIVE_DATA *RxData;
- EFI_IP4_PROTOCOL *Ip4;
- PXEBC_PRIVATE_DATA *Private;
- EFI_PXE_BASE_CODE_MODE *Mode;
- UINT8 Type;
- UINTN Index;
- UINT32 CopiedLen;
- UINT8 *IcmpError;
- Private = (PXEBC_PRIVATE_DATA *)Context;
- Mode = &Private->Mode;
- Status = Private->IcmpToken.Status;
- RxData = Private->IcmpToken.Packet.RxData;
- Ip4 = Private->Ip4;
- ASSERT (!Mode->UsingIpv6);
- if (Status == EFI_ABORTED) {
- //
- // It's triggered by user cancellation.
- //
- return;
- }
- if (RxData == NULL) {
- goto ON_EXIT;
- }
- if (Status != EFI_ICMP_ERROR) {
- //
- // The return status should be recognized as EFI_ICMP_ERROR.
- //
- goto ON_RECYCLE;
- }
- if ((EFI_IP4 (RxData->Header->SourceAddress) != 0) &&
- (NTOHL (Mode->SubnetMask.Addr[0]) != 0) &&
- IP4_NET_EQUAL (NTOHL (Mode->StationIp.Addr[0]), EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])) &&
- !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])))
- {
- //
- // The source address of the received packet should be a valid unicast address.
- //
- goto ON_RECYCLE;
- }
- if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {
- //
- // The destination address of the received packet should be equal to the host address.
- //
- goto ON_RECYCLE;
- }
- //
- // The protocol has been configured to only receive ICMP packet.
- //
- ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);
- Type = *((UINT8 *)RxData->FragmentTable[0].FragmentBuffer);
- if ((Type != ICMP_DEST_UNREACHABLE) &&
- (Type != ICMP_SOURCE_QUENCH) &&
- (Type != ICMP_REDIRECT) &&
- (Type != ICMP_TIME_EXCEEDED) &&
- (Type != ICMP_PARAMETER_PROBLEM))
- {
- //
- // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.
- //
- goto ON_RECYCLE;
- }
- //
- // Copy the right ICMP error message into mode data.
- //
- CopiedLen = 0;
- IcmpError = (UINT8 *)&Mode->IcmpError;
- for (Index = 0; Index < RxData->FragmentCount; Index++) {
- CopiedLen += RxData->FragmentTable[Index].FragmentLength;
- if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
- CopyMem (
- IcmpError,
- RxData->FragmentTable[Index].FragmentBuffer,
- RxData->FragmentTable[Index].FragmentLength
- );
- } else {
- CopyMem (
- IcmpError,
- RxData->FragmentTable[Index].FragmentBuffer,
- CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
- );
- }
- IcmpError += CopiedLen;
- }
- ON_RECYCLE:
- gBS->SignalEvent (RxData->RecycleSignal);
- ON_EXIT:
- Private->IcmpToken.Status = EFI_NOT_READY;
- Ip4->Receive (Ip4, &Private->IcmpToken);
- }
- /**
- Callback function to update the latest ICMP6 error message.
- @param Event The event signalled.
- @param Context The context passed in using the event notifier.
- **/
- VOID
- EFIAPI
- PxeBcIcmpErrorUpdate (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- QueueDpc (TPL_CALLBACK, PxeBcIcmpErrorDpcHandle, Context);
- }
- /**
- Notify function to handle the received ICMP6 message in DPC.
- @param Context The PXEBC private data.
- **/
- VOID
- EFIAPI
- PxeBcIcmp6ErrorDpcHandle (
- IN VOID *Context
- )
- {
- PXEBC_PRIVATE_DATA *Private;
- EFI_IP6_RECEIVE_DATA *RxData;
- EFI_IP6_PROTOCOL *Ip6;
- EFI_PXE_BASE_CODE_MODE *Mode;
- EFI_STATUS Status;
- UINTN Index;
- UINT8 Type;
- UINT32 CopiedLen;
- UINT8 *Icmp6Error;
- Private = (PXEBC_PRIVATE_DATA *)Context;
- Mode = &Private->Mode;
- Status = Private->Icmp6Token.Status;
- RxData = Private->Icmp6Token.Packet.RxData;
- Ip6 = Private->Ip6;
- ASSERT (Mode->UsingIpv6);
- if (Status == EFI_ABORTED) {
- //
- // It's triggered by user cancellation.
- //
- return;
- }
- if (RxData == NULL) {
- goto ON_EXIT;
- }
- if (Status != EFI_ICMP_ERROR) {
- //
- // The return status should be recognized as EFI_ICMP_ERROR.
- //
- goto ON_RECYCLE;
- }
- if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {
- //
- // The source address of the received packet should be a valid unicast address.
- //
- goto ON_RECYCLE;
- }
- if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&
- !EFI_IP6_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v6))
- {
- //
- // The destination address of the received packet should be equal to the host address.
- //
- goto ON_RECYCLE;
- }
- //
- // The protocol has been configured to only receive ICMP packet.
- //
- ASSERT (RxData->Header->NextHeader == IP6_ICMP);
- Type = *((UINT8 *)RxData->FragmentTable[0].FragmentBuffer);
- if ((Type != ICMP_V6_DEST_UNREACHABLE) &&
- (Type != ICMP_V6_PACKET_TOO_BIG) &&
- (Type != ICMP_V6_TIME_EXCEEDED) &&
- (Type != ICMP_V6_PARAMETER_PROBLEM))
- {
- //
- // The type of the receveid packet should be an ICMP6 error message.
- //
- goto ON_RECYCLE;
- }
- //
- // Copy the right ICMP6 error message into mode data.
- //
- CopiedLen = 0;
- Icmp6Error = (UINT8 *)&Mode->IcmpError;
- for (Index = 0; Index < RxData->FragmentCount; Index++) {
- CopiedLen += RxData->FragmentTable[Index].FragmentLength;
- if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
- CopyMem (
- Icmp6Error,
- RxData->FragmentTable[Index].FragmentBuffer,
- RxData->FragmentTable[Index].FragmentLength
- );
- } else {
- CopyMem (
- Icmp6Error,
- RxData->FragmentTable[Index].FragmentBuffer,
- CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
- );
- }
- Icmp6Error += CopiedLen;
- }
- ON_RECYCLE:
- gBS->SignalEvent (RxData->RecycleSignal);
- ON_EXIT:
- Private->Icmp6Token.Status = EFI_NOT_READY;
- Ip6->Receive (Ip6, &Private->Icmp6Token);
- }
- /**
- Callback function to update the latest ICMP6 error message.
- @param Event The event signalled.
- @param Context The context passed in using the event notifier.
- **/
- VOID
- EFIAPI
- PxeBcIcmp6ErrorUpdate (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- QueueDpc (TPL_CALLBACK, PxeBcIcmp6ErrorDpcHandle, Context);
- }
- /**
- This function is to configure a UDPv4 instance for UdpWrite.
- @param[in] Udp4 The pointer to EFI_UDP4_PROTOCOL.
- @param[in] StationIp The pointer to the station address.
- @param[in] SubnetMask The pointer to the subnet mask.
- @param[in] Gateway The pointer to the gateway address.
- @param[in, out] SrcPort The pointer to the source port.
- @param[in] DoNotFragment If TRUE, fragment is not enabled.
- Otherwise, fragment is enabled.
- @param[in] Ttl The time to live field of the IP header.
- @param[in] ToS The type of service field of the IP header.
- @retval EFI_SUCCESS Successfully configured this instance.
- @retval Others Failed to configure this instance.
- **/
- EFI_STATUS
- PxeBcConfigUdp4Write (
- IN EFI_UDP4_PROTOCOL *Udp4,
- IN EFI_IPv4_ADDRESS *StationIp,
- IN EFI_IPv4_ADDRESS *SubnetMask,
- IN EFI_IPv4_ADDRESS *Gateway,
- IN OUT UINT16 *SrcPort,
- IN BOOLEAN DoNotFragment,
- IN UINT8 Ttl,
- IN UINT8 ToS
- )
- {
- EFI_UDP4_CONFIG_DATA Udp4CfgData;
- EFI_STATUS Status;
- ZeroMem (&Udp4CfgData, sizeof (Udp4CfgData));
- Udp4CfgData.TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
- Udp4CfgData.ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
- Udp4CfgData.TypeOfService = ToS;
- Udp4CfgData.TimeToLive = Ttl;
- Udp4CfgData.AllowDuplicatePort = TRUE;
- Udp4CfgData.DoNotFragment = DoNotFragment;
- CopyMem (&Udp4CfgData.StationAddress, StationIp, sizeof (*StationIp));
- CopyMem (&Udp4CfgData.SubnetMask, SubnetMask, sizeof (*SubnetMask));
- Udp4CfgData.StationPort = *SrcPort;
- //
- // Reset the UDPv4 instance.
- //
- Udp4->Configure (Udp4, NULL);
- Status = Udp4->Configure (Udp4, &Udp4CfgData);
- if (!EFI_ERROR (Status) && !EFI_IP4_EQUAL (Gateway, &mZeroIp4Addr)) {
- //
- // The basic configuration is OK, need to add the default route entry
- //
- Status = Udp4->Routes (Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway);
- if (EFI_ERROR (Status)) {
- Udp4->Configure (Udp4, NULL);
- }
- }
- if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
- Udp4->GetModeData (Udp4, &Udp4CfgData, NULL, NULL, NULL);
- *SrcPort = Udp4CfgData.StationPort;
- }
- return Status;
- }
- /**
- This function is to configure a UDPv6 instance for UdpWrite.
- @param[in] Udp6 The pointer to EFI_UDP6_PROTOCOL.
- @param[in] StationIp The pointer to the station address.
- @param[in, out] SrcPort The pointer to the source port.
- @retval EFI_SUCCESS Successfully configured this instance.
- @retval Others Failed to configure this instance.
- **/
- EFI_STATUS
- PxeBcConfigUdp6Write (
- IN EFI_UDP6_PROTOCOL *Udp6,
- IN EFI_IPv6_ADDRESS *StationIp,
- IN OUT UINT16 *SrcPort
- )
- {
- EFI_UDP6_CONFIG_DATA CfgData;
- EFI_STATUS Status;
- ZeroMem (&CfgData, sizeof (EFI_UDP6_CONFIG_DATA));
- CfgData.ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
- CfgData.TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
- CfgData.HopLimit = PXEBC_DEFAULT_HOPLIMIT;
- CfgData.AllowDuplicatePort = TRUE;
- CfgData.StationPort = *SrcPort;
- CopyMem (&CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
- //
- // Reset the UDPv6 instance.
- //
- Udp6->Configure (Udp6, NULL);
- Status = Udp6->Configure (Udp6, &CfgData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
- Udp6->GetModeData (Udp6, &CfgData, NULL, NULL, NULL);
- *SrcPort = CfgData.StationPort;
- }
- return Status;
- }
- /**
- This function is to configure a UDPv4 instance for UdpWrite.
- @param[in] Udp4 The pointer to EFI_UDP4_PROTOCOL.
- @param[in] Session The pointer to the UDP4 session data.
- @param[in] TimeoutEvent The event for timeout.
- @param[in] Gateway The pointer to the gateway address.
- @param[in] HeaderSize An optional field which may be set to the length of a header
- at HeaderPtr to be prefixed to the data at BufferPtr.
- @param[in] HeaderPtr If HeaderSize is not NULL, a pointer to a header to be
- prefixed to the data at BufferPtr.
- @param[in] BufferSize A pointer to the size of the data at BufferPtr.
- @param[in] BufferPtr A pointer to the data to be written.
- @retval EFI_SUCCESS Successfully send out data using Udp4Write.
- @retval Others Failed to send out data.
- **/
- EFI_STATUS
- PxeBcUdp4Write (
- IN EFI_UDP4_PROTOCOL *Udp4,
- IN EFI_UDP4_SESSION_DATA *Session,
- IN EFI_EVENT TimeoutEvent,
- IN EFI_IPv4_ADDRESS *Gateway OPTIONAL,
- IN UINTN *HeaderSize OPTIONAL,
- IN VOID *HeaderPtr OPTIONAL,
- IN UINTN *BufferSize,
- IN VOID *BufferPtr
- )
- {
- EFI_UDP4_COMPLETION_TOKEN Token;
- EFI_UDP4_TRANSMIT_DATA *TxData;
- UINT32 TxLength;
- UINT32 FragCount;
- UINT32 DataLength;
- BOOLEAN IsDone;
- EFI_STATUS Status;
- //
- // Arrange one fragment buffer for data, and another fragment buffer for header if has.
- //
- FragCount = (HeaderSize != NULL) ? 2 : 1;
- TxLength = sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA);
- TxData = (EFI_UDP4_TRANSMIT_DATA *)AllocateZeroPool (TxLength);
- if (TxData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- TxData->FragmentCount = FragCount;
- TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32)*BufferSize;
- TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
- DataLength = (UINT32)*BufferSize;
- if (HeaderSize != NULL) {
- TxData->FragmentTable[0].FragmentLength = (UINT32)*HeaderSize;
- TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
- DataLength += (UINT32)*HeaderSize;
- }
- if (Gateway != NULL) {
- TxData->GatewayAddress = Gateway;
- }
- TxData->UdpSessionData = Session;
- TxData->DataLength = DataLength;
- Token.Packet.TxData = TxData;
- Token.Status = EFI_NOT_READY;
- IsDone = FALSE;
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- PxeBcCommonNotify,
- &IsDone,
- &Token.Event
- );
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- Status = Udp4->Transmit (Udp4, &Token);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- //
- // Poll the UDPv6 read instance if no packet received and no timeout triggered.
- //
- while (!IsDone &&
- Token.Status == EFI_NOT_READY &&
- EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
- {
- Udp4->Poll (Udp4);
- }
- Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;
- ON_EXIT:
- if (Token.Event != NULL) {
- gBS->CloseEvent (Token.Event);
- }
- FreePool (TxData);
- return Status;
- }
- /**
- This function is to configure a UDPv4 instance for UdpWrite.
- @param[in] Udp6 The pointer to EFI_UDP6_PROTOCOL.
- @param[in] Session The pointer to the UDP6 session data.
- @param[in] TimeoutEvent The event for timeout.
- @param[in] HeaderSize An optional field which may be set to the length of a header
- at HeaderPtr to be prefixed to the data at BufferPtr.
- @param[in] HeaderPtr If HeaderSize is not NULL, a pointer to a header to be
- prefixed to the data at BufferPtr.
- @param[in] BufferSize A pointer to the size of the data at BufferPtr.
- @param[in] BufferPtr A pointer to the data to be written.
- @retval EFI_SUCCESS Successfully sent out data using Udp6Write.
- @retval Others Failed to send out data.
- **/
- EFI_STATUS
- PxeBcUdp6Write (
- IN EFI_UDP6_PROTOCOL *Udp6,
- IN EFI_UDP6_SESSION_DATA *Session,
- IN EFI_EVENT TimeoutEvent,
- IN UINTN *HeaderSize OPTIONAL,
- IN VOID *HeaderPtr OPTIONAL,
- IN UINTN *BufferSize,
- IN VOID *BufferPtr
- )
- {
- EFI_UDP6_COMPLETION_TOKEN Token;
- EFI_UDP6_TRANSMIT_DATA *TxData;
- UINT32 TxLength;
- UINT32 FragCount;
- UINT32 DataLength;
- BOOLEAN IsDone;
- EFI_STATUS Status;
- //
- // Arrange one fragment buffer for data, and another fragment buffer for header if has.
- //
- FragCount = (HeaderSize != NULL) ? 2 : 1;
- TxLength = sizeof (EFI_UDP6_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP6_FRAGMENT_DATA);
- TxData = (EFI_UDP6_TRANSMIT_DATA *)AllocateZeroPool (TxLength);
- if (TxData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- TxData->FragmentCount = FragCount;
- TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32)*BufferSize;
- TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
- DataLength = (UINT32)*BufferSize;
- if (HeaderSize != NULL) {
- TxData->FragmentTable[0].FragmentLength = (UINT32)*HeaderSize;
- TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
- DataLength += (UINT32)*HeaderSize;
- }
- TxData->UdpSessionData = Session;
- TxData->DataLength = DataLength;
- Token.Packet.TxData = TxData;
- Token.Status = EFI_NOT_READY;
- IsDone = FALSE;
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- PxeBcCommonNotify,
- &IsDone,
- &Token.Event
- );
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- Status = Udp6->Transmit (Udp6, &Token);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- //
- // Poll the UDPv6 read instance if no packet received and no timeout triggered.
- //
- while (!IsDone &&
- Token.Status == EFI_NOT_READY &&
- EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
- {
- Udp6->Poll (Udp6);
- }
- Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;
- ON_EXIT:
- if (Token.Event != NULL) {
- gBS->CloseEvent (Token.Event);
- }
- FreePool (TxData);
- return Status;
- }
- /**
- Check the received packet using the Ip filter.
- @param[in] Mode The pointer to the mode data of PxeBc.
- @param[in] Session The pointer to the current UDPv4 session.
- @param[in] OpFlags Operation flag for UdpRead/UdpWrite.
- @retval TRUE Passed the Ip filter successfully.
- @retval FALSE Failed to pass the Ip filter.
- **/
- BOOLEAN
- PxeBcCheckByIpFilter (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN VOID *Session,
- IN UINT16 OpFlags
- )
- {
- EFI_IP_ADDRESS DestinationIp;
- UINTN Index;
- if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) == 0) {
- return TRUE;
- }
- if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0) {
- return TRUE;
- }
- //
- // Convert the destination address in session data to host order.
- //
- if (Mode->UsingIpv6) {
- CopyMem (
- &DestinationIp,
- &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress,
- sizeof (EFI_IPv6_ADDRESS)
- );
- NTOHLLL (&DestinationIp.v6);
- } else {
- ZeroMem (&DestinationIp, sizeof (EFI_IP_ADDRESS));
- CopyMem (
- &DestinationIp,
- &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress,
- sizeof (EFI_IPv4_ADDRESS)
- );
- EFI_NTOHL (DestinationIp);
- }
- if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0) &&
- (IP4_IS_MULTICAST (DestinationIp.Addr[0]) ||
- IP6_IS_MULTICAST (&DestinationIp)))
- {
- return TRUE;
- }
- if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) &&
- IP4_IS_LOCAL_BROADCAST (DestinationIp.Addr[0]))
- {
- ASSERT (!Mode->UsingIpv6);
- return TRUE;
- }
- if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) &&
- (EFI_IP4_EQUAL (&Mode->StationIp.v4, &DestinationIp) ||
- EFI_IP6_EQUAL (&Mode->StationIp.v6, &DestinationIp)))
- {
- //
- // Matched if the dest address is equal to the station address.
- //
- return TRUE;
- }
- for (Index = 0; Index < Mode->IpFilter.IpCnt; Index++) {
- ASSERT (Index < EFI_PXE_BASE_CODE_MAX_IPCNT);
- if (EFI_IP4_EQUAL (&Mode->IpFilter.IpList[Index].v4, &DestinationIp) ||
- EFI_IP6_EQUAL (&Mode->IpFilter.IpList[Index].v6, &DestinationIp))
- {
- //
- // Matched if the dest address is equal to any of address in the filter list.
- //
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- Filter the received packet using the destination Ip.
- @param[in] Mode The pointer to the mode data of PxeBc.
- @param[in] Session The pointer to the current UDPv4 session.
- @param[in, out] DestIp The pointer to the destination Ip address.
- @param[in] OpFlags Operation flag for UdpRead/UdpWrite.
- @retval TRUE Passed the IPv4 filter successfully.
- @retval FALSE Failed to pass the IPv4 filter.
- **/
- BOOLEAN
- PxeBcCheckByDestIp (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN VOID *Session,
- IN OUT EFI_IP_ADDRESS *DestIp,
- IN UINT16 OpFlags
- )
- {
- if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) != 0) {
- //
- // Copy the destination address from the received packet if accept any.
- //
- if (DestIp != NULL) {
- if (Mode->UsingIpv6) {
- CopyMem (
- DestIp,
- &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress,
- sizeof (EFI_IPv6_ADDRESS)
- );
- } else {
- ZeroMem (DestIp, sizeof (EFI_IP_ADDRESS));
- CopyMem (
- DestIp,
- &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress,
- sizeof (EFI_IPv4_ADDRESS)
- );
- }
- }
- return TRUE;
- } else if ((DestIp != NULL) &&
- (EFI_IP4_EQUAL (DestIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
- EFI_IP6_EQUAL (DestIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress)))
- {
- //
- // The destination address in the received packet is matched if present.
- //
- return TRUE;
- } else if (EFI_IP4_EQUAL (&Mode->StationIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
- EFI_IP6_EQUAL (&Mode->StationIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress))
- {
- //
- // The destination address in the received packet is equal to the host address.
- //
- return TRUE;
- }
- return FALSE;
- }
- /**
- Check the received packet using the destination port.
- @param[in] Mode The pointer to the mode data of PxeBc.
- @param[in] Session The pointer to the current UDPv4 session.
- @param[in, out] DestPort The pointer to the destination port.
- @param[in] OpFlags Operation flag for UdpRead/UdpWrite.
- @retval TRUE Passed the IPv4 filter successfully.
- @retval FALSE Failed to pass the IPv4 filter.
- **/
- BOOLEAN
- PxeBcCheckByDestPort (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN VOID *Session,
- IN OUT UINT16 *DestPort,
- IN UINT16 OpFlags
- )
- {
- UINT16 Port;
- if (Mode->UsingIpv6) {
- Port = ((EFI_UDP6_SESSION_DATA *)Session)->DestinationPort;
- } else {
- Port = ((EFI_UDP4_SESSION_DATA *)Session)->DestinationPort;
- }
- if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) != 0) {
- //
- // Return the destination port in the received packet if accept any.
- //
- if (DestPort != NULL) {
- *DestPort = Port;
- }
- return TRUE;
- } else if ((DestPort != NULL) && (*DestPort == Port)) {
- //
- // The destination port in the received packet is matched if present.
- //
- return TRUE;
- }
- return FALSE;
- }
- /**
- Filter the received packet using the source Ip.
- @param[in] Mode The pointer to the mode data of PxeBc.
- @param[in] Session The pointer to the current UDPv4 session.
- @param[in, out] SrcIp The pointer to the source Ip address.
- @param[in] OpFlags Operation flag for UdpRead/UdpWrite.
- @retval TRUE Passed the IPv4 filter successfully.
- @retval FALSE Failed to pass the IPv4 filter.
- **/
- BOOLEAN
- PxeBcFilterBySrcIp (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN VOID *Session,
- IN OUT EFI_IP_ADDRESS *SrcIp,
- IN UINT16 OpFlags
- )
- {
- if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) != 0) {
- //
- // Copy the source address from the received packet if accept any.
- //
- if (SrcIp != NULL) {
- if (Mode->UsingIpv6) {
- CopyMem (
- SrcIp,
- &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress,
- sizeof (EFI_IPv6_ADDRESS)
- );
- } else {
- ZeroMem (SrcIp, sizeof (EFI_IP_ADDRESS));
- CopyMem (
- SrcIp,
- &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress,
- sizeof (EFI_IPv4_ADDRESS)
- );
- }
- }
- return TRUE;
- } else if ((SrcIp != NULL) &&
- (EFI_IP4_EQUAL (SrcIp, &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress) ||
- EFI_IP6_EQUAL (SrcIp, &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress)))
- {
- //
- // The source address in the received packet is matched if present.
- //
- return TRUE;
- }
- return FALSE;
- }
- /**
- Filter the received packet using the source port.
- @param[in] Mode The pointer to the mode data of PxeBc.
- @param[in] Session The pointer to the current UDPv4 session.
- @param[in, out] SrcPort The pointer to the source port.
- @param[in] OpFlags Operation flag for UdpRead/UdpWrite.
- @retval TRUE Passed the IPv4 filter successfully.
- @retval FALSE Failed to pass the IPv4 filter.
- **/
- BOOLEAN
- PxeBcFilterBySrcPort (
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN VOID *Session,
- IN OUT UINT16 *SrcPort,
- IN UINT16 OpFlags
- )
- {
- UINT16 Port;
- if (Mode->UsingIpv6) {
- Port = ((EFI_UDP6_SESSION_DATA *)Session)->SourcePort;
- } else {
- Port = ((EFI_UDP4_SESSION_DATA *)Session)->SourcePort;
- }
- if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) != 0) {
- //
- // Return the source port in the received packet if accept any.
- //
- if (SrcPort != NULL) {
- *SrcPort = Port;
- }
- return TRUE;
- } else if ((SrcPort != NULL) && (*SrcPort == Port)) {
- //
- // The source port in the received packet is matched if present.
- //
- return TRUE;
- }
- return FALSE;
- }
- /**
- This function is to receive packet using Udp4Read.
- @param[in] Udp4 The pointer to EFI_UDP4_PROTOCOL.
- @param[in] Token The pointer to EFI_UDP4_COMPLETION_TOKEN.
- @param[in] Mode The pointer to EFI_PXE_BASE_CODE_MODE.
- @param[in] TimeoutEvent The event for timeout.
- @param[in] OpFlags The UDP operation flags.
- @param[in] IsDone The pointer to the IsDone flag.
- @param[out] IsMatched The pointer to the IsMatched flag.
- @param[in, out] DestIp The pointer to the destination address.
- @param[in, out] DestPort The pointer to the destination port.
- @param[in, out] SrcIp The pointer to the source address.
- @param[in, out] SrcPort The pointer to the source port.
- @retval EFI_SUCCESS Successfully read the data using Udp4.
- @retval Others Failed to send out data.
- **/
- EFI_STATUS
- PxeBcUdp4Read (
- IN EFI_UDP4_PROTOCOL *Udp4,
- IN EFI_UDP4_COMPLETION_TOKEN *Token,
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN EFI_EVENT TimeoutEvent,
- IN UINT16 OpFlags,
- IN BOOLEAN *IsDone,
- OUT BOOLEAN *IsMatched,
- IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL,
- IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL,
- IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL,
- IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL
- )
- {
- EFI_UDP4_RECEIVE_DATA *RxData;
- EFI_UDP4_SESSION_DATA *Session;
- EFI_STATUS Status;
- Token->Status = EFI_NOT_READY;
- *IsDone = FALSE;
- Status = Udp4->Receive (Udp4, Token);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Poll the UDPv6 read instance if no packet received and no timeout triggered.
- //
- while (!(*IsDone) &&
- Token->Status == EFI_NOT_READY &&
- EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
- {
- //
- // Poll the token until reply/ICMPv6 error message received or timeout.
- //
- Udp4->Poll (Udp4);
- if ((Token->Status == EFI_ICMP_ERROR) ||
- (Token->Status == EFI_NETWORK_UNREACHABLE) ||
- (Token->Status == EFI_HOST_UNREACHABLE) ||
- (Token->Status == EFI_PROTOCOL_UNREACHABLE) ||
- (Token->Status == EFI_PORT_UNREACHABLE))
- {
- break;
- }
- }
- Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;
- if (!EFI_ERROR (Status)) {
- //
- // check whether this packet matches the filters
- //
- RxData = Token->Packet.RxData;
- Session = &RxData->UdpSession;
- *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);
- if (*IsMatched) {
- *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
- }
- if (!(*IsMatched)) {
- //
- // Recycle the receiving buffer if not matched.
- //
- gBS->SignalEvent (RxData->RecycleSignal);
- }
- }
- return Status;
- }
- /**
- This function is to receive packets using Udp6Read.
- @param[in] Udp6 The pointer to EFI_UDP6_PROTOCOL.
- @param[in] Token The pointer to EFI_UDP6_COMPLETION_TOKEN.
- @param[in] Mode The pointer to EFI_PXE_BASE_CODE_MODE.
- @param[in] TimeoutEvent The event for timeout.
- @param[in] OpFlags The UDP operation flags.
- @param[in] IsDone The pointer to the IsDone flag.
- @param[out] IsMatched The pointer to the IsMatched flag.
- @param[in, out] DestIp The pointer to the destination address.
- @param[in, out] DestPort The pointer to the destination port.
- @param[in, out] SrcIp The pointer to the source address.
- @param[in, out] SrcPort The pointer to the source port.
- @retval EFI_SUCCESS Successfully read data using Udp6.
- @retval Others Failed to send out data.
- **/
- EFI_STATUS
- PxeBcUdp6Read (
- IN EFI_UDP6_PROTOCOL *Udp6,
- IN EFI_UDP6_COMPLETION_TOKEN *Token,
- IN EFI_PXE_BASE_CODE_MODE *Mode,
- IN EFI_EVENT TimeoutEvent,
- IN UINT16 OpFlags,
- IN BOOLEAN *IsDone,
- OUT BOOLEAN *IsMatched,
- IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL,
- IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL,
- IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL,
- IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL
- )
- {
- EFI_UDP6_RECEIVE_DATA *RxData;
- EFI_UDP6_SESSION_DATA *Session;
- EFI_STATUS Status;
- Token->Status = EFI_NOT_READY;
- *IsDone = FALSE;
- Status = Udp6->Receive (Udp6, Token);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Poll the UDPv6 read instance if no packet received and no timeout triggered.
- //
- while (!(*IsDone) &&
- Token->Status == EFI_NOT_READY &&
- EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
- {
- //
- // Poll the token until reply/ICMPv6 error message received or timeout.
- //
- Udp6->Poll (Udp6);
- if ((Token->Status == EFI_ICMP_ERROR) ||
- (Token->Status == EFI_NETWORK_UNREACHABLE) ||
- (Token->Status == EFI_HOST_UNREACHABLE) ||
- (Token->Status == EFI_PROTOCOL_UNREACHABLE) ||
- (Token->Status == EFI_PORT_UNREACHABLE))
- {
- break;
- }
- }
- Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;
- if (!EFI_ERROR (Status)) {
- //
- // check whether this packet matches the filters
- //
- RxData = Token->Packet.RxData;
- Session = &RxData->UdpSession;
- *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);
- if (*IsMatched) {
- *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
- }
- if (*IsMatched) {
- *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
- }
- if (!(*IsMatched)) {
- //
- // Recycle the receiving buffer if not matched.
- //
- gBS->SignalEvent (RxData->RecycleSignal);
- }
- }
- return Status;
- }
- /**
- This function is to display the IPv4 address.
- @param[in] Ip The pointer to the IPv4 address.
- **/
- VOID
- PxeBcShowIp4Addr (
- IN EFI_IPv4_ADDRESS *Ip
- )
- {
- UINTN Index;
- for (Index = 0; Index < 4; Index++) {
- AsciiPrint ("%d", Ip->Addr[Index]);
- if (Index < 3) {
- AsciiPrint (".");
- }
- }
- }
- /**
- This function is to display the IPv6 address.
- @param[in] Ip The pointer to the IPv6 address.
- **/
- VOID
- PxeBcShowIp6Addr (
- IN EFI_IPv6_ADDRESS *Ip
- )
- {
- UINTN Index;
- for (Index = 0; Index < 16; Index++) {
- if (Ip->Addr[Index] != 0) {
- AsciiPrint ("%x", Ip->Addr[Index]);
- }
- Index++;
- if (Index > 15) {
- return;
- }
- if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
- AsciiPrint ("0");
- }
- AsciiPrint ("%x", Ip->Addr[Index]);
- if (Index < 15) {
- AsciiPrint (":");
- }
- }
- }
- /**
- This function is to convert UINTN to ASCII string with the required formatting.
- @param[in] Number Numeric value to be converted.
- @param[in] Buffer The pointer to the buffer for ASCII string.
- @param[in] Length The length of the required format.
- **/
- VOID
- PxeBcUintnToAscDecWithFormat (
- IN UINTN Number,
- IN UINT8 *Buffer,
- IN INTN Length
- )
- {
- UINTN Remainder;
- for ( ; Length > 0; Length--) {
- Remainder = Number % 10;
- Number /= 10;
- Buffer[Length - 1] = (UINT8)('0' + Remainder);
- }
- }
- /**
- This function is to convert a UINTN to a ASCII string, and return the
- actual length of the buffer.
- @param[in] Number Numeric value to be converted.
- @param[in] Buffer The pointer to the buffer for ASCII string.
- @param[in] BufferSize The maxsize of the buffer.
- @return Length The actual length of the ASCII string.
- **/
- UINTN
- PxeBcUintnToAscDec (
- IN UINTN Number,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
- )
- {
- UINTN Index;
- UINTN Length;
- CHAR8 TempStr[64];
- Index = 63;
- TempStr[Index] = 0;
- do {
- Index--;
- TempStr[Index] = (CHAR8)('0' + (Number % 10));
- Number = (UINTN)(Number / 10);
- } while (Number != 0);
- AsciiStrCpyS ((CHAR8 *)Buffer, BufferSize, &TempStr[Index]);
- Length = AsciiStrLen ((CHAR8 *)Buffer);
- return Length;
- }
- /**
- This function is to convert unicode hex number to a UINT8.
- @param[out] Digit The converted UINT8 for output.
- @param[in] Char The unicode hex number to be converted.
- @retval EFI_SUCCESS Successfully converted the unicode hex.
- @retval EFI_INVALID_PARAMETER Failed to convert the unicode hex.
- **/
- EFI_STATUS
- PxeBcUniHexToUint8 (
- OUT UINT8 *Digit,
- IN CHAR16 Char
- )
- {
- if ((Char >= L'0') && (Char <= L'9')) {
- *Digit = (UINT8)(Char - L'0');
- return EFI_SUCCESS;
- }
- if ((Char >= L'A') && (Char <= L'F')) {
- *Digit = (UINT8)(Char - L'A' + 0x0A);
- return EFI_SUCCESS;
- }
- if ((Char >= L'a') && (Char <= L'f')) {
- *Digit = (UINT8)(Char - L'a' + 0x0A);
- return EFI_SUCCESS;
- }
- return EFI_INVALID_PARAMETER;
- }
- /**
- Calculate the elapsed time.
- @param[in] Private The pointer to PXE private data
- **/
- VOID
- CalcElapsedTime (
- IN PXEBC_PRIVATE_DATA *Private
- )
- {
- EFI_TIME Time;
- UINT64 CurrentStamp;
- UINT64 ElapsedTimeValue;
- //
- // Generate a time stamp of the centiseconds from 1900/1/1, assume 30day/month.
- //
- ZeroMem (&Time, sizeof (EFI_TIME));
- gRT->GetTime (&Time, NULL);
- CurrentStamp = MultU64x32 (
- ((((UINT32)(Time.Year - 1900) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,
- 100
- ) +
- DivU64x32 (
- Time.Nanosecond,
- 10000000
- );
- //
- // Sentinel value of 0 means that this is the first DHCP packet that we are
- // sending and that we need to initialize the value. First DHCP Solicit
- // gets 0 elapsed-time. Otherwise, calculate based on StartTime.
- //
- if (Private->ElapsedTime == 0) {
- Private->ElapsedTime = CurrentStamp;
- } else {
- ElapsedTimeValue = CurrentStamp - Private->ElapsedTime;
- //
- // If elapsed time cannot fit in two bytes, set it to 0xffff.
- //
- if (ElapsedTimeValue > 0xffff) {
- ElapsedTimeValue = 0xffff;
- }
- //
- // Save the elapsed time
- //
- Private->ElapsedTime = ElapsedTimeValue;
- }
- }
|