From 2362f1a7859760e38f3137761f07bcc480349f5b Mon Sep 17 00:00:00 2001 From: Bryce Lanham Date: Mon, 24 Apr 2023 06:44:56 -0500 Subject: [PATCH] Implement Multiboot2 network tag Added caching of the dhcp response in the pxe code, and then adding the tag containing it. --- common/protos/multiboot2.c | 18 ++++++++++++++++++ common/pxe/pxe.h | 3 +++ common/pxe/tftp.s2.c | 8 ++++++++ test/multiboot2.c | 6 ++++++ 4 files changed, 35 insertions(+) diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index d6791613..816aa887 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -24,6 +24,7 @@ #include #include #include +#include #define LIMINE_BRAND "Limine " LIMINE_VERSION @@ -56,6 +57,7 @@ static size_t get_multiboot2_info_size( ALIGN_UP(sizeof(struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN) + // EFI image handle 64 #endif #endif + ALIGN_UP(sizeof(struct multiboot_tag_network) + cached_dhcp_packet_len, MULTIBOOT_TAG_ALIGN) + // network info ALIGN_UP(sizeof(struct multiboot_tag), MULTIBOOT_TAG_ALIGN); // end } @@ -782,6 +784,22 @@ skip_modeset:; } #endif + ////////////////////////////////////////////// + // Create network info tag + ////////////////////////////////////////////// + { + if (cached_dhcp_packet_len) { + struct multiboot_tag_network *tag = (struct multiboot_tag_network *)(mb2_info + info_idx); + + tag->type = MULTIBOOT_TAG_TYPE_NETWORK; + tag->size = sizeof(struct multiboot_tag_network) + cached_dhcp_packet_len; + + // Copy over the DHCP packet. + memcpy(tag->dhcpack, cached_dhcp_packet, cached_dhcp_packet_len); + append_tag(info_idx, tag); + } + } + ////////////////////////////////////////////// // Create end tag ////////////////////////////////////////////// diff --git a/common/pxe/pxe.h b/common/pxe/pxe.h index e80c7150..20c51119 100644 --- a/common/pxe/pxe.h +++ b/common/pxe/pxe.h @@ -4,6 +4,9 @@ #include #include +extern uint8_t cached_dhcp_packet[1472]; +extern int cached_dhcp_packet_len; + #if defined (BIOS) struct volume *pxe_bind_volume(void); diff --git a/common/pxe/tftp.s2.c b/common/pxe/tftp.s2.c index db32b5d6..ff7c8078 100644 --- a/common/pxe/tftp.s2.c +++ b/common/pxe/tftp.s2.c @@ -10,6 +10,10 @@ #include #include +// cache the dhcp packet +uint8_t cached_dhcp_packet[1472] = { 0 }; +int cached_dhcp_packet_len = 0; + #if defined (BIOS) static uint32_t get_boot_server_info(void) { @@ -17,6 +21,8 @@ static uint32_t get_boot_server_info(void) { cachedinfo.packet_type = PXENV_PACKET_TYPE_CACHED_REPLY; 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)); + memcpy(&cached_dhcp_packet, ph, sizeof(struct bootph)); + cached_dhcp_packet_len = sizeof(struct bootph); return ph->sip; } @@ -141,6 +147,8 @@ 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 packet = &part->pxe_base_code->Mode->DhcpAck; memcpy(out.Addr, packet->Dhcpv4.BootpSiAddr, 4); + memcpy(cached_dhcp_packet, packet, sizeof(EFI_PXE_BASE_CODE_PACKET)); + cached_dhcp_packet_len = sizeof(EFI_PXE_BASE_CODE_PACKET); } else { if (inet_pton(server_addr, &out.Addr)) { panic(true, "tftp: Invalid IPv4 address: \"%s\"", server_addr); diff --git a/test/multiboot2.c b/test/multiboot2.c index ef522285..34428541 100644 --- a/test/multiboot2.c +++ b/test/multiboot2.c @@ -132,6 +132,12 @@ void multiboot2_main(uint32_t magic, struct multiboot_info* mb_info_addr) { break; } + + case MULTIBOOT_TAG_TYPE_NETWORK: { + struct multiboot_tag_network *network = (struct multiboot_tag_network *)tag; + e9_printf("\t network tag exists"); + break; + } } add_size = tag->size;