pxe: Add and use constant PXE ACK packet size and fix BIOS PXE ACK struct

This commit is contained in:
mintsuki 2023-04-28 04:59:08 +02:00
parent 36846549e0
commit 8dd7973e23
3 changed files with 19 additions and 13 deletions

View File

@ -57,7 +57,7 @@ static size_t get_multiboot2_info_size(
ALIGN_UP(sizeof(struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN) + // EFI image handle 64 ALIGN_UP(sizeof(struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN) + // EFI image handle 64
#endif #endif
#endif #endif
ALIGN_UP(sizeof(struct multiboot_tag_network) + cached_dhcp_packet_len, MULTIBOOT_TAG_ALIGN) + // network info ALIGN_UP(sizeof(struct multiboot_tag_network) + DHCP_ACK_PACKET_LEN, MULTIBOOT_TAG_ALIGN) + // network info
ALIGN_UP(sizeof(struct multiboot_tag), MULTIBOOT_TAG_ALIGN); // end ALIGN_UP(sizeof(struct multiboot_tag), MULTIBOOT_TAG_ALIGN); // end
} }
@ -788,14 +788,14 @@ skip_modeset:;
// Create network info tag // Create network info tag
////////////////////////////////////////////// //////////////////////////////////////////////
{ {
if (cached_dhcp_packet_len) { if (cached_dhcp_ack_valid) {
struct multiboot_tag_network *tag = (struct multiboot_tag_network *)(mb2_info + info_idx); struct multiboot_tag_network *tag = (struct multiboot_tag_network *)(mb2_info + info_idx);
tag->type = MULTIBOOT_TAG_TYPE_NETWORK; tag->type = MULTIBOOT_TAG_TYPE_NETWORK;
tag->size = sizeof(struct multiboot_tag_network) + cached_dhcp_packet_len; tag->size = sizeof(struct multiboot_tag_network) + DHCP_ACK_PACKET_LEN;
// Copy over the DHCP packet. // Copy over the DHCP packet.
memcpy(tag->dhcpack, cached_dhcp_packet, cached_dhcp_packet_len); memcpy(tag->dhcpack, cached_dhcp_packet, DHCP_ACK_PACKET_LEN);
append_tag(info_idx, tag); append_tag(info_idx, tag);
} }
} }

View File

@ -4,8 +4,10 @@
#include <stdint.h> #include <stdint.h>
#include <lib/part.h> #include <lib/part.h>
extern uint8_t cached_dhcp_packet[1472]; #define DHCP_ACK_PACKET_LEN 296
extern int cached_dhcp_packet_len;
extern uint8_t cached_dhcp_packet[DHCP_ACK_PACKET_LEN];
extern bool cached_dhcp_ack_valid;
#if defined (BIOS) #if defined (BIOS)
@ -36,7 +38,7 @@ struct bootph {
struct bootph_vendor_v { struct bootph_vendor_v {
uint8_t magic[4]; uint8_t magic[4];
uint32_t flags; uint32_t flags;
uint8_t pad[56]; uint8_t pad[52];
} v; } v;
} vendor; } vendor;
}; };

View File

@ -11,8 +11,8 @@
#include <lib/misc.h> #include <lib/misc.h>
// cache the dhcp packet // cache the dhcp packet
uint8_t cached_dhcp_packet[1472] = { 0 }; uint8_t cached_dhcp_packet[DHCP_ACK_PACKET_LEN] = { 0 };
int cached_dhcp_packet_len = 0; bool cached_dhcp_ack_valid = false;
#if defined (BIOS) #if defined (BIOS)
@ -21,8 +21,10 @@ static uint32_t get_boot_server_info(void) {
cachedinfo.packet_type = PXENV_PACKET_TYPE_CACHED_REPLY; cachedinfo.packet_type = PXENV_PACKET_TYPE_CACHED_REPLY;
pxe_call(PXENV_GET_CACHED_INFO, ((uint16_t)rm_seg(&cachedinfo)), (uint16_t)rm_off(&cachedinfo)); pxe_call(PXENV_GET_CACHED_INFO, ((uint16_t)rm_seg(&cachedinfo)), (uint16_t)rm_off(&cachedinfo));
struct bootph *ph = (struct bootph*)(void *) (((((uint32_t)cachedinfo.buffer) >> 16) << 4) + (((uint32_t)cachedinfo.buffer) & 0xFFFF)); struct bootph *ph = (struct bootph*)(void *) (((((uint32_t)cachedinfo.buffer) >> 16) << 4) + (((uint32_t)cachedinfo.buffer) & 0xFFFF));
memcpy(&cached_dhcp_packet, ph, sizeof(struct bootph)); if (!cached_dhcp_ack_valid) {
cached_dhcp_packet_len = sizeof(struct bootph); memcpy(cached_dhcp_packet, ph, DHCP_ACK_PACKET_LEN);
cached_dhcp_ack_valid = true;
}
return ph->sip; return ph->sip;
} }
@ -147,8 +149,10 @@ static EFI_IP_ADDRESS *parse_ip_addr(struct volume *part, const char *server_add
else if (part->pxe_base_code->Mode->ProxyOfferReceived) packet = &part->pxe_base_code->Mode->ProxyOffer; else if (part->pxe_base_code->Mode->ProxyOfferReceived) packet = &part->pxe_base_code->Mode->ProxyOffer;
else packet = &part->pxe_base_code->Mode->DhcpAck; else packet = &part->pxe_base_code->Mode->DhcpAck;
memcpy(out.Addr, packet->Dhcpv4.BootpSiAddr, 4); memcpy(out.Addr, packet->Dhcpv4.BootpSiAddr, 4);
memcpy(cached_dhcp_packet, packet, sizeof(EFI_PXE_BASE_CODE_PACKET)); if (!cached_dhcp_ack_valid) {
cached_dhcp_packet_len = sizeof(EFI_PXE_BASE_CODE_PACKET); memcpy(cached_dhcp_packet, packet, DHCP_ACK_PACKET_LEN);
cached_dhcp_ack_valid = true;
}
} else { } else {
if (inet_pton(server_addr, &out.Addr)) { if (inet_pton(server_addr, &out.Addr)) {
panic(true, "tftp: Invalid IPv4 address: \"%s\"", server_addr); panic(true, "tftp: Invalid IPv4 address: \"%s\"", server_addr);