iPXE
efi_cachedhcp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <string.h>
27 #include <errno.h>
28 #include <ipxe/cachedhcp.h>
29 #include <ipxe/efi/efi.h>
30 #include <ipxe/efi/efi_cachedhcp.h>
32 
33 /** @file
34  *
35  * EFI cached DHCP packet
36  *
37  */
38 
39 /**
40  * Record cached DHCP packet
41  *
42  * @v device Device handle
43  * @ret rc Return status code
44  */
47  union {
49  void *interface;
50  } pxe;
52  EFI_STATUS efirc;
53  int rc;
54 
55  /* Look for a PXE base code instance on the image's device handle */
56  if ( ( efirc = bs->OpenProtocol ( device,
58  &pxe.interface, efi_image_handle,
59  NULL,
61  rc = -EEFI ( efirc );
62  DBGC ( device, "EFI %s has no PXE base code instance: %s\n",
63  efi_handle_name ( device ), strerror ( rc ) );
64  goto err_open;
65  }
66 
67  /* Do not attempt to cache IPv6 packets */
68  mode = pxe.pxe->Mode;
69  if ( mode->UsingIpv6 ) {
70  rc = -ENOTSUP;
71  DBGC ( device, "EFI %s has IPv6 PXE base code\n",
72  efi_handle_name ( device ) );
73  goto err_ipv6;
74  }
75 
76  /* Record DHCPACK, if present */
77  if ( mode->DhcpAckReceived &&
79  virt_to_user ( &mode->DhcpAck ),
80  sizeof ( mode->DhcpAck ) ) ) != 0 ) ) {
81  DBGC ( device, "EFI %s could not record DHCPACK: %s\n",
82  efi_handle_name ( device ), strerror ( rc ) );
83  goto err_dhcpack;
84  }
85 
86  /* Record ProxyDHCPOFFER, if present */
87  if ( mode->ProxyOfferReceived &&
89  virt_to_user ( &mode->ProxyOffer ),
90  sizeof ( mode->ProxyOffer ) ) ) != 0)){
91  DBGC ( device, "EFI %s could not record ProxyDHCPOFFER: %s\n",
92  efi_handle_name ( device ), strerror ( rc ) );
93  goto err_proxydhcp;
94  }
95 
96  /* Record PxeBSACK, if present */
97  if ( mode->PxeReplyReceived &&
99  virt_to_user ( &mode->PxeReply ),
100  sizeof ( mode->PxeReply ) ) ) != 0)){
101  DBGC ( device, "EFI %s could not record PXEBSACK: %s\n",
102  efi_handle_name ( device ), strerror ( rc ) );
103  goto err_pxebs;
104  }
105 
106  /* Success */
107  rc = 0;
108 
109  err_pxebs:
110  err_proxydhcp:
111  err_dhcpack:
112  err_ipv6:
115  err_open:
116  return rc;
117 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int efi_cachedhcp_record(EFI_HANDLE device)
Record cached DHCP packet.
Definition: efi_cachedhcp.c:45
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Error codes.
struct cached_dhcp_packet cached_proxydhcp
Cached ProxyDHCPOFFER.
Definition: cachedhcp.c:54
#define DBGC(...)
Definition: compiler.h:505
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition: efi_guid.c:224
EFI PXE Base Code Protocol definitions, which is used to access PXE-compatible devices for network ac...
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:298
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1906
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A hardware device.
Definition: device.h:73
An object interface.
Definition: interface.h:124
Cached DHCP packet.
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1271
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:722
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI cached DHCP packet.
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:33
struct cached_dhcp_packet cached_dhcpack
Cached DHCPACK.
Definition: cachedhcp.c:49
EFI API.
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:295
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
struct cached_dhcp_packet cached_pxebs
Cached PXEBSACK.
Definition: cachedhcp.c:59
int cachedhcp_record(struct cached_dhcp_packet *cache, userptr_t data, size_t max_len)
Record cached DHCP packet.
Definition: cachedhcp.c:139
The EFI_PXE_BASE_CODE_PROTOCOL is used to control PXE-compatible devices.
Definition: PxeBaseCode.h:909
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
EFI_PXE_BASE_CODE_PACKET ProxyOffer
Definition: PxeBaseCode.h:296
String functions.
Definition: efi.h:50