iPXE
efi_pxe.c File Reference

EFI PXE base code protocol. More...

#include <string.h>
#include <errno.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/netdevice.h>
#include <ipxe/fakedhcp.h>
#include <ipxe/process.h>
#include <ipxe/uri.h>
#include <ipxe/in.h>
#include <ipxe/socket.h>
#include <ipxe/tcpip.h>
#include <ipxe/xferbuf.h>
#include <ipxe/open.h>
#include <ipxe/dhcppkt.h>
#include <ipxe/udp.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_pxe.h>
#include <ipxe/efi/efi_null.h>
#include <ipxe/efi/Protocol/PxeBaseCode.h>
#include <ipxe/efi/Protocol/AppleNetBoot.h>
#include <usr/ifmgmt.h>
#include <config/general.h>

Go to the source code of this file.

Data Structures

struct  efi_pxe
 A PXE base code. More...
struct  sockaddr_efi
 An EFI socket address. More...
struct  efi_pxe_udp_pseudo_header
 EFI UDP pseudo-header. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void efi_pxe_free (struct refcnt *refcnt)
 Free PXE base code.
static LIST_HEAD (efi_pxes)
 List of PXE base codes.
static struct efi_pxeefi_pxe_find (EFI_HANDLE handle)
 Locate PXE base code.
static void efi_pxe_ip_sockaddr (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, struct sockaddr *sa)
 Populate socket address from EFI IP address.
static const char * efi_pxe_ip_ntoa (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
 Transcribe EFI IP address (for debugging).
static int efi_pxe_ip (struct efi_pxe *pxe)
 Populate local IP address.
static int efi_pxe_ip_filter (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
 Check if IP address matches filter.
static void efi_pxe_tftp_close (struct efi_pxe *pxe, int rc)
 Close PXE (M)TFTP download interface.
static size_t efi_pxe_tftp_window (struct efi_pxe *pxe)
 Check PXE (M)TFTP download flow control window.
static int efi_pxe_tftp_deliver (struct efi_pxe *pxe, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive new PXE (M)TFTP download data.
static int efi_pxe_tftp_open (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, const char *filename)
 Open (M)TFTP download interface.
static void efi_pxe_udp_close (struct efi_pxe *pxe, int rc)
 Close UDP interface.
static int efi_pxe_udp_deliver (struct efi_pxe *pxe, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive UDP packet.
static int efi_pxe_udp_open (struct efi_pxe *pxe)
 Open UDP interface.
static void efi_pxe_udp_schedule_close (struct efi_pxe *pxe)
 Schedule close of UDP interface.
static void efi_pxe_udp_scheduled_close (struct efi_pxe *pxe)
 Scheduled close of UDP interface.
static const char * efi_pxe_fake_name (struct efi_pxe *pxe, EFI_PXE_BASE_CODE_PACKET *packet)
 Name fake DHCP packet.
static BOOLEAN efi_pxe_fake (struct efi_pxe *pxe, int(*fake)(struct net_device *netdev, void *data, size_t len), EFI_PXE_BASE_CODE_PACKET *packet)
 Construct fake DHCP packet and flag.
static void efi_pxe_fake_all (struct efi_pxe *pxe)
 Construct fake DHCP packets.
static EFI_STATUS EFIAPI efi_pxe_start (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
 Start PXE base code.
static EFI_STATUS EFIAPI efi_pxe_stop (EFI_PXE_BASE_CODE_PROTOCOL *base)
 Stop PXE base code.
static EFI_STATUS EFIAPI efi_pxe_dhcp (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
 Perform DHCP.
static EFI_STATUS EFIAPI efi_pxe_discover (EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 type, UINT16 *layer, BOOLEAN bis, EFI_PXE_BASE_CODE_DISCOVER_INFO *info)
 Perform boot server discovery.
static EFI_STATUS EFIAPI efi_pxe_mtftp (EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_PXE_BASE_CODE_TFTP_OPCODE opcode, VOID *data, BOOLEAN overwrite, UINT64 *len, UINTN *blksize, EFI_IP_ADDRESS *ip, UINT8 *filename, EFI_PXE_BASE_CODE_MTFTP_INFO *info, BOOLEAN callback)
 Perform (M)TFTP.
static EFI_STATUS EFIAPI efi_pxe_udp_write (EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags, EFI_IP_ADDRESS *dest_ip, EFI_PXE_BASE_CODE_UDP_PORT *dest_port, EFI_IP_ADDRESS *gateway, EFI_IP_ADDRESS *src_ip, EFI_PXE_BASE_CODE_UDP_PORT *src_port, UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data)
 Transmit UDP packet.
static EFI_STATUS EFIAPI efi_pxe_udp_read (EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags, EFI_IP_ADDRESS *dest_ip, EFI_PXE_BASE_CODE_UDP_PORT *dest_port, EFI_IP_ADDRESS *src_ip, EFI_PXE_BASE_CODE_UDP_PORT *src_port, UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data)
 Receive UDP packet.
static EFI_STATUS EFIAPI efi_pxe_set_ip_filter (EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_PXE_BASE_CODE_IP_FILTER *filter)
 Set receive filter.
static EFI_STATUS EFIAPI efi_pxe_arp (EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac)
 Resolve MAC address.
static EFI_STATUS EFIAPI efi_pxe_set_parameters (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN *autoarp, BOOLEAN *sendguid, UINT8 *ttl, UINT8 *tos, BOOLEAN *callback)
 Set parameters.
static EFI_STATUS EFIAPI efi_pxe_set_station_ip (EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_IP_ADDRESS *ip, EFI_IP_ADDRESS *netmask)
 Set IP address.
static EFI_STATUS EFIAPI efi_pxe_set_packets (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN *dhcpdisc_ok, BOOLEAN *dhcpack_ok, BOOLEAN *proxyoffer_ok, BOOLEAN *pxebsdisc_ok, BOOLEAN *pxebsack_ok, BOOLEAN *pxebsbis_ok, EFI_PXE_BASE_CODE_PACKET *dhcpdisc, EFI_PXE_BASE_CODE_PACKET *dhcpack, EFI_PXE_BASE_CODE_PACKET *proxyoffer, EFI_PXE_BASE_CODE_PACKET *pxebsdisc, EFI_PXE_BASE_CODE_PACKET *pxebsack, EFI_PXE_BASE_CODE_PACKET *pxebsbis)
 Update cached DHCP packets.
static EFI_STATUS EFIAPI efi_apple_get_response (EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len, VOID *data)
 Get DHCP/BSDP response.
static EFI_STATUS EFIAPI efi_apple_get_dhcp_response (EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
 Get DHCP response.
static EFI_STATUS EFIAPI efi_apple_get_bsdp_response (EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
 Get BSDP response.
int efi_pxe_install (EFI_HANDLE handle, struct net_device *netdev)
 Install PXE base code protocol.
void efi_pxe_uninstall (EFI_HANDLE handle)
 Uninstall PXE base code protocol.

Variables

static struct interface_operation efi_pxe_tftp_operations []
 PXE file data transfer interface operations.
static struct interface_descriptor efi_pxe_tftp_desc
 PXE file data transfer interface descriptor.
static struct interface_operation efi_pxe_udp_operations []
 PXE UDP interface operations.
static struct interface_descriptor efi_pxe_udp_desc
 PXE UDP interface descriptor.
static struct process_descriptor efi_pxe_process_desc
 UDP close process descriptor.
static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol
 PXE base code protocol.
static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol
 Apple NetBoot protocol.

Detailed Description

EFI PXE base code protocol.

Definition in file efi_pxe.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_pxe_free()

void efi_pxe_free ( struct refcnt * refcnt)
static

Free PXE base code.

Parameters
refcntReference count

Definition at line 119 of file efi_pxe.c.

119 {
120 struct efi_pxe *pxe = container_of ( refcnt, struct efi_pxe, refcnt );
121
122 netdev_put ( pxe->netdev );
123 free ( pxe );
124}
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A PXE base code.
Definition efi_pxe.c:70
struct net_device * netdev
Underlying network device.
Definition efi_pxe.c:74
A reference counter.
Definition refcnt.h:27

References container_of, free, efi_pxe::netdev, and netdev_put().

Referenced by efi_pxe_install().

◆ LIST_HEAD()

LIST_HEAD ( efi_pxes )
static

List of PXE base codes.

◆ efi_pxe_find()

struct efi_pxe * efi_pxe_find ( EFI_HANDLE handle)
static

Locate PXE base code.

Parameters
handleEFI handle
Return values
Preboot eXecution Environment (PXE) APIPXE base code, or NULL

Definition at line 135 of file efi_pxe.c.

135 {
136 struct efi_pxe *pxe;
137
138 /* Locate base code */
139 list_for_each_entry ( pxe, &efi_pxes, list ) {
140 if ( pxe->handle == handle )
141 return pxe;
142 }
143
144 return NULL;
145}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
uint16_t handle
Handle.
Definition smbios.h:5
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
struct list_head list
List of PXE base codes.
Definition efi_pxe.c:78
EFI_HANDLE handle
Installed handle.
Definition efi_pxe.c:81

References EFI_HANDLE, efi_pxe::handle, handle, efi_pxe::list, list_for_each_entry, and NULL.

Referenced by efi_pxe_uninstall().

◆ efi_pxe_ip_sockaddr()

void efi_pxe_ip_sockaddr ( struct efi_pxe * pxe,
EFI_IP_ADDRESS * ip,
struct sockaddr * sa )
static

Populate socket address from EFI IP address.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
ipEFI IP address
saSocket address to fill in

Definition at line 194 of file efi_pxe.c.

195 {
196 union {
197 struct sockaddr sa;
198 struct sockaddr_efi se;
199 } *sockaddr = container_of ( sa, typeof ( *sockaddr ), sa );
200
201 /* Initialise socket address */
202 memset ( sockaddr, 0, sizeof ( *sockaddr ) );
203 sockaddr->sa.sa_family = pxe->tcpip->sa_family;
204 memcpy ( &sockaddr->se.se_addr, ip, pxe->net->net_addr_len );
205 sockaddr->se.se_scope_id = pxe->netdev->scope_id;
206}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
IP4_t ip
Destination IP address.
Definition pxe_api.h:1
struct tcpip_net_protocol * tcpip
TCP/IP network-layer protocol.
Definition efi_pxe.c:90
struct net_protocol * net
Network-layer protocol.
Definition efi_pxe.c:92
unsigned int scope_id
Scope ID.
Definition netdevice.h:361
uint8_t net_addr_len
Network-layer address length.
Definition netdevice.h:102
An EFI socket address.
Definition efi_pxe.c:158
Generalized socket address structure.
Definition socket.h:97
sa_family_t sa_family
Socket address family.
Definition socket.h:102
sa_family_t sa_family
Network address family.
Definition tcpip.h:145
struct sockaddr sa
Definition syslog.c:57

References container_of, ip, memcpy(), memset(), efi_pxe::net, net_protocol::net_addr_len, efi_pxe::netdev, sa, sockaddr::sa_family, tcpip_net_protocol::sa_family, net_device::scope_id, efi_pxe::tcpip, and typeof().

Referenced by efi_pxe_tftp_open(), and efi_pxe_udp_write().

◆ efi_pxe_ip_ntoa()

const char * efi_pxe_ip_ntoa ( struct efi_pxe * pxe,
EFI_IP_ADDRESS * ip )
static

Transcribe EFI IP address (for debugging).

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
ipEFI IP address
Return values
textTranscribed IP address

Definition at line 215 of file efi_pxe.c.

216 {
217
218 return pxe->net->ntoa ( ip );
219}
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition netdevice.h:95

References ip, efi_pxe::net, and net_protocol::ntoa.

Referenced by efi_pxe_arp(), efi_pxe_discover(), efi_pxe_mtftp(), efi_pxe_set_ip_filter(), efi_pxe_set_station_ip(), efi_pxe_tftp_open(), efi_pxe_udp_read(), and efi_pxe_udp_write().

◆ efi_pxe_ip()

int efi_pxe_ip ( struct efi_pxe * pxe)
static

Populate local IP address.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
Return values
rcReturn status code

Definition at line 227 of file efi_pxe.c.

227 {
229 struct in_addr address;
230 struct in_addr netmask;
231
232 /* It's unclear which of the potentially many IPv6 addresses
233 * is supposed to be used.
234 */
235 if ( mode->UsingIpv6 )
236 return -ENOTSUP;
237
238 /* Fetch IP address and subnet mask */
240 &address );
242 &netmask );
243
244 /* Populate IP address and subnet mask */
245 memset ( &mode->StationIp, 0, sizeof ( mode->StationIp ) );
246 memcpy ( &mode->StationIp, &address, sizeof ( address ) );
247 memset ( &mode->SubnetMask, 0, sizeof ( mode->SubnetMask ) );
248 memcpy ( &mode->SubnetMask, &netmask, sizeof ( netmask ) );
249
250 return 0;
251}
const struct setting ip_setting
const struct setting netmask_setting
uint64_t address
Base address.
Definition ena.h:13
uint16_t mode
Acceleration mode.
Definition ena.h:15
#define ENOTSUP
Operation not supported.
Definition errno.h:633
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:590
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913
EFI_PXE_BASE_CODE_MODE.
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition efi_pxe.c:85
IP address structure.
Definition in.h:42

References address, ENOTSUP, fetch_ipv4_setting(), ip_setting, memcpy(), memset(), efi_pxe::mode, mode, efi_pxe::netdev, netdev_settings(), and netmask_setting.

Referenced by efi_pxe_dhcp(), and efi_pxe_start().

◆ efi_pxe_ip_filter()

int efi_pxe_ip_filter ( struct efi_pxe * pxe,
EFI_IP_ADDRESS * ip )
static

Check if IP address matches filter.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
ipEFI IP address
Return values
is_matchIP address matches filter

Definition at line 260 of file efi_pxe.c.

260 {
263 uint8_t filters = filter->Filters;
264 union {
266 struct in_addr in;
267 struct in6_addr in6;
268 } *u = container_of ( ip, typeof ( *u ), ip );
269 size_t addr_len = pxe->net->net_addr_len;
270 unsigned int max;
271 unsigned int i;
272
273 /* Match everything, if applicable */
275 return 1;
276
277 /* Match all multicasts, if applicable */
279 if ( mode->UsingIpv6 ) {
280 if ( IN6_IS_ADDR_MULTICAST ( &u->in6 ) )
281 return 1;
282 } else {
283 if ( IN_IS_MULTICAST ( u->in.s_addr ) )
284 return 1;
285 }
286 }
287
288 /* Match IPv4 broadcasts, if applicable */
290 if ( ( ! mode->UsingIpv6 ) &&
291 ( u->in.s_addr == INADDR_BROADCAST ) )
292 return 1;
293 }
294
295 /* Match station address, if applicable */
297 if ( memcmp ( ip, &mode->StationIp, addr_len ) == 0 )
298 return 1;
299 }
300
301 /* Match explicit addresses, if applicable */
302 max = ( sizeof ( filter->IpList ) / sizeof ( filter->IpList[0] ) );
303 for ( i = 0 ; ( ( i < filter->IpCnt ) && ( i < max ) ) ; i++ ) {
304 if ( memcmp ( ip, &filter->IpList[i], addr_len ) == 0 )
305 return 1;
306 }
307
308 return 0;
309}
__be32 in[4]
Definition CIB_PRM.h:7
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition PxeBaseCode.h:85
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition PxeBaseCode.h:84
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition PxeBaseCode.h:86
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST
Definition PxeBaseCode.h:87
unsigned char uint8_t
Definition stdint.h:10
#define max(x, y)
Definition ath.h:41
union @104331263140136355135267063077374276003064103115 u
#define INADDR_BROADCAST
Definition in.h:22
#define IN6_IS_ADDR_MULTICAST(addr)
Definition in.h:68
#define IN_IS_MULTICAST(addr)
Definition in.h:34
UINT8_t filter
Receive packet filter.
Definition pxe_api.h:11
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
IP Receive Filter structure.
Definition PxeBaseCode.h:77
IP6 address structure.
Definition in.h:51
16-byte buffer aligned on a 4-byte boundary.

References container_of, EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST, EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS, EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST, EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP, filter, in, IN6_IS_ADDR_MULTICAST, IN_IS_MULTICAST, INADDR_BROADCAST, ip, max, memcmp(), efi_pxe::mode, mode, efi_pxe::net, net_protocol::net_addr_len, typeof(), and u.

Referenced by efi_pxe_udp_read().

◆ efi_pxe_tftp_close()

void efi_pxe_tftp_close ( struct efi_pxe * pxe,
int rc )
static

Close PXE (M)TFTP download interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
rcReason for close

Definition at line 324 of file efi_pxe.c.

324 {
325
326 /* Restart interface */
327 intf_restart ( &pxe->tftp, rc );
328
329 /* Record overall status */
330 pxe->rc = rc;
331}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
struct interface tftp
(M)TFTP download interface
Definition efi_pxe.c:98
int rc
Overall return status.
Definition efi_pxe.c:104

References intf_restart(), efi_pxe::rc, rc, and efi_pxe::tftp.

Referenced by efi_pxe_mtftp(), efi_pxe_stop(), and efi_pxe_tftp_deliver().

◆ efi_pxe_tftp_window()

size_t efi_pxe_tftp_window ( struct efi_pxe * pxe)
static

Check PXE (M)TFTP download flow control window.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
Return values
lenLength of window

Definition at line 339 of file efi_pxe.c.

339 {
340
341 /* Return requested blocksize */
342 return pxe->blksize;
343}
size_t blksize
Block size (for TFTP).
Definition efi_pxe.c:102

References efi_pxe::blksize.

◆ efi_pxe_tftp_deliver()

int efi_pxe_tftp_deliver ( struct efi_pxe * pxe,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Receive new PXE (M)TFTP download data.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
iobufI/O buffer
metaTransfer metadata
Return values
rcReturn status code

Definition at line 353 of file efi_pxe.c.

355 {
356 int rc;
357
358 /* Deliver to data transfer buffer */
359 if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
360 meta ) ) != 0 )
361 goto done;
362
363 /* Stop when filesize is known, if applicable */
365 ( meta->flags & XFER_FL_ABS_OFFSET ) ) {
366 goto done;
367 }
368
369 return 0;
370
371 done:
372 efi_pxe_tftp_close ( pxe, rc );
373 return rc;
374}
@ EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE
struct bofm_section_header done
Definition bofm_test.c:46
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition efi_pxe.c:324
uint8_t meta
Metadata flags.
Definition ena.h:3
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
unsigned int opcode
Opcode.
Definition efi_pxe.c:100
struct xfer_buffer buf
Data transfer buffer.
Definition efi_pxe.c:95
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48
int xferbuf_deliver(struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Add received data to data transfer buffer.
Definition xferbuf.c:198

References efi_pxe::buf, done, EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, efi_pxe_tftp_close(), iob_disown, meta, efi_pxe::opcode, rc, XFER_FL_ABS_OFFSET, and xferbuf_deliver().

◆ efi_pxe_tftp_open()

int efi_pxe_tftp_open ( struct efi_pxe * pxe,
EFI_IP_ADDRESS * ip,
const char * filename )
static

Open (M)TFTP download interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
ipEFI IP address
filenameFilename
Return values
rcReturn status code

Definition at line 395 of file efi_pxe.c.

396 {
397 struct sockaddr server;
398 struct uri *uri;
399 int rc;
400
401 /* Parse server address and filename */
402 efi_pxe_ip_sockaddr ( pxe, ip, &server );
403 uri = pxe_uri ( &server, filename );
404 if ( ! uri ) {
405 DBGC ( pxe, "PXE %s could not parse %s:%s\n", pxe->name,
406 efi_pxe_ip_ntoa ( pxe, ip ), filename );
407 rc = -ENOTSUP;
408 goto err_parse;
409 }
410
411 /* Open URI */
412 if ( ( rc = xfer_open_uri ( &pxe->tftp, uri ) ) != 0 ) {
413 DBGC ( pxe, "PXE %s could not open: %s\n",
414 pxe->name, strerror ( rc ) );
415 goto err_open;
416 }
417
418 err_open:
419 uri_put ( uri );
420 err_parse:
421 return rc;
422}
static void efi_pxe_ip_sockaddr(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, struct sockaddr *sa)
Populate socket address from EFI IP address.
Definition efi_pxe.c:194
static const char * efi_pxe_ip_ntoa(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
Transcribe EFI IP address (for debugging).
Definition efi_pxe.c:215
#define DBGC(...)
Definition compiler.h:530
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition open.c:68
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
const char * name
Name.
Definition efi_pxe.c:76
A Uniform Resource Identifier.
Definition uri.h:65
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition uri.c:810
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206

References DBGC, efi_pxe_ip_ntoa(), efi_pxe_ip_sockaddr(), ENOTSUP, ip, efi_pxe::name, pxe_uri(), rc, strerror(), efi_pxe::tftp, uri_put(), and xfer_open_uri().

Referenced by efi_pxe_mtftp().

◆ efi_pxe_udp_close()

void efi_pxe_udp_close ( struct efi_pxe * pxe,
int rc )
static

Close UDP interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
rcReason for close

Definition at line 447 of file efi_pxe.c.

447 {
448 struct io_buffer *iobuf;
449 struct io_buffer *tmp;
450
451 /* Release our claim on SNP devices, if applicable */
452 if ( process_running ( &pxe->process ) )
454
455 /* Stop process */
456 process_del ( &pxe->process );
457
458 /* Restart UDP interface */
459 intf_restart ( &pxe->udp, rc );
460
461 /* Flush any received UDP packets */
462 list_for_each_entry_safe ( iobuf, tmp, &pxe->queue, list ) {
463 list_del ( &iobuf->list );
464 free_iob ( iobuf );
465 }
466}
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition efi_snp.h:100
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
static int process_running(struct process *process)
Check if process is running.
Definition process.h:176
struct interface udp
UDP interface.
Definition efi_pxe.c:107
struct list_head queue
List of received UDP packets.
Definition efi_pxe.c:109
struct process process
UDP interface closer process.
Definition efi_pxe.c:111
A persistent I/O buffer.
Definition iobuf.h:98
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:105

References efi_snp_release(), free_iob(), intf_restart(), io_buffer::list, list_del, list_for_each_entry_safe, efi_pxe::process, process_del(), process_running(), efi_pxe::queue, rc, tmp, and efi_pxe::udp.

Referenced by efi_pxe_stop(), and efi_pxe_udp_scheduled_close().

◆ efi_pxe_udp_deliver()

int efi_pxe_udp_deliver ( struct efi_pxe * pxe,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Receive UDP packet.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 476 of file efi_pxe.c.

477 {
478 struct sockaddr_efi *se_src;
479 struct sockaddr_efi *se_dest;
480 struct tcpip_net_protocol *tcpip;
481 struct net_protocol *net;
482 struct efi_pxe_udp_pseudo_header *pshdr;
483 size_t addr_len;
484 size_t pshdr_len;
485 int rc;
486
487 /* Sanity checks */
488 assert ( meta != NULL );
489 se_src = ( ( struct sockaddr_efi * ) meta->src );
490 assert ( se_src != NULL );
491 se_dest = ( ( struct sockaddr_efi * ) meta->dest );
492 assert ( se_dest != NULL );
493 assert ( se_src->se_family == se_dest->se_family );
494
495 /* Determine protocol */
496 tcpip = tcpip_net_protocol ( se_src->se_family );
497 if ( ! tcpip ) {
498 rc = -ENOTSUP;
499 goto err_unsupported;
500 }
501 net = tcpip->net_protocol;
502 addr_len = net->net_addr_len;
503
504 /* Construct pseudo-header */
505 pshdr_len = ( sizeof ( *pshdr ) + ( 2 * addr_len ) );
506 if ( ( rc = iob_ensure_headroom ( iobuf, pshdr_len ) ) != 0 )
507 goto err_headroom;
508 memcpy ( iob_push ( iobuf, addr_len ), &se_src->se_addr, addr_len );
509 memcpy ( iob_push ( iobuf, addr_len ), &se_dest->se_addr, addr_len );
510 pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
511 pshdr->net = net;
512 pshdr->dest_port = ntohs ( se_dest->se_port );
513 pshdr->src_port = ntohs ( se_src->se_port );
514
515 /* Add to queue */
516 list_add_tail ( &iobuf->list, &pxe->queue );
517
518 return 0;
519
520 err_unsupported:
521 err_headroom:
522 free_iob ( iobuf );
523 return rc;
524}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
#define ntohs(value)
Definition byteswap.h:137
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition iobuf.c:235
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
EFI UDP pseudo-header.
Definition efi_pxe.c:432
struct net_protocol * net
Network-layer protocol.
Definition efi_pxe.c:434
uint16_t src_port
Source port.
Definition efi_pxe.c:438
uint16_t dest_port
Destination port.
Definition efi_pxe.c:436
A network-layer protocol.
Definition netdevice.h:65
sa_family_t se_family
Socket address family (part of struct sockaddr).
Definition efi_pxe.c:160
uint16_t se_port
TCP/IP port (part of struct sockaddr_tcpip).
Definition efi_pxe.c:164
EFI_IP_ADDRESS se_addr
IP address.
Definition efi_pxe.c:172
A network-layer protocol of the TCP/IP stack (eg.
Definition tcpip.h:141
struct net_protocol * net_protocol
Network-layer protocol.
Definition tcpip.h:149
struct tcpip_net_protocol * tcpip_net_protocol(sa_family_t sa_family)
Find TCP/IP network-layer protocol.
Definition tcpip.c:69

References assert, efi_pxe_udp_pseudo_header::dest_port, ENOTSUP, free_iob(), iob_ensure_headroom(), iob_push, io_buffer::list, list_add_tail, memcpy(), meta, efi_pxe_udp_pseudo_header::net, net_protocol::net_addr_len, tcpip_net_protocol::net_protocol, ntohs, NULL, efi_pxe::queue, rc, sockaddr_efi::se_addr, sockaddr_efi::se_family, sockaddr_efi::se_port, efi_pxe_udp_pseudo_header::src_port, and tcpip_net_protocol().

◆ efi_pxe_udp_open()

int efi_pxe_udp_open ( struct efi_pxe * pxe)
static

Open UDP interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
Return values
rcReturn status code

Definition at line 542 of file efi_pxe.c.

542 {
543 int rc;
544
545 /* If interface is already open, then cancel the scheduled close */
546 if ( process_running ( &pxe->process ) ) {
547 process_del ( &pxe->process );
548 return 0;
549 }
550
551 /* Open promiscuous UDP interface */
552 if ( ( rc = udp_open_promisc ( &pxe->udp ) ) != 0 ) {
553 DBGC ( pxe, "PXE %s could not open UDP connection: %s\n",
554 pxe->name, strerror ( rc ) );
555 return rc;
556 }
557
558 /* Claim network devices */
560
561 return 0;
562}
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition efi_snp.h:92
int udp_open_promisc(struct interface *xfer)
Open a promiscuous UDP connection.
Definition udp.c:145

References DBGC, efi_snp_claim(), efi_pxe::name, efi_pxe::process, process_del(), process_running(), rc, strerror(), efi_pxe::udp, and udp_open_promisc().

Referenced by efi_pxe_udp_read(), and efi_pxe_udp_write().

◆ efi_pxe_udp_schedule_close()

void efi_pxe_udp_schedule_close ( struct efi_pxe * pxe)
static

Schedule close of UDP interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code

Definition at line 569 of file efi_pxe.c.

569 {
570
571 /* The EFI PXE base code protocol does not provide any
572 * explicit UDP open/close methods. To avoid the overhead of
573 * reopening a socket for each read/write operation, we start
574 * a process which will close the socket immediately if the
575 * next call into iPXE is anything other than a UDP
576 * read/write.
577 */
578 process_add ( &pxe->process );
579}
void process_add(struct process *process)
Add process to process list.
Definition process.c:60

References efi_pxe::process, and process_add().

Referenced by efi_pxe_udp_read(), and efi_pxe_udp_write().

◆ efi_pxe_udp_scheduled_close()

void efi_pxe_udp_scheduled_close ( struct efi_pxe * pxe)
static

Scheduled close of UDP interface.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code

Definition at line 586 of file efi_pxe.c.

586 {
587
588 /* Close UDP interface */
589 efi_pxe_udp_close ( pxe, 0 );
590}
static void efi_pxe_udp_close(struct efi_pxe *pxe, int rc)
Close UDP interface.
Definition efi_pxe.c:447

References efi_pxe_udp_close().

◆ efi_pxe_fake_name()

const char * efi_pxe_fake_name ( struct efi_pxe * pxe,
EFI_PXE_BASE_CODE_PACKET * packet )
static

Name fake DHCP packet.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
packetPacket
Return values
nameName of packet

Definition at line 610 of file efi_pxe.c.

611 {
613
614 if ( packet == &mode->DhcpDiscover ) {
615 return "DhcpDiscover";
616 } else if ( packet == &mode->DhcpAck ) {
617 return "DhcpAck";
618 } else if ( packet == &mode->ProxyOffer ) {
619 return "ProxyOffer";
620 } else if ( packet == &mode->PxeDiscover ) {
621 return "PxeDiscover";
622 } else if ( packet == &mode->PxeReply ) {
623 return "PxeReply";
624 } else if ( packet == &mode->PxeBisReply ) {
625 return "PxeBisReply";
626 } else {
627 return "<UNKNOWN>";
628 }
629}

References efi_pxe::mode, and mode.

Referenced by efi_pxe_fake().

◆ efi_pxe_fake()

BOOLEAN efi_pxe_fake ( struct efi_pxe * pxe,
int(* fake )(struct net_device *netdev, void *data, size_t len),
EFI_PXE_BASE_CODE_PACKET * packet )
static

Construct fake DHCP packet and flag.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code
fakeFake packet constructor
packetPacket to fill in
Return values
existsPacket existence flag

Definition at line 639 of file efi_pxe.c.

642 {
644 struct dhcp_packet dhcppkt;
645 struct dhcphdr *dhcphdr;
646 unsigned int len;
647 int rc;
648
649 /* The fake packet constructors do not support IPv6 */
650 if ( mode->UsingIpv6 )
651 return FALSE;
652
653 /* Attempt to construct packet */
654 if ( ( rc = fake ( pxe->netdev, packet, sizeof ( *packet ) ) != 0 ) ) {
655 DBGC ( pxe, "PXE %s could not fake %s: %s\n", pxe->name,
656 efi_pxe_fake_name ( pxe, packet ), strerror ( rc ) );
657 return FALSE;
658 }
659
660 /* The WDS bootstrap wdsmgfw.efi has a buggy DHCPv4 packet
661 * parser which does not correctly handle DHCP padding bytes.
662 * Specifically, if a padding byte (i.e. a zero) is
663 * encountered, the parse will first increment the pointer by
664 * one to skip over the padding byte but will then drop into
665 * the code path for handling normal options, which increments
666 * the pointer by two to skip over the (already-skipped) type
667 * field and the (non-existent) length field.
668 *
669 * The upshot of this bug in WDS is that the parser will fail
670 * with an error 0xc0000023 if the number of spare bytes after
671 * the end of the options is not an exact multiple of three.
672 *
673 * Work around this buggy parser by adding an explicit
674 * DHCP_END tag.
675 */
677 struct dhcphdr, op );
678 dhcppkt_init ( &dhcppkt, dhcphdr, sizeof ( *packet ) );
679 len = dhcppkt_len ( &dhcppkt );
680 if ( len < sizeof ( *packet ) )
681 packet->Raw[len] = DHCP_END;
682
683 return TRUE;
684}
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition dhcppkt.c:301
static size_t dhcppkt_len(struct dhcp_packet *dhcppkt)
Get used length of DHCP packet.
Definition dhcppkt.h:60
ring len
Length.
Definition dwmac.h:226
static const char * efi_pxe_fake_name(struct efi_pxe *pxe, EFI_PXE_BASE_CODE_PACKET *packet)
Name fake DHCP packet.
Definition efi_pxe.c:610
#define DHCP_END
End of options.
Definition dhcp.h:549
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
A DHCP packet.
Definition dhcppkt.h:21
A DHCP header.
Definition dhcp.h:616
#define TRUE
Definition tlan.h:46
#define FALSE
Definition tlan.h:45
EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4

References EFI_PXE_BASE_CODE_DHCPV4_PACKET::BootpOpcode, container_of, data, DBGC, DHCP_END, dhcppkt_init(), dhcppkt_len(), EFI_PXE_BASE_CODE_PACKET::Dhcpv4, efi_pxe_fake_name(), FALSE, len, efi_pxe::mode, mode, efi_pxe::name, efi_pxe::netdev, netdev, op, EFI_PXE_BASE_CODE_PACKET::Raw, rc, strerror(), and TRUE.

Referenced by efi_pxe_fake_all().

◆ efi_pxe_fake_all()

void efi_pxe_fake_all ( struct efi_pxe * pxe)
static

Construct fake DHCP packets.

Parameters
Preboot eXecution Environment (PXE) APIPXE base code

Definition at line 691 of file efi_pxe.c.

691 {
693
694 /* Construct fake packets */
695 mode->DhcpDiscoverValid =
697 &mode->DhcpDiscover );
698 mode->DhcpAckReceived =
700 &mode->DhcpAck );
701 mode->PxeReplyReceived =
703 &mode->PxeReply );
704}
static BOOLEAN efi_pxe_fake(struct efi_pxe *pxe, int(*fake)(struct net_device *netdev, void *data, size_t len), EFI_PXE_BASE_CODE_PACKET *packet)
Construct fake DHCP packet and flag.
Definition efi_pxe.c:639
int create_fakedhcpdiscover(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPDISCOVER packet.
Definition fakedhcp.c:110
int create_fakepxebsack(struct net_device *netdev, void *data, size_t max_len)
Create fake PXE Boot Server ACK packet.
Definition fakedhcp.c:179
int create_fakedhcpack(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPACK packet.
Definition fakedhcp.c:137

References create_fakedhcpack(), create_fakedhcpdiscover(), create_fakepxebsack(), efi_pxe_fake(), efi_pxe::mode, and mode.

Referenced by efi_pxe_dhcp(), and efi_pxe_start().

◆ efi_pxe_start()

EFI_STATUS EFIAPI efi_pxe_start ( EFI_PXE_BASE_CODE_PROTOCOL * base,
BOOLEAN use_ipv6 )
static

Start PXE base code.

Parameters
basePXE base code protocol
use_ipv6Use IPv6
Return values
efircEFI status code

Definition at line 720 of file efi_pxe.c.

721 {
722 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
725 sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
726 int rc;
727
728 DBGC ( pxe, "PXE %s START %s\n",
729 pxe->name, ( use_ipv6 ? "IPv6" : "IPv4" ) );
730
731 /* Initialise mode structure */
732 memset ( mode, 0, sizeof ( *mode ) );
733 mode->AutoArp = TRUE;
734 mode->TTL = DEFAULT_TTL;
735 mode->ToS = DEFAULT_ToS;
736 mode->IpFilter.Filters =
741
742 /* Check for IPv4/IPv6 support */
743 mode->Ipv6Supported = ( ipv6 != NULL );
744 mode->Ipv6Available = ( ipv6 != NULL );
745 pxe->tcpip = tcpip_net_protocol ( family );
746 if ( ! pxe->tcpip ) {
747 DBGC ( pxe, "PXE %s has no support for %s\n",
748 pxe->name, socket_family_name ( family ) );
749 return EFI_UNSUPPORTED;
750 }
751 pxe->net = pxe->tcpip->net_protocol;
752 mode->UsingIpv6 = use_ipv6;
753
754 /* Populate station IP address */
755 if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
756 return rc;
757
758 /* Construct fake DHCP packets */
759 efi_pxe_fake_all ( pxe );
760
761 /* Record that base code is started */
762 mode->Started = TRUE;
763 DBGC ( pxe, "PXE %s using %s\n",
764 pxe->name, pxe->net->ntoa ( &mode->StationIp ) );
765
766 return 0;
767}
#define DEFAULT_ToS
Definition PxeBaseCode.h:40
#define DEFAULT_TTL
Default IP TTL and ToS.
Definition PxeBaseCode.h:39
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
static int efi_pxe_ip(struct efi_pxe *pxe)
Populate local IP address.
Definition efi_pxe.c:227
static void efi_pxe_fake_all(struct efi_pxe *pxe)
Construct fake DHCP packets.
Definition efi_pxe.c:691
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define AF_INET6
IPv6 Internet addresses.
Definition socket.h:65
uint32_t base
Base.
Definition librm.h:3
uint16_t sa_family_t
A socket address family.
Definition socket.h:86
static const char * socket_family_name(int family)
Name address family.
Definition socket.h:76

References AF_INET, AF_INET6, base, container_of, DBGC, DEFAULT_ToS, DEFAULT_TTL, EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST, EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS, EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST, EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP, efi_pxe_fake_all(), efi_pxe_ip(), EFI_UNSUPPORTED, EFIAPI, memset(), efi_pxe::mode, mode, efi_pxe::name, efi_pxe::net, tcpip_net_protocol::net_protocol, net_protocol::ntoa, NULL, rc, socket_family_name(), efi_pxe::tcpip, tcpip_net_protocol(), and TRUE.

Referenced by efi_pxe_install().

◆ efi_pxe_stop()

EFI_STATUS EFIAPI efi_pxe_stop ( EFI_PXE_BASE_CODE_PROTOCOL * base)
static

Stop PXE base code.

Parameters
basePXE base code protocol
Return values
efircEFI status code

Definition at line 775 of file efi_pxe.c.

775 {
776 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
778
779 DBGC ( pxe, "PXE %s STOP\n", pxe->name );
780
781 /* Record that base code is stopped */
782 mode->Started = FALSE;
783
784 /* Close TFTP */
785 efi_pxe_tftp_close ( pxe, 0 );
786
787 /* Close UDP */
788 efi_pxe_udp_close ( pxe, 0 );
789
790 return 0;
791}

References base, container_of, DBGC, efi_pxe_tftp_close(), efi_pxe_udp_close(), EFIAPI, FALSE, efi_pxe::mode, mode, and efi_pxe::name.

Referenced by efi_pxe_uninstall().

◆ efi_pxe_dhcp()

EFI_STATUS EFIAPI efi_pxe_dhcp ( EFI_PXE_BASE_CODE_PROTOCOL * base,
BOOLEAN sort )
static

Perform DHCP.

Parameters
basePXE base code protocol
sortOffers should be sorted
Return values
efircEFI status code

Definition at line 800 of file efi_pxe.c.

801 {
802 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
803 struct net_device *netdev = pxe->netdev;
804 int rc;
805
806 DBGC ( pxe, "PXE %s DHCP %s\n",
807 pxe->name, ( sort ? "sorted" : "unsorted" ) );
808
809 /* Claim network devices */
811
812 /* Initiate configuration */
813 if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
814 DBGC ( pxe, "PXE %s could not initiate configuration: %s\n",
815 pxe->name, strerror ( rc ) );
816 goto err_configure;
817 }
818
819 /* Wait for configuration to complete (or time out) */
821 step();
822
823 /* Report timeout if configuration failed */
824 if ( ! netdev_configuration_ok ( netdev ) ) {
825 rc = -ETIMEDOUT;
826 goto err_timeout;
827 }
828
829 /* Update station IP address */
830 if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
831 goto err_ip;
832
833 /* Update faked DHCP packets */
834 efi_pxe_fake_all ( pxe );
835
836 err_ip:
837 err_timeout:
838 err_configure:
840 return EFIRC ( rc );
841}
static struct net_device * netdev
Definition gdbudp.c:53
#define ETIMEDOUT
Connection timed out.
Definition errno.h:713
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:173
int netdev_configure_all(struct net_device *netdev)
Start network device configuration via all supported configurators.
Definition netdevice.c:1340
int netdev_configuration_ok(struct net_device *netdev)
Check if network device has at least one successful configuration.
Definition netdevice.c:1396
int netdev_configuration_in_progress(struct net_device *netdev)
Check if network device configuration is in progress.
Definition netdevice.c:1384
void step(void)
Single-step a single process.
Definition process.c:99
A network device.
Definition netdevice.h:353

References base, container_of, DBGC, efi_pxe_fake_all(), efi_pxe_ip(), efi_snp_claim(), efi_snp_release(), EFIAPI, EFIRC, ETIMEDOUT, efi_pxe::name, efi_pxe::netdev, netdev, netdev_configuration_in_progress(), netdev_configuration_ok(), netdev_configure_all(), rc, step(), and strerror().

◆ efi_pxe_discover()

EFI_STATUS EFIAPI efi_pxe_discover ( EFI_PXE_BASE_CODE_PROTOCOL * base,
UINT16 type,
UINT16 * layer,
BOOLEAN bis,
EFI_PXE_BASE_CODE_DISCOVER_INFO * info )
static

Perform boot server discovery.

Parameters
basePXE base code protocol
typeBoot server type
layerBoot server layer
bisUse boot integrity services
infoAdditional information
Return values
efircEFI status code

Definition at line 854 of file efi_pxe.c.

855 {
856 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
858 unsigned int i;
859
860 DBGC ( pxe, "PXE %s DISCOVER type %d layer %d%s\n",
861 pxe->name, type, *layer, ( bis ? " bis" : "" ) );
862 if ( info ) {
863 DBGC ( pxe, "%s%s%s%s %s",
864 ( info->UseMCast ? " mcast" : "" ),
865 ( info->UseBCast ? " bcast" : "" ),
866 ( info->UseUCast ? " ucast" : "" ),
867 ( info->MustUseList ? " list" : "" ),
868 efi_pxe_ip_ntoa ( pxe, &info->ServerMCastIp ) );
869 for ( i = 0 ; i < info->IpCnt ; i++ ) {
870 ip = &info->SrvList[i].IpAddr;
871 DBGC ( pxe, " %d%s:%s", info->SrvList[i].Type,
872 ( info->SrvList[i].AcceptAnyResponse ?
873 ":any" : "" ), efi_pxe_ip_ntoa ( pxe, ip ) );
874 }
875 }
876 DBGC ( pxe, "\n" );
877
878 /* Not used by any bootstrap I can find to test with */
879 return EFI_UNSUPPORTED;
880}
u32 info
Definition ar9003_mac.h:0
uint32_t type
Operating system type.
Definition ena.h:1

References base, container_of, DBGC, efi_pxe_ip_ntoa(), EFI_UNSUPPORTED, info, ip, efi_pxe::name, and type.

◆ efi_pxe_mtftp()

EFI_STATUS EFIAPI efi_pxe_mtftp ( EFI_PXE_BASE_CODE_PROTOCOL * base,
EFI_PXE_BASE_CODE_TFTP_OPCODE opcode,
VOID * data,
BOOLEAN overwrite,
UINT64 * len,
UINTN * blksize,
EFI_IP_ADDRESS * ip,
UINT8 * filename,
EFI_PXE_BASE_CODE_MTFTP_INFO * info,
BOOLEAN callback )
static

Perform (M)TFTP.

Parameters
basePXE base code protocol
opcodeTFTP opcode
dataData buffer
overwriteOverwrite file
lenLength of data buffer
blksizeBlock size
ipServer address
filenameFilename
infoAdditional information
callbackPass packets to callback instead of data buffer
Return values
efircEFI status code

Definition at line 898 of file efi_pxe.c.

902 {
903 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
904 int rc;
905
906 DBGC ( pxe, "PXE %s MTFTP %d%s %p+%llx", pxe->name, opcode,
907 ( overwrite ? " overwrite" : "" ), data, *len );
908 if ( blksize )
909 DBGC ( pxe, " blksize %zd", ( ( size_t ) *blksize ) );
910 DBGC ( pxe, " %s:%s", efi_pxe_ip_ntoa ( pxe, ip ), filename );
911 if ( info ) {
912 DBGC ( pxe, " %s:%d:%d:%d:%d",
913 efi_pxe_ip_ntoa ( pxe, &info->MCastIp ),
914 info->CPort, info->SPort, info->ListenTimeout,
915 info->TransmitTimeout );
916 }
917 DBGC ( pxe, "%s\n", ( callback ? " callback" : "" ) );
918
919 /* Fail unless operation is supported */
923 DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
924 pxe->name, opcode );
925 rc = -ENOTSUP;
926 goto err_opcode;
927 }
928
929 /* Claim network devices */
931
932 /* Determine block size. Ignore the requested block size
933 * unless we are using callbacks, since limiting HTTP to a
934 * 512-byte TCP window is not sensible.
935 */
936 pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
937
938 /* Initialise data transfer buffer */
939 memset ( &pxe->buf, 0, sizeof ( pxe->buf ) );
941 xferbuf_void_init ( &pxe->buf );
942 } else {
943 xferbuf_fixed_init ( &pxe->buf, data, *len );
944 }
945
946 /* Open download */
947 if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
948 ( ( const char * ) filename ) ) ) != 0 )
949 goto err_open;
950
951 /* Wait for download to complete */
952 pxe->opcode = opcode;
953 pxe->rc = -EINPROGRESS;
954 while ( pxe->rc == -EINPROGRESS )
955 step();
956 *len = pxe->buf.max;
957 if ( ( rc = pxe->rc ) != 0 ) {
958 DBGC ( pxe, "PXE %s MTFTP %d failed: %s\n",
959 pxe->name, opcode, strerror ( rc ) );
960 goto err_download;
961 }
962 DBGC ( pxe, "PXE %s MTFTP %d %p+%llx complete\n",
963 pxe->name, opcode, data, *len );
964
965 err_download:
966 efi_pxe_tftp_close ( pxe, rc );
967 err_open:
968 xferbuf_fixed_init ( &pxe->buf, NULL, 0 );
970 err_opcode:
971 return EFIRC ( rc );
972}
@ EFI_PXE_BASE_CODE_TFTP_READ_FILE
@ EFI_PXE_BASE_CODE_MTFTP_READ_FILE
int overwrite(const WINDOW *, WINDOW *)
static int efi_pxe_tftp_open(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, const char *filename)
Open (M)TFTP download interface.
Definition efi_pxe.c:395
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t opcode
Opcode.
Definition ena.h:5
#define EINPROGRESS
Operation in progress.
Definition errno.h:462
uint32_t blksize
Cipher block size.
Definition pccrr.h:1
size_t max
Maximum required size of data.
Definition xferbuf.h:27
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition xferbuf.h:93
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition xferbuf.h:108

References base, blksize, efi_pxe::blksize, efi_pxe::buf, container_of, data, DBGC, EFI_PXE_BASE_CODE_MTFTP_READ_FILE, EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, EFI_PXE_BASE_CODE_TFTP_READ_FILE, efi_pxe_ip_ntoa(), efi_pxe_tftp_close(), efi_pxe_tftp_open(), efi_snp_claim(), efi_snp_release(), EFIRC, EINPROGRESS, ENOTSUP, info, ip, len, xfer_buffer::max, memset(), efi_pxe::name, NULL, efi_pxe::opcode, opcode, overwrite(), efi_pxe::rc, rc, step(), strerror(), VOID, xferbuf_fixed_init(), and xferbuf_void_init().

◆ efi_pxe_udp_write()

EFI_STATUS EFIAPI efi_pxe_udp_write ( EFI_PXE_BASE_CODE_PROTOCOL * base,
UINT16 flags,
EFI_IP_ADDRESS * dest_ip,
EFI_PXE_BASE_CODE_UDP_PORT * dest_port,
EFI_IP_ADDRESS * gateway,
EFI_IP_ADDRESS * src_ip,
EFI_PXE_BASE_CODE_UDP_PORT * src_port,
UINTN * hdr_len,
VOID * hdr,
UINTN * len,
VOID * data )
static

Transmit UDP packet.

Parameters
basePXE base code protocol
flagsOperation flags
dest_ipDestination address
dest_portDestination port
gatewayGateway address
src_ipSource address
src_portSource port
hdr_lenHeader length
hdrHeader data
lenLength
dataData
Return values
efircEFI status code

Definition at line 991 of file efi_pxe.c.

996 {
997 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
999 struct io_buffer *iobuf;
1000 struct xfer_metadata meta;
1001 union {
1002 struct sockaddr_tcpip st;
1003 struct sockaddr sa;
1004 } dest;
1005 union {
1006 struct sockaddr_tcpip st;
1007 struct sockaddr sa;
1008 } src;
1009 int rc;
1010
1011 DBGC2 ( pxe, "PXE %s UDP WRITE ", pxe->name );
1012 if ( src_ip )
1013 DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1014 DBGC2 ( pxe, ":" );
1015 if ( src_port &&
1017 DBGC2 ( pxe, "%d", *src_port );
1018 } else {
1019 DBGC2 ( pxe, "*" );
1020 }
1021 DBGC2 ( pxe, "->%s:%d", efi_pxe_ip_ntoa ( pxe, dest_ip ), *dest_port );
1022 if ( gateway )
1023 DBGC2 ( pxe, " via %s", efi_pxe_ip_ntoa ( pxe, gateway ) );
1024 if ( hdr_len )
1025 DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1026 DBGC2 ( pxe, " %p+%zx", data, ( ( size_t ) *len ) );
1028 DBGC2 ( pxe, " frag" );
1029 DBGC2 ( pxe, "\n" );
1030
1031 /* Open UDP connection (if applicable) */
1032 if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1033 goto err_open;
1034
1035 /* Construct destination address */
1036 efi_pxe_ip_sockaddr ( pxe, dest_ip, &dest.sa );
1037 dest.st.st_port = htons ( *dest_port );
1038
1039 /* Construct source address */
1040 efi_pxe_ip_sockaddr ( pxe, ( src_ip ? src_ip : &mode->StationIp ),
1041 &src.sa );
1042 if ( src_port &&
1044 src.st.st_port = htons ( *src_port );
1045 } else {
1046 /* The API does not allow for a sensible concept of
1047 * binding to a local port, so just use a random value.
1048 */
1049 src.st.st_port = ( random() | htons ( 1024 ) );
1050 if ( src_port )
1051 *src_port = ntohs ( src.st.st_port );
1052 }
1053
1054 /* Allocate I/O buffer */
1055 iobuf = xfer_alloc_iob ( &pxe->udp,
1056 ( *len + ( hdr_len ? *hdr_len : 0 ) ) );
1057 if ( ! iobuf ) {
1058 rc = -ENOMEM;
1059 goto err_alloc;
1060 }
1061
1062 /* Populate I/O buffer */
1063 if ( hdr_len )
1064 memcpy ( iob_put ( iobuf, *hdr_len ), hdr, *hdr_len );
1065 memcpy ( iob_put ( iobuf, *len ), data, *len );
1066
1067 /* Construct metadata */
1068 memset ( &meta, 0, sizeof ( meta ) );
1069 meta.src = &src.sa;
1070 meta.dest = &dest.sa;
1071 meta.netdev = pxe->netdev;
1072
1073 /* Deliver I/O buffer */
1074 if ( ( rc = xfer_deliver ( &pxe->udp, iob_disown ( iobuf ),
1075 &meta ) ) != 0 ) {
1076 DBGC ( pxe, "PXE %s could not transmit: %s\n",
1077 pxe->name, strerror ( rc ) );
1078 goto err_deliver;
1079 }
1080
1081 err_deliver:
1082 free_iob ( iobuf );
1083 err_alloc:
1085 err_open:
1086 return EFIRC ( rc );
1087}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
static const void * src
Definition string.h:48
static int efi_pxe_udp_open(struct efi_pxe *pxe)
Open UDP interface.
Definition efi_pxe.c:542
static void efi_pxe_udp_schedule_close(struct efi_pxe *pxe)
Schedule close of UDP interface.
Definition efi_pxe.c:569
uint8_t flags
Flags.
Definition ena.h:7
#define DBGC2(...)
Definition compiler.h:547
#define ENOMEM
Not enough space.
Definition errno.h:578
#define htons(value)
Definition byteswap.h:136
#define iob_put(iobuf, len)
Definition iobuf.h:185
IP4_t dest_ip
Destination IP address.
Definition pxe_api.h:2
IP4_t src_ip
IP address of this station.
Definition pxe_api.h:1
UDP_PORT_t src_port
Source UDP port.
Definition pxe_api.h:3
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
Data transfer metadata.
Definition xfer.h:23
struct sockaddr_tcpip st
Definition syslog.c:58
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

References base, container_of, data, DBGC, DBGC2, dest, dest_ip, EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT, EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT, efi_pxe_ip_ntoa(), efi_pxe_ip_sockaddr(), efi_pxe_udp_open(), efi_pxe_udp_schedule_close(), EFIRC, ENOMEM, flags, free_iob(), hdr, htons, iob_disown, iob_put, len, memcpy(), memset(), meta, efi_pxe::mode, mode, efi_pxe::name, efi_pxe::netdev, ntohs, random(), rc, sa, src, src_ip, src_port, st, strerror(), efi_pxe::udp, VOID, xfer_alloc_iob(), and xfer_deliver().

◆ efi_pxe_udp_read()

EFI_STATUS EFIAPI efi_pxe_udp_read ( EFI_PXE_BASE_CODE_PROTOCOL * base,
UINT16 flags,
EFI_IP_ADDRESS * dest_ip,
EFI_PXE_BASE_CODE_UDP_PORT * dest_port,
EFI_IP_ADDRESS * src_ip,
EFI_PXE_BASE_CODE_UDP_PORT * src_port,
UINTN * hdr_len,
VOID * hdr,
UINTN * len,
VOID * data )
static

Receive UDP packet.

Parameters
basePXE base code protocol
flagsOperation flags
dest_ipDestination address
dest_portDestination port
src_ipSource address
src_portSource port
hdr_lenHeader length
hdrHeader data
lenLength
dataData
Return values
efircEFI status code

Definition at line 1105 of file efi_pxe.c.

1110 {
1111 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1112 struct io_buffer *iobuf;
1113 struct efi_pxe_udp_pseudo_header *pshdr;
1114 EFI_IP_ADDRESS *actual_dest_ip;
1115 EFI_IP_ADDRESS *actual_src_ip;
1116 size_t addr_len;
1117 size_t frag_len;
1118 int rc;
1119
1120 DBGC2 ( pxe, "PXE %s UDP READ ", pxe->name );
1122 DBGC2 ( pxe, "(filter)" );
1124 DBGC2 ( pxe, "*" );
1125 } else if ( dest_ip ) {
1126 DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, dest_ip ) );
1127 }
1128 DBGC2 ( pxe, ":" );
1130 DBGC2 ( pxe, "*" );
1131 } else if ( dest_port ) {
1132 DBGC2 ( pxe, "%d", *dest_port );
1133 } else {
1134 DBGC2 ( pxe, "<NULL>" );
1135 }
1136 DBGC2 ( pxe, "<-" );
1138 DBGC2 ( pxe, "*" );
1139 } else if ( src_ip ) {
1140 DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1141 } else {
1142 DBGC2 ( pxe, "<NULL>" );
1143 }
1144 DBGC2 ( pxe, ":" );
1146 DBGC2 ( pxe, "*" );
1147 } else if ( src_port ) {
1148 DBGC2 ( pxe, "%d", *src_port );
1149 } else {
1150 DBGC2 ( pxe, "<NULL>" );
1151 }
1152 if ( hdr_len )
1153 DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1154 DBGC2 ( pxe, " %p+%zx\n", data, ( ( size_t ) *len ) );
1155
1156 /* Open UDP connection (if applicable) */
1157 if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1158 goto err_open;
1159
1160 /* Try receiving a packet, if the queue is empty */
1161 if ( list_empty ( &pxe->queue ) )
1162 step();
1163
1164 /* Remove first packet from the queue */
1165 iobuf = list_first_entry ( &pxe->queue, struct io_buffer, list );
1166 if ( ! iobuf ) {
1167 rc = -ETIMEDOUT; /* "no packet" */
1168 goto err_empty;
1169 }
1170 list_del ( &iobuf->list );
1171
1172 /* Strip pseudo-header */
1173 pshdr = iobuf->data;
1174 addr_len = ( pshdr->net->net_addr_len );
1175 iob_pull ( iobuf, sizeof ( *pshdr ) );
1176 actual_dest_ip = iobuf->data;
1177 iob_pull ( iobuf, addr_len );
1178 actual_src_ip = iobuf->data;
1179 iob_pull ( iobuf, addr_len );
1180 DBGC2 ( pxe, "PXE %s UDP RX %s:%d", pxe->name,
1181 pshdr->net->ntoa ( actual_dest_ip ), pshdr->dest_port );
1182 DBGC2 ( pxe, "<-%s:%d len %#zx\n", pshdr->net->ntoa ( actual_src_ip ),
1183 pshdr->src_port, iob_len ( iobuf ) );
1184
1185 /* Filter based on network-layer protocol */
1186 if ( pshdr->net != pxe->net ) {
1187 DBGC2 ( pxe, "PXE %s filtered out %s packet\n",
1188 pxe->name, pshdr->net->name );
1189 rc = -ETIMEDOUT; /* "no packet" */
1190 goto err_filter;
1191 }
1192
1193 /* Filter based on port numbers */
1195 ( dest_port && ( *dest_port == pshdr->dest_port ) ) ) ) {
1196 DBGC2 ( pxe, "PXE %s filtered out destination port %d\n",
1197 pxe->name, pshdr->dest_port );
1198 rc = -ETIMEDOUT; /* "no packet" */
1199 goto err_filter;
1200 }
1202 ( src_port && ( *src_port == pshdr->src_port ) ) ) ) {
1203 DBGC2 ( pxe, "PXE %s filtered out source port %d\n",
1204 pxe->name, pshdr->src_port );
1205 rc = -ETIMEDOUT; /* "no packet" */
1206 goto err_filter;
1207 }
1208
1209 /* Filter based on source IP address */
1211 ( src_ip &&
1212 ( memcmp ( src_ip, actual_src_ip, addr_len ) == 0 ) ) ) ) {
1213 DBGC2 ( pxe, "PXE %s filtered out source IP %s\n",
1214 pxe->name, pshdr->net->ntoa ( actual_src_ip ) );
1215 rc = -ETIMEDOUT; /* "no packet" */
1216 goto err_filter;
1217 }
1218
1219 /* Filter based on destination IP address */
1221 efi_pxe_ip_filter ( pxe, actual_dest_ip ) ) ||
1224 ( dest_ip && ( memcmp ( dest_ip, actual_dest_ip,
1225 addr_len ) == 0 ) ) ) ) ) ) {
1226 DBGC2 ( pxe, "PXE %s filtered out destination IP %s\n",
1227 pxe->name, pshdr->net->ntoa ( actual_dest_ip ) );
1228 rc = -ETIMEDOUT; /* "no packet" */
1229 goto err_filter;
1230 }
1231
1232 /* Fill in addresses and port numbers */
1233 if ( dest_ip )
1234 memcpy ( dest_ip, actual_dest_ip, addr_len );
1235 if ( dest_port )
1236 *dest_port = pshdr->dest_port;
1237 if ( src_ip )
1238 memcpy ( src_ip, actual_src_ip, addr_len );
1239 if ( src_port )
1240 *src_port = pshdr->src_port;
1241
1242 /* Fill in header, if applicable */
1243 if ( hdr_len ) {
1244 frag_len = iob_len ( iobuf );
1245 if ( frag_len > *hdr_len )
1246 frag_len = *hdr_len;
1247 memcpy ( hdr, iobuf->data, frag_len );
1248 iob_pull ( iobuf, frag_len );
1249 *hdr_len = frag_len;
1250 }
1251
1252 /* Fill in data buffer */
1253 frag_len = iob_len ( iobuf );
1254 if ( frag_len > *len )
1255 frag_len = *len;
1256 memcpy ( data, iobuf->data, frag_len );
1257 iob_pull ( iobuf, frag_len );
1258 *len = frag_len;
1259
1260 /* Check for overflow */
1261 if ( iob_len ( iobuf ) ) {
1262 rc = -ERANGE;
1263 goto err_too_short;
1264 }
1265
1266 /* Success */
1267 rc = 0;
1268
1269 err_too_short:
1270 err_filter:
1271 free_iob ( iobuf );
1272 err_empty:
1274 err_open:
1275 return EFIRC ( rc );
1276}
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP
static int efi_pxe_ip_filter(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
Check if IP address matches filter.
Definition efi_pxe.c:260
#define ERANGE
Result too large.
Definition errno.h:683
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
void * data
Start of data.
Definition iobuf.h:113
const char * name
Protocol name.
Definition netdevice.h:67

References base, container_of, data, io_buffer::data, DBGC2, dest_ip, efi_pxe_udp_pseudo_header::dest_port, EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP, EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT, EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP, EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT, EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER, efi_pxe_ip_filter(), efi_pxe_ip_ntoa(), efi_pxe_udp_open(), efi_pxe_udp_schedule_close(), EFIRC, ERANGE, ETIMEDOUT, flags, free_iob(), hdr, iob_len(), iob_pull, len, io_buffer::list, list_del, list_empty, list_first_entry, memcmp(), memcpy(), efi_pxe::name, net_protocol::name, efi_pxe::net, efi_pxe_udp_pseudo_header::net, net_protocol::net_addr_len, net_protocol::ntoa, efi_pxe::queue, rc, src_ip, efi_pxe_udp_pseudo_header::src_port, src_port, step(), and VOID.

◆ efi_pxe_set_ip_filter()

EFI_STATUS EFIAPI efi_pxe_set_ip_filter ( EFI_PXE_BASE_CODE_PROTOCOL * base,
EFI_PXE_BASE_CODE_IP_FILTER * filter )
static

Set receive filter.

Parameters
basePXE base code protocol
filterReceive filter
Return values
efircEFI status code

Definition at line 1286 of file efi_pxe.c.

1287 {
1288 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1290 unsigned int max;
1291 unsigned int i;
1292
1293 DBGC ( pxe, "PXE %s SET IP FILTER %02x",
1294 pxe->name, filter->Filters );
1295 max = ( sizeof ( filter->IpList ) / sizeof ( filter->IpList[0] ) );
1296 for ( i = 0 ; ( ( i < filter->IpCnt ) && ( i < max ) ) ; i++ ) {
1297 DBGC ( pxe, " %s",
1298 efi_pxe_ip_ntoa ( pxe, &filter->IpList[i] ) );
1299 }
1300 if ( filter->IpCnt > max )
1301 DBGC ( pxe, " (invalid count %d)", filter->IpCnt );
1302 DBGC ( pxe, "\n" );
1303
1304 /* Update filter */
1305 memcpy ( &mode->IpFilter, filter, sizeof ( mode->IpFilter ) );
1306
1307 return 0;
1308}

References base, container_of, DBGC, efi_pxe_ip_ntoa(), filter, max, memcpy(), efi_pxe::mode, mode, and efi_pxe::name.

◆ efi_pxe_arp()

EFI_STATUS EFIAPI efi_pxe_arp ( EFI_PXE_BASE_CODE_PROTOCOL * base,
EFI_IP_ADDRESS * ip,
EFI_MAC_ADDRESS * mac )
static

Resolve MAC address.

Parameters
basePXE base code protocol
ipIP address
macMAC address to fill in
Return values
efircEFI status code

Definition at line 1318 of file efi_pxe.c.

1320 {
1321 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1322
1323 DBGC ( pxe, "PXE %s ARP %s %p\n",
1324 pxe->name, efi_pxe_ip_ntoa ( pxe, ip ), mac );
1325
1326 /* Not used by any bootstrap I can find to test with */
1327 return EFI_UNSUPPORTED;
1328}
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13

References base, container_of, DBGC, efi_pxe_ip_ntoa(), EFI_UNSUPPORTED, EFIAPI, ip, mac, and efi_pxe::name.

◆ efi_pxe_set_parameters()

EFI_STATUS EFIAPI efi_pxe_set_parameters ( EFI_PXE_BASE_CODE_PROTOCOL * base,
BOOLEAN * autoarp,
BOOLEAN * sendguid,
UINT8 * ttl,
UINT8 * tos,
BOOLEAN * callback )
static

Set parameters.

Parameters
basePXE base code protocol
autoarpAutomatic ARP packet generation
sendguidSend GUID as client hardware address
ttlIP time to live
tosIP type of service
callbackMake callbacks
Return values
efircEFI status code

Definition at line 1342 of file efi_pxe.c.

1344 {
1345 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1347
1348 DBGC ( pxe, "PXE %s SET PARAMETERS", pxe->name );
1349 if ( autoarp )
1350 DBGC ( pxe, " %s", ( *autoarp ? "autoarp" : "noautoarp" ) );
1351 if ( sendguid )
1352 DBGC ( pxe, " %s", ( *sendguid ? "sendguid" : "sendmac" ) );
1353 if ( ttl )
1354 DBGC ( pxe, " ttl %d", *ttl );
1355 if ( tos )
1356 DBGC ( pxe, " tos %d", *tos );
1357 if ( callback ) {
1358 DBGC ( pxe, " %s",
1359 ( *callback ? "callback" : "nocallback" ) );
1360 }
1361 DBGC ( pxe, "\n" );
1362
1363 /* Update parameters */
1364 if ( autoarp )
1365 mode->AutoArp = *autoarp;
1366 if ( sendguid )
1367 mode->SendGUID = *sendguid;
1368 if ( ttl )
1369 mode->TTL = *ttl;
1370 if ( tos )
1371 mode->ToS = *tos;
1372 if ( callback )
1373 mode->MakeCallbacks = *callback;
1374
1375 return 0;
1376}

References base, container_of, DBGC, efi_pxe::mode, mode, and efi_pxe::name.

◆ efi_pxe_set_station_ip()

EFI_STATUS EFIAPI efi_pxe_set_station_ip ( EFI_PXE_BASE_CODE_PROTOCOL * base,
EFI_IP_ADDRESS * ip,
EFI_IP_ADDRESS * netmask )
static

Set IP address.

Parameters
basePXE base code protocol
ipIP address
netmaskSubnet mask
Return values
efircEFI status code

Definition at line 1387 of file efi_pxe.c.

1388 {
1389 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1391
1392 DBGC ( pxe, "PXE %s SET STATION IP ", pxe->name );
1393 if ( ip )
1394 DBGC ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, ip ) );
1395 if ( netmask )
1396 DBGC ( pxe, "/%s", efi_pxe_ip_ntoa ( pxe, netmask ) );
1397 DBGC ( pxe, "\n" );
1398
1399 /* Update IP address and netmask */
1400 if ( ip )
1401 memcpy ( &mode->StationIp, ip, sizeof ( mode->StationIp ) );
1402 if ( netmask )
1403 memcpy ( &mode->SubnetMask, netmask, sizeof (mode->SubnetMask));
1404
1405 return 0;
1406}

References base, container_of, DBGC, efi_pxe_ip_ntoa(), ip, memcpy(), efi_pxe::mode, mode, and efi_pxe::name.

◆ efi_pxe_set_packets()

EFI_STATUS EFIAPI efi_pxe_set_packets ( EFI_PXE_BASE_CODE_PROTOCOL * base,
BOOLEAN * dhcpdisc_ok,
BOOLEAN * dhcpack_ok,
BOOLEAN * proxyoffer_ok,
BOOLEAN * pxebsdisc_ok,
BOOLEAN * pxebsack_ok,
BOOLEAN * pxebsbis_ok,
EFI_PXE_BASE_CODE_PACKET * dhcpdisc,
EFI_PXE_BASE_CODE_PACKET * dhcpack,
EFI_PXE_BASE_CODE_PACKET * proxyoffer,
EFI_PXE_BASE_CODE_PACKET * pxebsdisc,
EFI_PXE_BASE_CODE_PACKET * pxebsack,
EFI_PXE_BASE_CODE_PACKET * pxebsbis )
static

Update cached DHCP packets.

Parameters
basePXE base code protocol
dhcpdisc_okDHCPDISCOVER is valid
dhcpack_okDHCPACK received
proxyoffer_okProxyDHCPOFFER received
pxebsdisc_okPxeBsDISCOVER valid
pxebsack_okPxeBsACK received
pxebsbis_okPxeBsBIS received
dhcpdiscDHCPDISCOVER packet
dhcpackDHCPACK packet
proxyofferProxyDHCPOFFER packet
pxebsdiscPxeBsDISCOVER packet
pxebsackPxeBsACK packet
pxebsbisPxeBsBIS packet
Return values
efircEFI status code

Definition at line 1427 of file efi_pxe.c.

1435 {
1436 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1438
1439 DBGC ( pxe, "PXE %s SET PACKETS\n", pxe->name );
1440
1441 /* Update fake packet flags */
1442 if ( dhcpdisc_ok )
1443 mode->DhcpDiscoverValid = *dhcpdisc_ok;
1444 if ( dhcpack_ok )
1445 mode->DhcpAckReceived = *dhcpack_ok;
1446 if ( proxyoffer_ok )
1447 mode->ProxyOfferReceived = *proxyoffer_ok;
1448 if ( pxebsdisc_ok )
1449 mode->PxeDiscoverValid = *pxebsdisc_ok;
1450 if ( pxebsack_ok )
1451 mode->PxeReplyReceived = *pxebsack_ok;
1452 if ( pxebsbis_ok )
1453 mode->PxeBisReplyReceived = *pxebsbis_ok;
1454
1455 /* Update fake packet contents */
1456 if ( dhcpdisc )
1457 memcpy ( &mode->DhcpDiscover, dhcpdisc, sizeof ( *dhcpdisc ) );
1458 if ( dhcpack )
1459 memcpy ( &mode->DhcpAck, dhcpack, sizeof ( *dhcpack ) );
1460 if ( proxyoffer )
1461 memcpy ( &mode->ProxyOffer, proxyoffer, sizeof ( *proxyoffer ));
1462 if ( pxebsdisc )
1463 memcpy ( &mode->PxeDiscover, pxebsdisc, sizeof ( *pxebsdisc ) );
1464 if ( pxebsack )
1465 memcpy ( &mode->PxeReply, pxebsack, sizeof ( *pxebsack ) );
1466 if ( pxebsbis )
1467 memcpy ( &mode->PxeBisReply, pxebsbis, sizeof ( *pxebsbis ) );
1468
1469 return 0;
1470}

References base, container_of, DBGC, memcpy(), efi_pxe::mode, mode, and efi_pxe::name.

◆ efi_apple_get_response()

EFI_STATUS EFIAPI efi_apple_get_response ( EFI_PXE_BASE_CODE_PACKET * packet,
UINTN * len,
VOID * data )
static

Get DHCP/BSDP response.

Parameters
packetPacket
lenLength of data buffer
dataData buffer
Return values
efircEFI status code

Definition at line 1505 of file efi_pxe.c.

1506 {
1507
1508 /* Check length */
1509 if ( *len < sizeof ( *packet ) ) {
1510 *len = sizeof ( *packet );
1511 return EFI_BUFFER_TOO_SMALL;
1512 }
1513
1514 /* Copy packet */
1515 memcpy ( data, packet, sizeof ( *packet ) );
1516 *len = sizeof ( *packet );
1517
1518 return EFI_SUCCESS;
1519}
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
#define EFI_SUCCESS
Enumeration of EFI_STATUS.

References data, EFI_BUFFER_TOO_SMALL, EFI_SUCCESS, len, memcpy(), and VOID.

Referenced by efi_apple_get_bsdp_response(), and efi_apple_get_dhcp_response().

◆ efi_apple_get_dhcp_response()

EFI_STATUS EFIAPI efi_apple_get_dhcp_response ( EFI_APPLE_NET_BOOT_PROTOCOL * apple,
UINTN * len,
VOID * data )
static

Get DHCP response.

Parameters
appleApple NetBoot protocol
lenLength of data buffer
dataData buffer
Return values
efircEFI status code

Definition at line 1530 of file efi_pxe.c.

1531 {
1532 struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1533
1534 return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
1535}
static EFI_STATUS EFIAPI efi_apple_get_response(EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len, VOID *data)
Get DHCP/BSDP response.
Definition efi_pxe.c:1505
EFI_PXE_BASE_CODE_PACKET DhcpAck
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition efi_pxe.c:87

References efi_pxe::apple, container_of, data, EFI_PXE_BASE_CODE_MODE::DhcpAck, efi_apple_get_response(), len, efi_pxe::mode, and VOID.

◆ efi_apple_get_bsdp_response()

EFI_STATUS EFIAPI efi_apple_get_bsdp_response ( EFI_APPLE_NET_BOOT_PROTOCOL * apple,
UINTN * len,
VOID * data )
static

Get BSDP response.

Parameters
appleApple NetBoot protocol
lenLength of data buffer
dataData buffer
Return values
efircEFI status code

Definition at line 1546 of file efi_pxe.c.

1547 {
1548 struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1549
1550 return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
1551}
EFI_PXE_BASE_CODE_PACKET PxeReply

References efi_pxe::apple, container_of, data, efi_apple_get_response(), len, efi_pxe::mode, EFI_PXE_BASE_CODE_MODE::PxeReply, and VOID.

◆ efi_pxe_install()

int efi_pxe_install ( EFI_HANDLE handle,
struct net_device * netdev )

Install PXE base code protocol.

Parameters
handleEFI handle
netdevUnderlying network device
Return values
rcReturn status code

Definition at line 1573 of file efi_pxe.c.

1573 {
1574 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1576 struct efi_pxe *pxe;
1577 struct in_addr ip;
1578 BOOLEAN use_ipv6;
1579 int leak = 0;
1580 EFI_STATUS efirc;
1581 int rc;
1582
1583 /* Allocate and initialise structure */
1584 pxe = zalloc ( sizeof ( *pxe ) );
1585 if ( ! pxe ) {
1586 rc = -ENOMEM;
1587 goto err_alloc;
1588 }
1589 ref_init ( &pxe->refcnt, efi_pxe_free );
1590 pxe->netdev = netdev_get ( netdev );
1591 pxe->name = netdev->name;
1592 pxe->handle = handle;
1593 memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
1594 pxe->base.Mode = &pxe->mode;
1596 sizeof ( pxe->apple ) );
1597 intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
1598 intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
1599 INIT_LIST_HEAD ( &pxe->queue );
1601 &pxe->refcnt );
1602
1603 /* Crude heuristic: assume that we prefer to use IPv4 if we
1604 * have an IPv4 address for the network device, otherwise
1605 * prefer IPv6 (if available).
1606 */
1608 use_ipv6 = ( ip.s_addr ? FALSE : ( ipv6 != NULL ) );
1609
1610 /* Start base code */
1611 efi_pxe_start ( &pxe->base, use_ipv6 );
1612
1613 /* Install PXE base code protocol */
1614 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1615 &handle,
1618 NULL ) ) != 0 ) {
1619 rc = -EEFI ( efirc );
1620 DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
1621 pxe->name, strerror ( rc ) );
1622 goto err_install_protocol;
1623 }
1624
1625 /* Transfer reference to list and return */
1626 list_add_tail ( &pxe->list, &efi_pxes );
1627 DBGC ( pxe, "PXE %s installed for %s\n",
1628 pxe->name, efi_handle_name ( handle ) );
1629 return 0;
1630
1631 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1632 handle,
1635 NULL ) ) != 0 ) {
1636 DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1637 pxe->name, strerror ( -EEFI ( efirc ) ) );
1638 leak = 1;
1639 }
1640 efi_nullify_pxe ( &pxe->base );
1641 efi_nullify_apple ( &pxe->apple );
1642 err_install_protocol:
1643 if ( ! leak )
1644 ref_put ( &pxe->refcnt );
1645 err_alloc:
1646 if ( leak )
1647 DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1648 return rc;
1649}
unsigned char BOOLEAN
Logical Boolean.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition efi_guid.c:326
EFI_GUID efi_apple_net_boot_protocol_guid
Apple NetBoot protocol GUID.
Definition efi_guid.c:134
void efi_nullify_pxe(EFI_PXE_BASE_CODE_PROTOCOL *pxe)
Nullify PXE base code protocol.
Definition efi_null.c:537
void efi_nullify_apple(EFI_APPLE_NET_BOOT_PROTOCOL *apple)
Nullify Apple Net Boot protocol.
Definition efi_null.c:572
static struct interface_descriptor efi_pxe_udp_desc
PXE UDP interface descriptor.
Definition efi_pxe.c:533
static struct interface_descriptor efi_pxe_tftp_desc
PXE file data transfer interface descriptor.
Definition efi_pxe.c:384
static void efi_pxe_free(struct refcnt *refcnt)
Free PXE base code.
Definition efi_pxe.c:119
static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol
PXE base code protocol.
Definition efi_pxe.c:1473
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition efi_pxe.c:720
static struct process_descriptor efi_pxe_process_desc
UDP close process descriptor.
Definition efi_pxe.c:593
static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol
Apple NetBoot protocol.
Definition efi_pxe.c:1554
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:181
EFI_SYSTEM_TABLE * efi_systab
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition process.h:146
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
EFI Boot Services Table.
Definition UefiSpec.h:1930
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2009
EFI_PXE_BASE_CODE_MODE * Mode
The pointer to the EFI_PXE_BASE_CODE_MODE data for this device.
EFI_PXE_BASE_CODE_PROTOCOL base
PXE base code protocol.
Definition efi_pxe.c:83
struct refcnt refcnt
Reference count.
Definition efi_pxe.c:72

References AF_INET6, efi_pxe::apple, efi_pxe::base, DBGC, EEFI, efi_apple_net_boot_protocol, efi_apple_net_boot_protocol_guid, EFI_HANDLE, efi_handle_name(), efi_nullify_apple(), efi_nullify_pxe(), efi_pxe_base_code_protocol, efi_pxe_base_code_protocol_guid, efi_pxe_free(), efi_pxe_process_desc, efi_pxe_start(), efi_pxe_tftp_desc, efi_pxe_udp_desc, efi_systab, ENOMEM, FALSE, fetch_ipv4_setting(), efi_pxe::handle, handle, INIT_LIST_HEAD, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, intf_init(), ip, ip_setting, efi_pxe::list, list_add_tail, memcpy(), _EFI_PXE_BASE_CODE_PROTOCOL::Mode, efi_pxe::mode, efi_pxe::name, efi_pxe::netdev, netdev, netdev_get(), netdev_settings(), NULL, efi_pxe::process, process_init_stopped(), efi_pxe::queue, rc, ref_init, ref_put, efi_pxe::refcnt, strerror(), tcpip_net_protocol(), efi_pxe::tftp, efi_pxe::udp, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and zalloc().

Referenced by efi_image_exec().

◆ efi_pxe_uninstall()

void efi_pxe_uninstall ( EFI_HANDLE handle)

Uninstall PXE base code protocol.

Parameters
handleEFI handle

Definition at line 1656 of file efi_pxe.c.

1656 {
1657 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1658 struct efi_pxe *pxe;
1659 int leak = efi_shutdown_in_progress;
1660 EFI_STATUS efirc;
1661
1662 /* Locate PXE base code */
1663 pxe = efi_pxe_find ( handle );
1664 if ( ! pxe ) {
1665 DBG ( "PXE could not find base code for %s\n",
1666 efi_handle_name ( handle ) );
1667 return;
1668 }
1669
1670 /* Stop base code */
1671 efi_pxe_stop ( &pxe->base );
1672
1673 /* Uninstall PXE base code protocol */
1674 if ( ( ! efi_shutdown_in_progress ) &&
1675 ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1676 handle,
1679 NULL ) ) != 0 ) ) {
1680 DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1681 pxe->name, strerror ( -EEFI ( efirc ) ) );
1682 leak = 1;
1683 }
1684 efi_nullify_pxe ( &pxe->base );
1685 efi_nullify_apple ( &pxe->apple );
1686
1687 /* Remove from list and drop list's reference */
1688 list_del ( &pxe->list );
1689 if ( ! leak )
1690 ref_put ( &pxe->refcnt );
1691
1692 /* Report leakage, if applicable */
1693 if ( leak && ( ! efi_shutdown_in_progress ) )
1694 DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1695}
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
static EFI_STATUS EFIAPI efi_pxe_stop(EFI_PXE_BASE_CODE_PROTOCOL *base)
Stop PXE base code.
Definition efi_pxe.c:775
static struct efi_pxe * efi_pxe_find(EFI_HANDLE handle)
Locate PXE base code.
Definition efi_pxe.c:135
#define DBG(...)
Print a debugging message.
Definition compiler.h:523

References efi_pxe::apple, efi_pxe::base, DBG, DBGC, EEFI, efi_apple_net_boot_protocol_guid, EFI_HANDLE, efi_handle_name(), efi_nullify_apple(), efi_nullify_pxe(), efi_pxe_base_code_protocol_guid, efi_pxe_find(), efi_pxe_stop(), efi_shutdown_in_progress, efi_systab, handle, efi_pxe::list, list_del, efi_pxe::name, NULL, ref_put, efi_pxe::refcnt, strerror(), and EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces.

Referenced by efi_image_exec().

Variable Documentation

◆ efi_pxe_tftp_operations

struct interface_operation efi_pxe_tftp_operations[]
static
Initial value:
= {
}
static size_t efi_pxe_tftp_window(struct efi_pxe *pxe)
Check PXE (M)TFTP download flow control window.
Definition efi_pxe.c:339
static int efi_pxe_tftp_deliver(struct efi_pxe *pxe, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new PXE (M)TFTP download data.
Definition efi_pxe.c:353
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

PXE file data transfer interface operations.

Definition at line 377 of file efi_pxe.c.

◆ efi_pxe_tftp_desc

struct interface_descriptor efi_pxe_tftp_desc
static
Initial value:
=
static struct interface_operation efi_pxe_tftp_operations[]
PXE file data transfer interface operations.
Definition efi_pxe.c:377
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

PXE file data transfer interface descriptor.

Definition at line 384 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ efi_pxe_udp_operations

struct interface_operation efi_pxe_udp_operations[]
static
Initial value:
= {
}
static int efi_pxe_udp_deliver(struct efi_pxe *pxe, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive UDP packet.
Definition efi_pxe.c:476

PXE UDP interface operations.

Definition at line 527 of file efi_pxe.c.

527 {
530};

◆ efi_pxe_udp_desc

struct interface_descriptor efi_pxe_udp_desc
static
Initial value:
=
static struct interface_operation efi_pxe_udp_operations[]
PXE UDP interface operations.
Definition efi_pxe.c:527

PXE UDP interface descriptor.

Definition at line 533 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ efi_pxe_process_desc

struct process_descriptor efi_pxe_process_desc
static
Initial value:
=
static void efi_pxe_udp_scheduled_close(struct efi_pxe *pxe)
Scheduled close of UDP interface.
Definition efi_pxe.c:586
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
A process.
Definition process.h:18

UDP close process descriptor.

Definition at line 593 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ efi_pxe_base_code_protocol

EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol
static
Initial value:
= {
.Start = efi_pxe_start,
.Stop = efi_pxe_stop,
.Dhcp = efi_pxe_dhcp,
.Discover = efi_pxe_discover,
.Mtftp = efi_pxe_mtftp,
.UdpWrite = efi_pxe_udp_write,
.UdpRead = efi_pxe_udp_read,
.SetIpFilter = efi_pxe_set_ip_filter,
.Arp = efi_pxe_arp,
.SetParameters = efi_pxe_set_parameters,
.SetStationIp = efi_pxe_set_station_ip,
.SetPackets = efi_pxe_set_packets,
}
#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION
static EFI_STATUS EFIAPI efi_pxe_mtftp(EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_PXE_BASE_CODE_TFTP_OPCODE opcode, VOID *data, BOOLEAN overwrite, UINT64 *len, UINTN *blksize, EFI_IP_ADDRESS *ip, UINT8 *filename, EFI_PXE_BASE_CODE_MTFTP_INFO *info, BOOLEAN callback)
Perform (M)TFTP.
Definition efi_pxe.c:898
static EFI_STATUS EFIAPI efi_pxe_dhcp(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
Perform DHCP.
Definition efi_pxe.c:800
static EFI_STATUS EFIAPI efi_pxe_set_ip_filter(EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_PXE_BASE_CODE_IP_FILTER *filter)
Set receive filter.
Definition efi_pxe.c:1286
static EFI_STATUS EFIAPI efi_pxe_udp_write(EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags, EFI_IP_ADDRESS *dest_ip, EFI_PXE_BASE_CODE_UDP_PORT *dest_port, EFI_IP_ADDRESS *gateway, EFI_IP_ADDRESS *src_ip, EFI_PXE_BASE_CODE_UDP_PORT *src_port, UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data)
Transmit UDP packet.
Definition efi_pxe.c:991
static EFI_STATUS EFIAPI efi_pxe_set_packets(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN *dhcpdisc_ok, BOOLEAN *dhcpack_ok, BOOLEAN *proxyoffer_ok, BOOLEAN *pxebsdisc_ok, BOOLEAN *pxebsack_ok, BOOLEAN *pxebsbis_ok, EFI_PXE_BASE_CODE_PACKET *dhcpdisc, EFI_PXE_BASE_CODE_PACKET *dhcpack, EFI_PXE_BASE_CODE_PACKET *proxyoffer, EFI_PXE_BASE_CODE_PACKET *pxebsdisc, EFI_PXE_BASE_CODE_PACKET *pxebsack, EFI_PXE_BASE_CODE_PACKET *pxebsbis)
Update cached DHCP packets.
Definition efi_pxe.c:1427
static EFI_STATUS EFIAPI efi_pxe_set_station_ip(EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_IP_ADDRESS *ip, EFI_IP_ADDRESS *netmask)
Set IP address.
Definition efi_pxe.c:1387
static EFI_STATUS EFIAPI efi_pxe_discover(EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 type, UINT16 *layer, BOOLEAN bis, EFI_PXE_BASE_CODE_DISCOVER_INFO *info)
Perform boot server discovery.
Definition efi_pxe.c:854
static EFI_STATUS EFIAPI efi_pxe_arp(EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac)
Resolve MAC address.
Definition efi_pxe.c:1318
static EFI_STATUS EFIAPI efi_pxe_set_parameters(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN *autoarp, BOOLEAN *sendguid, UINT8 *ttl, UINT8 *tos, BOOLEAN *callback)
Set parameters.
Definition efi_pxe.c:1342
static EFI_STATUS EFIAPI efi_pxe_udp_read(EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags, EFI_IP_ADDRESS *dest_ip, EFI_PXE_BASE_CODE_UDP_PORT *dest_port, EFI_IP_ADDRESS *src_ip, EFI_PXE_BASE_CODE_UDP_PORT *src_port, UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data)
Receive UDP packet.
Definition efi_pxe.c:1105

PXE base code protocol.

Definition at line 1473 of file efi_pxe.c.

1473 {
1475 .Start = efi_pxe_start,
1476 .Stop = efi_pxe_stop,
1477 .Dhcp = efi_pxe_dhcp,
1478 .Discover = efi_pxe_discover,
1479 .Mtftp = efi_pxe_mtftp,
1480 .UdpWrite = efi_pxe_udp_write,
1481 .UdpRead = efi_pxe_udp_read,
1482 .SetIpFilter = efi_pxe_set_ip_filter,
1483 .Arp = efi_pxe_arp,
1484 .SetParameters = efi_pxe_set_parameters,
1485 .SetStationIp = efi_pxe_set_station_ip,
1486 .SetPackets = efi_pxe_set_packets,
1487};

Referenced by efi_pxe_install().

◆ efi_apple_net_boot_protocol

EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol
static
Initial value:
= {
.GetDhcpResponse = efi_apple_get_dhcp_response,
.GetBsdpResponse = efi_apple_get_bsdp_response,
}
static EFI_STATUS EFIAPI efi_apple_get_bsdp_response(EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
Get BSDP response.
Definition efi_pxe.c:1546
static EFI_STATUS EFIAPI efi_apple_get_dhcp_response(EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
Get DHCP response.
Definition efi_pxe.c:1530

Apple NetBoot protocol.

Definition at line 1554 of file efi_pxe.c.

1554 {
1555 .GetDhcpResponse = efi_apple_get_dhcp_response,
1556 .GetBsdpResponse = efi_apple_get_bsdp_response,
1557};

Referenced by efi_pxe_install().