Пример #1
0
/**
  Parse out the boot information from the last Dhcp4 reply packet.

  @param[in, out] Private      Pointer to PxeBc private data.
  @param[out]     BufferSize   Size of the boot file to be downloaded.

  @retval EFI_SUCCESS          Successfully parsed out all the boot information.
  @retval Others               Failed to parse out the boot information.

**/
EFI_STATUS
PxeBcDhcp4BootInfo (
  IN OUT PXEBC_PRIVATE_DATA   *Private,
     OUT UINT64               *BufferSize
  )
{
  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;
  EFI_PXE_BASE_CODE_MODE      *Mode;
  EFI_STATUS                  Status;
  PXEBC_DHCP4_PACKET_CACHE    *Cache4;
  UINT16                      Value;
  PXEBC_VENDOR_OPTION         *VendorOpt;
  PXEBC_BOOT_SVR_ENTRY        *Entry;
  
  PxeBc       = &Private->PxeBc;
  Mode        = PxeBc->Mode;
  Status      = EFI_SUCCESS;
  *BufferSize = 0;

  //
  // Get the last received Dhcp4 reply packet.
  //
  if (Mode->PxeReplyReceived) {
    Cache4 = &Private->PxeReply.Dhcp4;
  } else if (Mode->ProxyOfferReceived) {
    Cache4 = &Private->ProxyOffer.Dhcp4;
  } else {
    Cache4 = &Private->DhcpAck.Dhcp4;
  }

  ASSERT (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);

  //
  // Parse the boot server address.
  // If prompt/discover is disabled, get the first boot server from the boot servers list.
  // Otherwise, parse the boot server Ipv4 address from next server address field in DHCP header.
  // If all these fields are not available, use option 54 instead.
  //
  VendorOpt = &Cache4->VendorOpt;
  if (IS_DISABLE_PROMPT_MENU (VendorOpt->DiscoverCtrl) && IS_VALID_BOOT_SERVERS (VendorOpt->BitMap)) {
    Entry = VendorOpt->BootSvr;
    if (VendorOpt->BootSvrLen >= sizeof (PXEBC_BOOT_SVR_ENTRY) && Entry->IpCnt > 0) {
      CopyMem (
        &Private->ServerIp,
        &Entry->IpAddr[0],
        sizeof (EFI_IPv4_ADDRESS)
        );
    }
  }
  if (Private->ServerIp.Addr[0] == 0) {
    //
    // ServerIp.Addr[0] equals zero means we failed to get IP address from boot server list.
    // Try to use next server address field.
    //
    CopyMem (
      &Private->ServerIp,
      &Cache4->Packet.Offer.Dhcp4.Header.ServerAddr,
      sizeof (EFI_IPv4_ADDRESS)
      );
  }
  if (Private->ServerIp.Addr[0] == 0) {
    //
    // Still failed , use the IP address from option 54.
    //
    CopyMem (
      &Private->ServerIp,
      Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,
      sizeof (EFI_IPv4_ADDRESS)
      );
  }

  //
  // Parse the boot file name by option.
  //
  Private->BootFileName = Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data;

  if (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN] != NULL) {
    //
    // Parse the boot file size by option.
    //
    CopyMem (&Value, Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));
    Value       = NTOHS (Value);
    //
    // The field of boot file size is 512 bytes in unit.
    //
    *BufferSize = 512 * Value;
  } else {
    //
    // Get the bootfile size by tftp command if no option available.
    //
    Status = PxeBc->Mtftp (
                      PxeBc,
                      EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
                      NULL,
                      FALSE,
                      BufferSize,
                      &Private->BlockSize,
                      &Private->ServerIp,
                      Private->BootFileName,
                      NULL,
                      FALSE
                      );
  }

  //
  // Save the value of boot file size.
  //
  Private->BootFileSize = (UINTN) *BufferSize;

  //
  // Display all the information: boot server address, boot file name and boot file size.
  //
  AsciiPrint ("\n  Server IP address is ");
  PxeBcShowIp4Addr (&Private->ServerIp.v4);
  AsciiPrint ("\n  NBP filename is %a", Private->BootFileName);
  AsciiPrint ("\n  NBP filesize is %d Bytes", Private->BootFileSize);

  return Status;
}
Пример #2
0
/**
  Parse out the boot information from the last Dhcp4 reply packet.

  @param[in, out] Private      Pointer to PxeBc private data.
  @param[out]     BufferSize   Size of the boot file to be downloaded.

  @retval EFI_SUCCESS          Successfully parsed out all the boot information.
  @retval Others               Failed to parse out the boot information.

**/
EFI_STATUS
PxeBcDhcp4BootInfo (
  IN OUT PXEBC_PRIVATE_DATA   *Private,
     OUT UINT64               *BufferSize
  )
{
  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;
  EFI_PXE_BASE_CODE_MODE      *Mode;
  EFI_STATUS                  Status;
  PXEBC_DHCP4_PACKET_CACHE    *Cache4;
  UINT16                      Value;

  PxeBc       = &Private->PxeBc;
  Mode        = PxeBc->Mode;
  Status      = EFI_SUCCESS;
  *BufferSize = 0;

  //
  // Get the last received Dhcp4 reply packet.
  //
  if (Mode->PxeReplyReceived) {
    Cache4 = &Private->PxeReply.Dhcp4;
  } else if (Mode->ProxyOfferReceived) {
    Cache4 = &Private->ProxyOffer.Dhcp4;
  } else {
    Cache4 = &Private->DhcpAck.Dhcp4;
  }

  //
  // Parse the boot server Ipv4 address by next server address.
  // If this field isn't available, use option 54 instead.
  //
  CopyMem (
    &Private->ServerIp,
    &Cache4->Packet.Offer.Dhcp4.Header.ServerAddr,
    sizeof (EFI_IPv4_ADDRESS)
    );

  if (Private->ServerIp.Addr[0] == 0) {
    CopyMem (
      &Private->ServerIp,
      Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,
      sizeof (EFI_IPv4_ADDRESS)
      );
  }

  //
  // Parse the boot file name by option.
  //
  ASSERT (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);
  Private->BootFileName = Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data;

  if (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN] != NULL) {
    //
    // Parse the boot file size by option.
    //
    CopyMem (&Value, Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));
    Value       = NTOHS (Value);
    //
    // The field of boot file size is 512 bytes in unit.
    //
    *BufferSize = 512 * Value;
  } else {
    //
    // Get the bootfile size by tftp command if no option available.
    //
    Status = PxeBc->Mtftp (
                      PxeBc,
                      EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
                      NULL,
                      FALSE,
                      BufferSize,
                      &Private->BlockSize,
                      &Private->ServerIp,
                      Private->BootFileName,
                      NULL,
                      FALSE
                      );
  }

  //
  // Save the value of boot file size.
  //
  Private->BootFileSize = (UINTN) *BufferSize;

  //
  // Display all the information: boot server address, boot file name and boot file size.
  //
  AsciiPrint ("\n  Server IP address is ");
  PxeBcShowIp4Addr (&Private->ServerIp.v4);
  AsciiPrint ("\n  NBP filename is %a", Private->BootFileName);
  AsciiPrint ("\n  NBP filesize is %d Bytes", Private->BootFileSize);

  return Status;
}