X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcSupport.c;h=7ab09e0367058e163e37385cbc6b48401da81e25;hb=a1b7461db369a013ce9d766583e2b11a0efc0787;hp=dfc79a067b9b9572cff4c7f981b617de2e48a992;hpb=f8e13a24b7a19d0076ac6a9a621891f54128156b;p=mirror_edk2.git diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c index dfc79a067b..7ab09e0367 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c @@ -1,7 +1,7 @@ /** @file Support functions implementation for UefiPxeBc Driver. - Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -36,16 +36,18 @@ PxeBcFlushStationIp ( { 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) { - - if (StationIp != NULL) { - CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS)); - CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS)); - } + 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. @@ -61,27 +63,55 @@ PxeBcFlushStationIp ( 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)); } - // - // 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; + 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; } - Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken); + 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: @@ -257,8 +287,7 @@ PxeBcIcmpErrorDpcHandle ( // // The return status should be recognized as EFI_ICMP_ERROR. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } if (EFI_IP4 (RxData->Header->SourceAddress) != 0 && @@ -268,25 +297,20 @@ PxeBcIcmpErrorDpcHandle ( // // The source address of the received packet should be a valid unicast address. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + 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. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } - if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) { - // - // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP. - // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; - } + // + // The protocol has been configured to only receive ICMP packet. + // + ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP); Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer); @@ -298,8 +322,7 @@ PxeBcIcmpErrorDpcHandle ( // // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } // @@ -326,6 +349,9 @@ PxeBcIcmpErrorDpcHandle ( IcmpError += CopiedLen; } +ON_RECYCLE: + gBS->SignalEvent (RxData->RecycleSignal); + ON_EXIT: Private->IcmpToken.Status = EFI_NOT_READY; Ip4->Receive (Ip4, &Private->IcmpToken); @@ -395,16 +421,14 @@ PxeBcIcmp6ErrorDpcHandle ( // // The return status should be recognized as EFI_ICMP_ERROR. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) { // // The source address of the received packet should be a valid unicast address. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) && @@ -412,17 +436,13 @@ PxeBcIcmp6ErrorDpcHandle ( // // The destination address of the received packet should be equal to the host address. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } - if (RxData->Header->NextHeader != IP6_ICMP) { - // - // The nextheader in the header of the receveid packet should be IP6_ICMP. - // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; - } + // + // The protocol has been configured to only receive ICMP packet. + // + ASSERT (RxData->Header->NextHeader == IP6_ICMP); Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer); @@ -433,8 +453,7 @@ PxeBcIcmp6ErrorDpcHandle ( // // The type of the receveid packet should be an ICMP6 error message. // - gBS->SignalEvent (RxData->RecycleSignal); - goto ON_EXIT; + goto ON_RECYCLE; } // @@ -461,6 +480,9 @@ PxeBcIcmp6ErrorDpcHandle ( Icmp6Error += CopiedLen; } +ON_RECYCLE: + gBS->SignalEvent (RxData->RecycleSignal); + ON_EXIT: Private->Icmp6Token.Status = EFI_NOT_READY; Ip6->Receive (Ip6, &Private->Icmp6Token); @@ -495,7 +517,7 @@ PxeBcIcmp6ErrorUpdate ( @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] 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. @@ -1488,14 +1510,14 @@ CalcElapsedTime ( // ZeroMem (&Time, sizeof (EFI_TIME)); gRT->GetTime (&Time, NULL); - CurrentStamp = (UINT64) - ( - ((((((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) - ); + 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