X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcSupport.c;h=4b6f8c9c7feff899abe478e69962476b0d2f8790;hb=c455687fd0babe03a203b38c9a884c65198d8c1d;hp=dfc79a067b9b9572cff4c7f981b617de2e48a992;hpb=f8e13a24b7a19d0076ac6a9a621891f54128156b;p=mirror_edk2.git diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c index dfc79a067b..4b6f8c9c7f 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,17 +36,19 @@ 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; } + + 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->Receive (Private->Ip4, &Private->IcmpToken); + 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; - } - - 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; + 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); @@ -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);