]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c
NetworkPkg: Remove some clarification from UefiPxeBcDxe.inf
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcSupport.c
index dfc79a067b9b9572cff4c7f981b617de2e48a992..7ab09e0367058e163e37385cbc6b48401da81e25 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Support functions implementation for UefiPxeBc Driver.\r
 \r
 /** @file\r
   Support functions implementation for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -36,16 +36,18 @@ PxeBcFlushStationIp (
 {\r
   EFI_PXE_BASE_CODE_MODE   *Mode;\r
   EFI_STATUS               Status;\r
 {\r
   EFI_PXE_BASE_CODE_MODE   *Mode;\r
   EFI_STATUS               Status;\r
+  EFI_ARP_CONFIG_DATA      ArpConfigData;\r
 \r
   Mode   = Private->PxeBc.Mode;\r
   Status = EFI_SUCCESS;\r
 \r
   Mode   = Private->PxeBc.Mode;\r
   Status = EFI_SUCCESS;\r
+  ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));\r
 \r
 \r
-  if (Mode->UsingIpv6) {\r
-\r
-    if (StationIp != NULL) {\r
-      CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
-      CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
-    }\r
+  if (Mode->UsingIpv6 && StationIp != NULL) {\r
+    //\r
+    // Overwrite Udp6CfgData/Ip6CfgData StationAddress.\r
+    //\r
+    CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
+    CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
 \r
     //\r
     // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.\r
 \r
     //\r
     // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.\r
@@ -61,27 +63,55 @@ PxeBcFlushStationIp (
     Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);\r
   } else {\r
     if (StationIp != NULL) {\r
     Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);\r
   } else {\r
     if (StationIp != NULL) {\r
+      //\r
+      // Reconfigure the ARP instance with station Ip address.\r
+      //\r
+      ArpConfigData.SwAddressType   = 0x0800;\r
+      ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);\r
+      ArpConfigData.StationAddress = StationIp;\r
+\r
+      Private->Arp->Configure (Private->Arp, NULL);\r
+      Private->Arp->Configure (Private->Arp, &ArpConfigData);\r
+\r
+      //\r
+      // Overwrite Udp4CfgData/Ip4CfgData StationAddress.\r
+      //\r
       CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
       CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
-    \r
+\r
     if (SubnetMask != NULL) {\r
     if (SubnetMask != NULL) {\r
+      //\r
+      // Overwrite Udp4CfgData/Ip4CfgData SubnetMask.\r
+      //\r
       CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
 \r
       CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
 \r
-    //\r
-    // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
-    //\r
-    Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
-    Private->Ip4->Configure (Private->Ip4, NULL);\r
-\r
-    Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_EXIT;\r
+    if (StationIp != NULL && SubnetMask != NULL) {\r
+      //\r
+      // Updated the route table.\r
+      //\r
+      Mode->RouteTableEntries                = 1;\r
+      Mode->RouteTable[0].IpAddr.Addr[0]     = StationIp->Addr[0] & SubnetMask->Addr[0];\r
+      Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];\r
+      Mode->RouteTable[0].GwAddr.Addr[0]     = 0;\r
     }\r
 \r
     }\r
 \r
-    Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+    if (StationIp != NULL || SubnetMask != NULL) {\r
+      //\r
+      // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
+      //\r
+      Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
+      Private->Ip4->Configure (Private->Ip4, NULL);\r
+\r
+      Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+    }\r
   }\r
 \r
 ON_EXIT:\r
   }\r
 \r
 ON_EXIT:\r
@@ -257,8 +287,7 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&\r
   }\r
 \r
   if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&\r
@@ -268,25 +297,20 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {\r
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
   }\r
 \r
   if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {\r
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   }\r
 \r
-  if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) {\r
-    //\r
-    // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP.\r
-    //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
-  }\r
+  //\r
+  // The protocol has been configured to only receive ICMP packet.\r
+  //\r
+  ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);\r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
@@ -298,8 +322,7 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.\r
     //\r
     //\r
     // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
@@ -326,6 +349,9 @@ PxeBcIcmpErrorDpcHandle (
     IcmpError += CopiedLen;\r
   }\r
 \r
     IcmpError += CopiedLen;\r
   }\r
 \r
+ON_RECYCLE:\r
+  gBS->SignalEvent (RxData->RecycleSignal);\r
+\r
 ON_EXIT:\r
   Private->IcmpToken.Status = EFI_NOT_READY;\r
   Ip4->Receive (Ip4, &Private->IcmpToken);\r
 ON_EXIT:\r
   Private->IcmpToken.Status = EFI_NOT_READY;\r
   Ip4->Receive (Ip4, &Private->IcmpToken);\r
@@ -395,16 +421,14 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {\r
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
   }\r
 \r
   if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {\r
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&\r
   }\r
 \r
   if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&\r
@@ -412,17 +436,13 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   }\r
 \r
-  if (RxData->Header->NextHeader != IP6_ICMP) {\r
-    //\r
-    // The nextheader in the header of the receveid packet should be IP6_ICMP.\r
-    //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
-  }\r
+  //\r
+  // The protocol has been configured to only receive ICMP packet.\r
+  //\r
+  ASSERT (RxData->Header->NextHeader == IP6_ICMP);\r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
@@ -433,8 +453,7 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The type of the receveid packet should be an ICMP6 error message.\r
     //\r
     //\r
     // The type of the receveid packet should be an ICMP6 error message.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
@@ -461,6 +480,9 @@ PxeBcIcmp6ErrorDpcHandle (
     Icmp6Error += CopiedLen;\r
   }\r
 \r
     Icmp6Error += CopiedLen;\r
   }\r
 \r
+ON_RECYCLE:\r
+  gBS->SignalEvent (RxData->RecycleSignal);\r
+\r
 ON_EXIT:\r
   Private->Icmp6Token.Status = EFI_NOT_READY;\r
   Ip6->Receive (Ip6, &Private->Icmp6Token);\r
 ON_EXIT:\r
   Private->Icmp6Token.Status = EFI_NOT_READY;\r
   Ip6->Receive (Ip6, &Private->Icmp6Token);\r
@@ -495,7 +517,7 @@ PxeBcIcmp6ErrorUpdate (
   @param[in, out]  SrcPort              The pointer to the source port.\r
   @param[in]       DoNotFragment        If TRUE, fragment is not enabled.\r
                                         Otherwise, fragment is enabled.\r
   @param[in, out]  SrcPort              The pointer to the source port.\r
   @param[in]       DoNotFragment        If TRUE, fragment is not enabled.\r
                                         Otherwise, fragment is enabled.\r
-  @param[in]       Ttl                  The time to live field of the IP header. \r
+  @param[in]       Ttl                  The time to live field of the IP header.\r
   @param[in]       ToS                  The type of service field of the IP header.\r
 \r
   @retval          EFI_SUCCESS          Successfully configured this instance.\r
   @param[in]       ToS                  The type of service field of the IP header.\r
 \r
   @retval          EFI_SUCCESS          Successfully configured this instance.\r
@@ -1488,14 +1510,14 @@ CalcElapsedTime (
   //\r
   ZeroMem (&Time, sizeof (EFI_TIME));\r
   gRT->GetTime (&Time, NULL);\r
   //\r
   ZeroMem (&Time, sizeof (EFI_TIME));\r
   gRT->GetTime (&Time, NULL);\r
-  CurrentStamp = (UINT64)\r
-    (\r
-      ((((((Time.Year - 1900) * 360 +\r
-       (Time.Month - 1)) * 30 +\r
-       (Time.Day - 1)) * 24 + Time.Hour) * 60 +\r
-       Time.Minute) * 60 + Time.Second) * 100\r
-       + DivU64x32(Time.Nanosecond, 10000000)\r
-    );\r
+  CurrentStamp = MultU64x32 (\r
+                   ((((UINT32)(Time.Year - 1900) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,\r
+                   100\r
+                   ) +\r
+                 DivU64x32 (\r
+                   Time.Nanosecond,\r
+                   10000000\r
+                   );\r
 \r
   //\r
   // Sentinel value of 0 means that this is the first DHCP packet that we are\r
 \r
   //\r
   // Sentinel value of 0 means that this is the first DHCP packet that we are\r