]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
Use siaddr in DHCP packet, if zero, use option 54 instead.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcDhcp.c
index db19d15ead436bfa22c26cc1b4f74626ae7e4c8a..5e86cf5779e6cc10e2789bc221dcaaad79820c5e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Support for PxeBc dhcp functions.\r
   \r
-Copyright (c) 2007 - 2008, Intel Corporation.<BR>                                                         \r
+Copyright (c) 2007 - 2009, Intel Corporation.<BR>                                                         \r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -37,8 +37,6 @@ UINT8 mInterestedDhcp4Tags[PXEBC_DHCP4_TAG_INDEX_MAX] = {
   @param  Seed    Pointer to the message instance of the DHCP4 packet.\r
   @param  Udp4    Pointer to the EFI_UDP4_PROTOCOL instance.\r
 \r
-  @return none.\r
-\r
 **/\r
 VOID\r
 PxeBcInitSeedPacket (\r
@@ -73,8 +71,6 @@ PxeBcInitSeedPacket (
   @param  Dst   Pointer to the EFI_DHCP4_PROTOCOL instance.\r
   @param  Src   Pointer to the EFI_DHCP4_PROTOCOL instance.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 PxeBcCopyEfiDhcp4Packet (\r
@@ -96,8 +92,6 @@ PxeBcCopyEfiDhcp4Packet (
   @param  OfferIndex    Index of cached packets as complements of pxe mode data,\r
                         the index is maximum offer number.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 PxeBcCopyProxyOffer (\r
@@ -109,6 +103,7 @@ PxeBcCopyProxyOffer (
   EFI_DHCP4_PACKET        *Offer;\r
 \r
   ASSERT (OfferIndex < Private->NumOffers);\r
+  ASSERT (OfferIndex < PXEBC_MAX_OFFER_NUM);\r
 \r
   Mode  = Private->PxeBc.Mode;\r
   Offer = &Private->Dhcp4Offers[OfferIndex].Packet.Offer;\r
@@ -274,23 +269,31 @@ PxeBcTryBinl (
   PXEBC_CACHED_DHCP4_PACKET *CachedPacket;\r
   EFI_DHCP4_PACKET          *Reply;\r
 \r
+  ASSERT (Index < PXEBC_MAX_OFFER_NUM);\r
   ASSERT (Private->Dhcp4Offers[Index].OfferType == DHCP4_PACKET_TYPE_BINL);\r
 \r
   Offer = &Private->Dhcp4Offers[Index].Packet.Offer;\r
-  if (Offer->Dhcp4.Header.ServerAddr.Addr[0] == 0) {\r
-    //\r
-    // next server ip address is zero, use server id option instead.\r
-    //\r
+\r
+  //\r
+  // Use siaddr(next server) in DHCPOFFER packet header, if zero, use option 54(server identifier)\r
+  // in DHCPOFFER packet.\r
+  // (It does not comply with PXE Spec, Ver2.1)\r
+  //\r
+  if (EFI_IP4_EQUAL (&Offer->Dhcp4.Header.ServerAddr.Addr, &mZeroIp4Addr)) {\r
     CopyMem (\r
       &ServerIp.Addr[0],\r
       Private->Dhcp4Offers[Index].Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,\r
       sizeof (EFI_IPv4_ADDRESS)\r
       );\r
   } else {\r
-    //\r
-    // use next server ip address.\r
-    //\r
-    CopyMem (&ServerIp.Addr[0], &Offer->Dhcp4.Header.ServerAddr, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (\r
+      &ServerIp.Addr[0], \r
+      &Offer->Dhcp4.Header.ServerAddr, \r
+      sizeof (EFI_IPv4_ADDRESS)\r
+      );\r
+  }\r
+  if (ServerIp.Addr[0] == 0) {\r
+    return FALSE;\r
   }\r
 \r
   CachedPacket = &Private->ProxyOffer;\r
@@ -525,8 +528,6 @@ PxeBcCheckSelectedOffer (
   @param  Private    Pointer to PxeBc private data.\r
   @param  RcvdOffer  Pointer to the received Dhcp proxy offer packet.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 PxeBcCacheDhcpOffer (\r
@@ -554,6 +555,7 @@ PxeBcCacheDhcpOffer (
   }\r
 \r
   OfferType = CachedOffer->OfferType;\r
+  ASSERT (OfferType < DHCP4_PACKET_TYPE_MAX);\r
 \r
   if (OfferType == DHCP4_PACKET_TYPE_BOOTP) {\r
 \r
@@ -597,6 +599,7 @@ PxeBcCacheDhcpOffer (
       //\r
       // It's a dhcp offer with your address.\r
       //\r
+      ASSERT (Private->ServerCount[OfferType] < PXEBC_MAX_OFFER_NUM);\r
       Private->OfferIndex[OfferType][Private->ServerCount[OfferType]] = Private->NumOffers;\r
       Private->ServerCount[OfferType]++;\r
     }\r
@@ -615,8 +618,6 @@ PxeBcCacheDhcpOffer (
   \r
   @param  Private   Pointer to PxeBc private data.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 PxeBcSelectOffer (\r
@@ -760,6 +761,7 @@ PxeBcSelectOffer (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 PxeBcDhcpCallBack (\r
   IN EFI_DHCP4_PROTOCOL                * This,\r
   IN VOID                              *Context,\r
@@ -1012,9 +1014,15 @@ PxeBcBuildDhcpOptions (
   OptList[Index]->OpCode  = PXEBC_PXE_DHCP4_TAG_UNDI;\r
   OptList[Index]->Length  = sizeof (PXEBC_DHCP4_OPTION_UNDI);\r
   OptEnt.Undi             = (PXEBC_DHCP4_OPTION_UNDI *) OptList[Index]->Data;\r
-  OptEnt.Undi->Type       = Private->Nii->Type;\r
-  OptEnt.Undi->MajorVer   = Private->Nii->MajorVer;\r
-  OptEnt.Undi->MinorVer   = Private->Nii->MinorVer;\r
+  if (Private->Nii != NULL) {\r
+    OptEnt.Undi->Type       = Private->Nii->Type;\r
+    OptEnt.Undi->MajorVer   = Private->Nii->MajorVer;\r
+    OptEnt.Undi->MinorVer   = Private->Nii->MinorVer;\r
+  } else {\r
+    OptEnt.Undi->Type       = DEFAULT_UNDI_TYPE;\r
+    OptEnt.Undi->MajorVer   = DEFAULT_UNDI_MAJOR;\r
+    OptEnt.Undi->MinorVer   = DEFAULT_UNDI_MINOR;\r
+  }\r
 \r
   Index++;\r
   OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);\r
@@ -1038,9 +1046,16 @@ PxeBcBuildDhcpOptions (
   OptEnt.Clid             = (PXEBC_DHCP4_OPTION_CLID *) OptList[Index]->Data;\r
   CopyMem (OptEnt.Clid, DEFAULT_CLASS_ID_DATA, sizeof (PXEBC_DHCP4_OPTION_CLID));\r
   CvtNum (SYS_ARCH, OptEnt.Clid->ArchitectureType, sizeof (OptEnt.Clid->ArchitectureType));\r
-  CopyMem (OptEnt.Clid->InterfaceName, Private->Nii->StringId, sizeof (OptEnt.Clid->InterfaceName));\r
-  CvtNum (Private->Nii->MajorVer, OptEnt.Clid->UndiMajor, sizeof (OptEnt.Clid->UndiMajor));\r
-  CvtNum (Private->Nii->MinorVer, OptEnt.Clid->UndiMinor, sizeof (OptEnt.Clid->UndiMinor));\r
+\r
+  if (Private->Nii != NULL) {\r
+    // \r
+    // If NII protocol exists, update DHCP option data\r
+    //\r
+    CopyMem (OptEnt.Clid->InterfaceName, Private->Nii->StringId, sizeof (OptEnt.Clid->InterfaceName));\r
+    CvtNum (Private->Nii->MajorVer, OptEnt.Clid->UndiMajor, sizeof (OptEnt.Clid->UndiMajor));\r
+    CvtNum (Private->Nii->MinorVer, OptEnt.Clid->UndiMinor, sizeof (OptEnt.Clid->UndiMinor));\r
+  }\r
+\r
   Index++;\r
 \r
   return Index;\r
@@ -1097,7 +1112,7 @@ PxeBcDiscvBootService (
   UINT8                               VendorOptLen;\r
   CHAR8                               *SystemSerialNumber;\r
   EFI_DHCP4_HEADER                    *DhcpHeader;\r
-\r
+  UINT32                              Xid;\r
 \r
   Mode      = Private->PxeBc.Mode;\r
   Dhcp4     = Private->Dhcp4;\r
@@ -1120,6 +1135,7 @@ PxeBcDiscvBootService (
   OptCount = PxeBcBuildDhcpOptions (Private, OptList, FALSE);\r
 \r
   if (IsDiscv) {\r
+    ASSERT (Layer != NULL);\r
     //\r
     // Add vendor option of PXE_BOOT_ITEM\r
     //\r
@@ -1163,14 +1179,15 @@ PxeBcDiscvBootService (
 \r
     DhcpHeader->HwAddrLen = sizeof (EFI_GUID);\r
   }\r
-\r
-  Token.Packet->Dhcp4.Header.Xid      = NET_RANDOM (NetRandomInitSeed ());\r
-  Token.Packet->Dhcp4.Header.Reserved = (UINT16) ((IsBCast) ? 0xf000 : 0x0);\r
+       \r
+  Xid                                 = NET_RANDOM (NetRandomInitSeed ());\r
+  Token.Packet->Dhcp4.Header.Xid      = HTONL(Xid);\r
+  Token.Packet->Dhcp4.Header.Reserved = HTONS((IsBCast) ? 0x8000 : 0);\r
   CopyMem (&Token.Packet->Dhcp4.Header.ClientAddr, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   Token.RemotePort = Sport;\r
 \r
-  if (DestIp == NULL) {\r
+  if (IsBCast) {\r
     SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff);\r
   } else {\r
     CopyMem (&Token.RemoteAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));\r
@@ -1190,7 +1207,8 @@ PxeBcDiscvBootService (
   //\r
   for (TryIndex = 1; TryIndex <= PXEBC_BOOT_REQUEST_RETRIES; TryIndex++) {\r
 \r
-    Token.TimeoutValue  = PXEBC_BOOT_REQUEST_TIMEOUT * TryIndex;\r
+    Token.TimeoutValue                  = (UINT16) (PXEBC_BOOT_REQUEST_TIMEOUT * TryIndex);\r
+    Token.Packet->Dhcp4.Header.Seconds  = (UINT16) (PXEBC_BOOT_REQUEST_TIMEOUT * (TryIndex - 1));\r
 \r
     Status              = Dhcp4->TransmitReceive (Dhcp4, &Token);\r
 \r
@@ -1438,8 +1456,6 @@ PxeBcParseVendorOptions (
   @param  Str     Pointer to a string (boot item string).\r
   @param  Len     The length of string.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 PxeBcDisplayBootItem (\r
@@ -1694,15 +1710,21 @@ PxeBcSelectBootMenu (
   MenuSize  = VendorOpt->BootMenuLen;\r
   MenuItem  = VendorOpt->BootMenu;\r
 \r
+  if (MenuSize == 0) {\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
   while (MenuSize > 0) {\r
-    MenuArray[Index]  = MenuItem;\r
+    MenuArray[Index++]  = MenuItem;\r
     MenuSize          = (UINT8) (MenuSize - (MenuItem->DescLen + 3));\r
     MenuItem          = (PXEBC_BOOT_MENU_ENTRY *) ((UINT8 *) MenuItem + MenuItem->DescLen + 3);\r
-    Index++;\r
+    if (Index >= PXEBC_MAX_MENU_NUM) {\r
+      break;\r
+    }\r
   }\r
 \r
   if (UseDefaultItem) {\r
-    CopyMem (Type, &MenuArray[0]->Type, sizeof (UINT16));\r
+    *Type = MenuArray[0]->Type;\r
     *Type = NTOHS (*Type);\r
     return EFI_SUCCESS;\r
   }\r
@@ -1716,6 +1738,7 @@ PxeBcSelectBootMenu (
   TopRow  = gST->ConOut->Mode->CursorRow - MenuNum;\r
 \r
   do {\r
+    ASSERT (Select < PXEBC_MAX_MENU_NUM);\r
     //\r
     // highlight selected row\r
     //\r