mirror of https://github.com/ipxe/ipxe.git
[efi] Expose DHCP packets via the Apple NetBoot protocol
Mac OS X uses non-standard EFI protocols to obtain the DHCP packets from the UEFI firmware. Originally-implemented-by: Michael Kuron <m.kuron@gmx.de> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/56/head
parent
af9afd0a86
commit
aa4b038c70
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef __EFI_APPLE_NET_BOOT_PROTOCOL_H__
|
||||||
|
#define __EFI_APPLE_NET_BOOT_PROTOCOL_H__
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
*
|
||||||
|
* Apple Net Boot Protocol
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE_LICENCE ( BSD3 );
|
||||||
|
|
||||||
|
#define EFI_APPLE_NET_BOOT_PROTOCOL_GUID \
|
||||||
|
{ 0x78ee99fb, 0x6a5e, 0x4186, \
|
||||||
|
{ 0x97, 0xde, 0xcd, 0x0a, 0xba, 0x34, 0x5a, 0x74 } }
|
||||||
|
|
||||||
|
typedef struct _EFI_APPLE_NET_BOOT_PROTOCOL EFI_APPLE_NET_BOOT_PROTOCOL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get a DHCP packet obtained by the firmware during NetBoot.
|
||||||
|
|
||||||
|
@param This A pointer to the APPLE_NET_BOOT_PROTOCOL instance.
|
||||||
|
@param BufferSize A pointer to the size of the buffer in bytes.
|
||||||
|
@param DataBuffer The memory buffer to copy the packet to. If it is
|
||||||
|
NULL, then the size of the packet is returned
|
||||||
|
in BufferSize.
|
||||||
|
@retval EFI_SUCCESS The packet was copied.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the
|
||||||
|
current packet. BufferSize has been
|
||||||
|
updated with the size needed to
|
||||||
|
complete the request.
|
||||||
|
**/
|
||||||
|
typedef
|
||||||
|
EFI_STATUS
|
||||||
|
(EFIAPI *GET_DHCP_RESPONSE) (
|
||||||
|
IN EFI_APPLE_NET_BOOT_PROTOCOL *This,
|
||||||
|
IN OUT UINTN *BufferSize,
|
||||||
|
OUT VOID *DataBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
struct _EFI_APPLE_NET_BOOT_PROTOCOL
|
||||||
|
{
|
||||||
|
GET_DHCP_RESPONSE GetDhcpResponse;
|
||||||
|
GET_DHCP_RESPONSE GetBsdpResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__EFI_APPLE_NET_BOOT_PROTOCOL_H__ */
|
|
@ -154,6 +154,7 @@ struct efi_config_table {
|
||||||
#define EEFI( efirc ) EPLATFORM ( EINFO_EPLATFORM, efirc )
|
#define EEFI( efirc ) EPLATFORM ( EINFO_EPLATFORM, efirc )
|
||||||
|
|
||||||
extern EFI_GUID efi_absolute_pointer_protocol_guid;
|
extern EFI_GUID efi_absolute_pointer_protocol_guid;
|
||||||
|
extern EFI_GUID efi_apple_net_boot_protocol_guid;
|
||||||
extern EFI_GUID efi_arp_protocol_guid;
|
extern EFI_GUID efi_arp_protocol_guid;
|
||||||
extern EFI_GUID efi_arp_service_binding_protocol_guid;
|
extern EFI_GUID efi_arp_service_binding_protocol_guid;
|
||||||
extern EFI_GUID efi_block_io_protocol_guid;
|
extern EFI_GUID efi_block_io_protocol_guid;
|
||||||
|
|
|
@ -71,6 +71,8 @@ struct efi_well_known_guid {
|
||||||
static struct efi_well_known_guid efi_well_known_guids[] = {
|
static struct efi_well_known_guid efi_well_known_guids[] = {
|
||||||
{ &efi_absolute_pointer_protocol_guid,
|
{ &efi_absolute_pointer_protocol_guid,
|
||||||
"AbsolutePointer" },
|
"AbsolutePointer" },
|
||||||
|
{ &efi_apple_net_boot_protocol_guid,
|
||||||
|
"AppleNetBoot" },
|
||||||
{ &efi_arp_protocol_guid,
|
{ &efi_arp_protocol_guid,
|
||||||
"Arp" },
|
"Arp" },
|
||||||
{ &efi_arp_service_binding_protocol_guid,
|
{ &efi_arp_service_binding_protocol_guid,
|
||||||
|
|
|
@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
#include <ipxe/efi/Protocol/AbsolutePointer.h>
|
#include <ipxe/efi/Protocol/AbsolutePointer.h>
|
||||||
|
#include <ipxe/efi/Protocol/AppleNetBoot.h>
|
||||||
#include <ipxe/efi/Protocol/Arp.h>
|
#include <ipxe/efi/Protocol/Arp.h>
|
||||||
#include <ipxe/efi/Protocol/BlockIo.h>
|
#include <ipxe/efi/Protocol/BlockIo.h>
|
||||||
#include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
|
#include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
|
||||||
|
@ -84,6 +85,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
EFI_GUID efi_absolute_pointer_protocol_guid
|
EFI_GUID efi_absolute_pointer_protocol_guid
|
||||||
= EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
|
= EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
|
||||||
|
|
||||||
|
/** Apple NetBoot protocol GUID */
|
||||||
|
EFI_GUID efi_apple_net_boot_protocol_guid
|
||||||
|
= EFI_APPLE_NET_BOOT_PROTOCOL_GUID;
|
||||||
|
|
||||||
/** ARP protocol GUID */
|
/** ARP protocol GUID */
|
||||||
EFI_GUID efi_arp_protocol_guid
|
EFI_GUID efi_arp_protocol_guid
|
||||||
= EFI_ARP_PROTOCOL_GUID;
|
= EFI_ARP_PROTOCOL_GUID;
|
||||||
|
|
|
@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/efi/efi_snp.h>
|
#include <ipxe/efi/efi_snp.h>
|
||||||
#include <ipxe/efi/efi_pxe.h>
|
#include <ipxe/efi/efi_pxe.h>
|
||||||
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
||||||
|
#include <ipxe/efi/Protocol/AppleNetBoot.h>
|
||||||
#include <usr/ifmgmt.h>
|
#include <usr/ifmgmt.h>
|
||||||
#include <config/general.h>
|
#include <config/general.h>
|
||||||
|
|
||||||
|
@ -80,6 +81,8 @@ struct efi_pxe {
|
||||||
EFI_PXE_BASE_CODE_PROTOCOL base;
|
EFI_PXE_BASE_CODE_PROTOCOL base;
|
||||||
/** PXE base code mode */
|
/** PXE base code mode */
|
||||||
EFI_PXE_BASE_CODE_MODE mode;
|
EFI_PXE_BASE_CODE_MODE mode;
|
||||||
|
/** Apple NetBoot protocol */
|
||||||
|
EFI_APPLE_NET_BOOT_PROTOCOL apple;
|
||||||
|
|
||||||
/** TCP/IP network-layer protocol */
|
/** TCP/IP network-layer protocol */
|
||||||
struct tcpip_net_protocol *tcpip;
|
struct tcpip_net_protocol *tcpip;
|
||||||
|
@ -1498,6 +1501,83 @@ static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol = {
|
||||||
.SetPackets = efi_pxe_set_packets,
|
.SetPackets = efi_pxe_set_packets,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Apple NetBoot protocol
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get DHCP/BSDP response
|
||||||
|
*
|
||||||
|
* @v packet Packet
|
||||||
|
* @v len Length of data buffer
|
||||||
|
* @v data Data buffer
|
||||||
|
* @ret efirc EFI status code
|
||||||
|
*/
|
||||||
|
static EFI_STATUS EFIAPI
|
||||||
|
efi_apple_get_response ( EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len,
|
||||||
|
VOID *data ) {
|
||||||
|
|
||||||
|
/* Check length */
|
||||||
|
if ( *len < sizeof ( *packet ) ) {
|
||||||
|
*len = sizeof ( *packet );
|
||||||
|
return EFI_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy packet */
|
||||||
|
memcpy ( data, packet, sizeof ( *packet ) );
|
||||||
|
*len = sizeof ( *packet );
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get DHCP response
|
||||||
|
*
|
||||||
|
* @v apple Apple NetBoot protocol
|
||||||
|
* @v len Length of data buffer
|
||||||
|
* @v data Data buffer
|
||||||
|
* @ret efirc EFI status code
|
||||||
|
*/
|
||||||
|
static EFI_STATUS EFIAPI
|
||||||
|
efi_apple_get_dhcp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
|
||||||
|
UINTN *len, VOID *data ) {
|
||||||
|
struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
|
||||||
|
|
||||||
|
return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get BSDP response
|
||||||
|
*
|
||||||
|
* @v apple Apple NetBoot protocol
|
||||||
|
* @v len Length of data buffer
|
||||||
|
* @v data Data buffer
|
||||||
|
* @ret efirc EFI status code
|
||||||
|
*/
|
||||||
|
static EFI_STATUS EFIAPI
|
||||||
|
efi_apple_get_bsdp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
|
||||||
|
UINTN *len, VOID *data ) {
|
||||||
|
struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
|
||||||
|
|
||||||
|
return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Apple NetBoot protocol */
|
||||||
|
static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol = {
|
||||||
|
.GetDhcpResponse = efi_apple_get_dhcp_response,
|
||||||
|
.GetBsdpResponse = efi_apple_get_bsdp_response,
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Installer
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install PXE base code protocol
|
* Install PXE base code protocol
|
||||||
*
|
*
|
||||||
|
@ -1526,6 +1606,8 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
|
||||||
pxe->handle = handle;
|
pxe->handle = handle;
|
||||||
memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
|
memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
|
||||||
pxe->base.Mode = &pxe->mode;
|
pxe->base.Mode = &pxe->mode;
|
||||||
|
memcpy ( &pxe->apple, &efi_apple_net_boot_protocol,
|
||||||
|
sizeof ( pxe->apple ) );
|
||||||
pxe->buf.op = &efi_pxe_buf_operations;
|
pxe->buf.op = &efi_pxe_buf_operations;
|
||||||
intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
|
intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
|
||||||
intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
|
intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
|
||||||
|
@ -1545,7 +1627,9 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
|
||||||
|
|
||||||
/* Install PXE base code protocol */
|
/* Install PXE base code protocol */
|
||||||
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
||||||
&handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
|
&handle,
|
||||||
|
&efi_pxe_base_code_protocol_guid, &pxe->base,
|
||||||
|
&efi_apple_net_boot_protocol_guid, &pxe->apple,
|
||||||
NULL ) ) != 0 ) {
|
NULL ) ) != 0 ) {
|
||||||
rc = -EEFI ( efirc );
|
rc = -EEFI ( efirc );
|
||||||
DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
|
DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
|
||||||
|
@ -1560,7 +1644,9 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bs->UninstallMultipleProtocolInterfaces (
|
bs->UninstallMultipleProtocolInterfaces (
|
||||||
handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
|
handle,
|
||||||
|
&efi_pxe_base_code_protocol_guid, &pxe->base,
|
||||||
|
&efi_apple_net_boot_protocol_guid, &pxe->apple,
|
||||||
NULL );
|
NULL );
|
||||||
err_install_protocol:
|
err_install_protocol:
|
||||||
ref_put ( &pxe->refcnt );
|
ref_put ( &pxe->refcnt );
|
||||||
|
@ -1590,7 +1676,9 @@ void efi_pxe_uninstall ( EFI_HANDLE handle ) {
|
||||||
|
|
||||||
/* Uninstall PXE base code protocol */
|
/* Uninstall PXE base code protocol */
|
||||||
bs->UninstallMultipleProtocolInterfaces (
|
bs->UninstallMultipleProtocolInterfaces (
|
||||||
handle, &efi_pxe_base_code_protocol_guid, &pxe->base,
|
handle,
|
||||||
|
&efi_pxe_base_code_protocol_guid, &pxe->base,
|
||||||
|
&efi_apple_net_boot_protocol_guid, &pxe->apple,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
/* Remove from list and drop list's reference */
|
/* Remove from list and drop list's reference */
|
||||||
|
|
Loading…
Reference in New Issue