/** @file Library functions which relate to boot option description. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
Copyright (C) 2024, Mike Beaton. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "NetworkBootInternal.h" /** Return the description for network boot device. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetNetworkDescription ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; MAC_ADDR_DEVICE_PATH *Mac; VLAN_DEVICE_PATH *Vlan; EFI_DEVICE_PATH_PROTOCOL *Ip; EFI_DEVICE_PATH_PROTOCOL *Uri; CHAR16 *Description; UINTN DescriptionSize; Status = gBS->OpenProtocol ( Handle, &gEfiLoadFileProtocolGuid, NULL, gImageHandle, Handle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (EFI_ERROR (Status)) { return NULL; } Status = gBS->OpenProtocol ( Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath, gImageHandle, Handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status) || (DevicePath == NULL)) { return NULL; } // // The PXE device path is like: // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)] // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...) // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...) // // The HTTP device path is like: // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...) // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...) // while (!IsDevicePathEnd (DevicePath) && ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) || (DevicePathSubType (DevicePath) != MSG_MAC_ADDR_DP)) ) { DevicePath = NextDevicePathNode (DevicePath); } if (IsDevicePathEnd (DevicePath)) { return NULL; } Mac = (MAC_ADDR_DEVICE_PATH *)DevicePath; DevicePath = NextDevicePathNode (DevicePath); // // Locate the optional Vlan node // if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_VLAN_DP) ) { Vlan = (VLAN_DEVICE_PATH *)DevicePath; DevicePath = NextDevicePathNode (DevicePath); } else { Vlan = NULL; } // // Skip the optional Wi-Fi node // if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_WIFI_DP) ) { DevicePath = NextDevicePathNode (DevicePath); } // // Locate the IP node // if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && ((DevicePathSubType (DevicePath) == MSG_IPv4_DP) || (DevicePathSubType (DevicePath) == MSG_IPv6_DP)) ) { Ip = DevicePath; DevicePath = NextDevicePathNode (DevicePath); } else { Ip = NULL; } // // Skip the optional DNS node // if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_DNS_DP) ) { DevicePath = NextDevicePathNode (DevicePath); } // // Locate the URI node // if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_URI_DP) ) { Uri = DevicePath; DevicePath = NextDevicePathNode (DevicePath); } else { Uri = NULL; } // // Build description like below: // "PXE Boot IPv6 (MAC:11-22-33-44-55-66 VLAN1)" // "HTTP Boot IPv4 (MAC:11-22-33-44-55-66)" // DescriptionSize = sizeof (L"HTTP Boot IPv6 (MAC:11-22-33-44-55-66 VLAN65535)"); Description = AllocatePool (DescriptionSize); ASSERT (Description != NULL); UnicodeSPrint ( Description, DescriptionSize, (Vlan == NULL) ? L"%s Boot IPv%d (MAC:%02x-%02x-%02x-%02x-%02x-%02x)" : L"%s Boot IPv%d (MAC:%02x-%02x-%02x-%02x-%02x-%02x VLAN%d)", (Uri == NULL) ? L"PXE" : L"HTTP", ((Ip == NULL) || (DevicePathSubType (Ip) == MSG_IPv4_DP)) ? 4 : 6, Mac->MacAddress.Addr[0], Mac->MacAddress.Addr[1], Mac->MacAddress.Addr[2], Mac->MacAddress.Addr[3], Mac->MacAddress.Addr[4], Mac->MacAddress.Addr[5], (Vlan == NULL) ? 0 : Vlan->VlanId ); return Description; }