]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Expose DHCP packets via the Apple NetBoot protocol
authorMichael Brown <mcb30@ipxe.org>
Sun, 29 May 2016 12:04:26 +0000 (13:04 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sun, 29 May 2016 12:10:14 +0000 (13:10 +0100)
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>
src/include/ipxe/efi/Protocol/AppleNetBoot.h [new file with mode: 0644]
src/include/ipxe/efi/efi.h
src/interface/efi/efi_debug.c
src/interface/efi/efi_guid.c
src/interface/efi/efi_pxe.c

diff --git a/src/include/ipxe/efi/Protocol/AppleNetBoot.h b/src/include/ipxe/efi/Protocol/AppleNetBoot.h
new file mode 100644 (file)
index 0000000..144beff
--- /dev/null
@@ -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__ */
index 390d4e6e65979a3321649ecb6c026f0bef006636..db9943a429d792b02a042c5ab395c55f267f1de5 100644 (file)
@@ -154,6 +154,7 @@ struct efi_config_table {
 #define EEFI( efirc ) EPLATFORM ( EINFO_EPLATFORM, efirc )
 
 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_service_binding_protocol_guid;
 extern EFI_GUID efi_block_io_protocol_guid;
index 84160d6434c4efc8232d575fafa5d744eb5d6356..19531fdc1afa707f7442f5ec6bf2ceaf98c444e6 100644 (file)
@@ -71,6 +71,8 @@ struct efi_well_known_guid {
 static struct efi_well_known_guid efi_well_known_guids[] = {
        { &efi_absolute_pointer_protocol_guid,
          "AbsolutePointer" },
+       { &efi_apple_net_boot_protocol_guid,
+         "AppleNetBoot" },
        { &efi_arp_protocol_guid,
          "Arp" },
        { &efi_arp_service_binding_protocol_guid,
index 39da5efe04d98a4a5d2d257b6e2ced7ba68c1d2a..62ee5a517c1492a409dfc5b339aea5536653241d 100644 (file)
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/Protocol/AbsolutePointer.h>
+#include <ipxe/efi/Protocol/AppleNetBoot.h>
 #include <ipxe/efi/Protocol/Arp.h>
 #include <ipxe/efi/Protocol/BlockIo.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_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 */
 EFI_GUID efi_arp_protocol_guid
        = EFI_ARP_PROTOCOL_GUID;
index 1847e3fd106448476af7e982fd1788fa3d3be298..a1f81df59761c8adb7975f72336c6d482b626400 100644 (file)
@@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/efi_snp.h>
 #include <ipxe/efi/efi_pxe.h>
 #include <ipxe/efi/Protocol/PxeBaseCode.h>
+#include <ipxe/efi/Protocol/AppleNetBoot.h>
 #include <usr/ifmgmt.h>
 #include <config/general.h>
 
@@ -80,6 +81,8 @@ struct efi_pxe {
        EFI_PXE_BASE_CODE_PROTOCOL base;
        /** PXE base code mode */
        EFI_PXE_BASE_CODE_MODE mode;
+       /** Apple NetBoot protocol */
+       EFI_APPLE_NET_BOOT_PROTOCOL apple;
 
        /** TCP/IP network-layer protocol */
        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,
 };
 
+/******************************************************************************
+ *
+ * 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
  *
@@ -1526,6 +1606,8 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
        pxe->handle = handle;
        memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
        pxe->base.Mode = &pxe->mode;
+       memcpy ( &pxe->apple, &efi_apple_net_boot_protocol,
+                sizeof ( pxe->apple ) );
        pxe->buf.op = &efi_pxe_buf_operations;
        intf_init ( &pxe->tftp, &efi_pxe_tftp_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 */
        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 ) {
                rc = -EEFI ( efirc );
                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;
 
        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 );
  err_install_protocol:
        ref_put ( &pxe->refcnt );
@@ -1590,7 +1676,9 @@ void efi_pxe_uninstall ( EFI_HANDLE handle ) {
 
        /* Uninstall PXE base code protocol */
        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 );
 
        /* Remove from list and drop list's reference */