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
pxePXE 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:322
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
pxePXE 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
pxePXE 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
pxePXE 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:590
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
pxePXE 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 i;
271
272 /* Match everything, if applicable */
274 return 1;
275
276 /* Match all multicasts, if applicable */
278 if ( mode->UsingIpv6 ) {
279 if ( IN6_IS_ADDR_MULTICAST ( &u->in6 ) )
280 return 1;
281 } else {
282 if ( IN_IS_MULTICAST ( u->in.s_addr ) )
283 return 1;
284 }
285 }
286
287 /* Match IPv4 broadcasts, if applicable */
289 if ( ( ! mode->UsingIpv6 ) &&
290 ( u->in.s_addr == INADDR_BROADCAST ) )
291 return 1;
292 }
293
294 /* Match station address, if applicable */
296 if ( memcmp ( ip, &mode->StationIp, addr_len ) == 0 )
297 return 1;
298 }
299
300 /* Match explicit addresses, if applicable */
301 for ( i = 0 ; i < filter->IpCnt ; i++ ) {
302 if ( memcmp ( ip, &filter->IpList[i], addr_len ) == 0 )
303 return 1;
304 }
305
306 return 0;
307}
__be32 in[4]
Definition CIB_PRM.h:7
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition PxeBaseCode.h:86
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition PxeBaseCode.h:85
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition PxeBaseCode.h:87
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST
Definition PxeBaseCode.h:88
unsigned char uint8_t
Definition stdint.h:10
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:78
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, 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
pxePXE base code
rcReason for close

Definition at line 322 of file efi_pxe.c.

322 {
323
324 /* Restart interface */
325 intf_restart ( &pxe->tftp, rc );
326
327 /* Record overall status */
328 pxe->rc = rc;
329}
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
pxePXE base code
Return values
lenLength of window

Definition at line 337 of file efi_pxe.c.

337 {
338
339 /* Return requested blocksize */
340 return pxe->blksize;
341}
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
pxePXE base code
iobufI/O buffer
metaTransfer metadata
Return values
rcReturn status code

Definition at line 351 of file efi_pxe.c.

353 {
354 int rc;
355
356 /* Deliver to data transfer buffer */
357 if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
358 meta ) ) != 0 )
359 goto done;
360
361 /* Stop when filesize is known, if applicable */
363 ( meta->flags & XFER_FL_ABS_OFFSET ) ) {
364 goto done;
365 }
366
367 return 0;
368
369 done:
370 efi_pxe_tftp_close ( pxe, rc );
371 return rc;
372}
@ 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:322
uint8_t meta
Metadata flags.
Definition ena.h:3
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
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:177

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
pxePXE base code
ipEFI IP address
filenameFilename
Return values
rcReturn status code

Definition at line 393 of file efi_pxe.c.

394 {
395 struct sockaddr server;
396 struct uri *uri;
397 int rc;
398
399 /* Parse server address and filename */
400 efi_pxe_ip_sockaddr ( pxe, ip, &server );
401 uri = pxe_uri ( &server, filename );
402 if ( ! uri ) {
403 DBGC ( pxe, "PXE %s could not parse %s:%s\n", pxe->name,
404 efi_pxe_ip_ntoa ( pxe, ip ), filename );
405 rc = -ENOTSUP;
406 goto err_parse;
407 }
408
409 /* Open URI */
410 if ( ( rc = xfer_open_uri ( &pxe->tftp, uri ) ) != 0 ) {
411 DBGC ( pxe, "PXE %s could not open: %s\n",
412 pxe->name, strerror ( rc ) );
413 goto err_open;
414 }
415
416 err_open:
417 uri_put ( uri );
418 err_parse:
419 return rc;
420}
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:505
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
pxePXE base code
rcReason for close

Definition at line 445 of file efi_pxe.c.

445 {
446 struct io_buffer *iobuf;
447 struct io_buffer *tmp;
448
449 /* Release our claim on SNP devices, if applicable */
450 if ( process_running ( &pxe->process ) )
452
453 /* Stop process */
454 process_del ( &pxe->process );
455
456 /* Restart UDP interface */
457 intf_restart ( &pxe->udp, rc );
458
459 /* Flush any received UDP packets */
460 list_for_each_entry_safe ( iobuf, tmp, &pxe->queue, list ) {
461 list_del ( &iobuf->list );
462 free_iob ( iobuf );
463 }
464}
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:38
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45

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
pxePXE base code
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 474 of file efi_pxe.c.

475 {
476 struct sockaddr_efi *se_src;
477 struct sockaddr_efi *se_dest;
478 struct tcpip_net_protocol *tcpip;
479 struct net_protocol *net;
480 struct efi_pxe_udp_pseudo_header *pshdr;
481 size_t addr_len;
482 size_t pshdr_len;
483 int rc;
484
485 /* Sanity checks */
486 assert ( meta != NULL );
487 se_src = ( ( struct sockaddr_efi * ) meta->src );
488 assert ( se_src != NULL );
489 se_dest = ( ( struct sockaddr_efi * ) meta->dest );
490 assert ( se_dest != NULL );
491 assert ( se_src->se_family == se_dest->se_family );
492
493 /* Determine protocol */
494 tcpip = tcpip_net_protocol ( se_src->se_family );
495 if ( ! tcpip ) {
496 rc = -ENOTSUP;
497 goto err_unsupported;
498 }
499 net = tcpip->net_protocol;
500 addr_len = net->net_addr_len;
501
502 /* Construct pseudo-header */
503 pshdr_len = ( sizeof ( *pshdr ) + ( 2 * addr_len ) );
504 if ( ( rc = iob_ensure_headroom ( iobuf, pshdr_len ) ) != 0 )
505 goto err_headroom;
506 memcpy ( iob_push ( iobuf, addr_len ), &se_src->se_addr, addr_len );
507 memcpy ( iob_push ( iobuf, addr_len ), &se_dest->se_addr, addr_len );
508 pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
509 pshdr->net = net;
510 pshdr->dest_port = ntohs ( se_dest->se_port );
511 pshdr->src_port = ntohs ( se_src->se_port );
512
513 /* Add to queue */
514 list_add_tail ( &iobuf->list, &pxe->queue );
515
516 return 0;
517
518 err_unsupported:
519 err_headroom:
520 free_iob ( iobuf );
521 return rc;
522}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#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:89
#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:430
struct net_protocol * net
Network-layer protocol.
Definition efi_pxe.c:432
uint16_t src_port
Source port.
Definition efi_pxe.c:436
uint16_t dest_port
Destination port.
Definition efi_pxe.c:434
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
pxePXE base code
Return values
rcReturn status code

Definition at line 540 of file efi_pxe.c.

540 {
541 int rc;
542
543 /* If interface is already open, then cancel the scheduled close */
544 if ( process_running ( &pxe->process ) ) {
545 process_del ( &pxe->process );
546 return 0;
547 }
548
549 /* Open promiscuous UDP interface */
550 if ( ( rc = udp_open_promisc ( &pxe->udp ) ) != 0 ) {
551 DBGC ( pxe, "PXE %s could not open UDP connection: %s\n",
552 pxe->name, strerror ( rc ) );
553 return rc;
554 }
555
556 /* Claim network devices */
558
559 return 0;
560}
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
pxePXE base code

Definition at line 567 of file efi_pxe.c.

567 {
568
569 /* The EFI PXE base code protocol does not provide any
570 * explicit UDP open/close methods. To avoid the overhead of
571 * reopening a socket for each read/write operation, we start
572 * a process which will close the socket immediately if the
573 * next call into iPXE is anything other than a UDP
574 * read/write.
575 */
576 process_add ( &pxe->process );
577}
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
pxePXE base code

Definition at line 584 of file efi_pxe.c.

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

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
pxePXE base code
packetPacket
Return values
nameName of packet

Definition at line 608 of file efi_pxe.c.

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

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
pxePXE base code
fakeFake packet constructor
packetPacket to fill in
Return values
existsPacket existence flag

Definition at line 637 of file efi_pxe.c.

640 {
642 struct dhcp_packet dhcppkt;
643 struct dhcphdr *dhcphdr;
644 unsigned int len;
645 int rc;
646
647 /* The fake packet constructors do not support IPv6 */
648 if ( mode->UsingIpv6 )
649 return FALSE;
650
651 /* Attempt to construct packet */
652 if ( ( rc = fake ( pxe->netdev, packet, sizeof ( *packet ) ) != 0 ) ) {
653 DBGC ( pxe, "PXE %s could not fake %s: %s\n", pxe->name,
654 efi_pxe_fake_name ( pxe, packet ), strerror ( rc ) );
655 return FALSE;
656 }
657
658 /* The WDS bootstrap wdsmgfw.efi has a buggy DHCPv4 packet
659 * parser which does not correctly handle DHCP padding bytes.
660 * Specifically, if a padding byte (i.e. a zero) is
661 * encountered, the parse will first increment the pointer by
662 * one to skip over the padding byte but will then drop into
663 * the code path for handling normal options, which increments
664 * the pointer by two to skip over the (already-skipped) type
665 * field and the (non-existent) length field.
666 *
667 * The upshot of this bug in WDS is that the parser will fail
668 * with an error 0xc0000023 if the number of spare bytes after
669 * the end of the options is not an exact multiple of three.
670 *
671 * Work around this buggy parser by adding an explicit
672 * DHCP_END tag.
673 */
675 struct dhcphdr, op );
676 dhcppkt_init ( &dhcppkt, dhcphdr, sizeof ( *packet ) );
677 len = dhcppkt_len ( &dhcppkt );
678 if ( len < sizeof ( *packet ) )
679 packet->Raw[len] = DHCP_END;
680
681 return TRUE;
682}
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:608
#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
pxePXE base code

Definition at line 689 of file efi_pxe.c.

689 {
691
692 /* Construct fake packets */
693 mode->DhcpDiscoverValid =
695 &mode->DhcpDiscover );
696 mode->DhcpAckReceived =
698 &mode->DhcpAck );
699 mode->PxeReplyReceived =
701 &mode->PxeReply );
702}
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:637
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 718 of file efi_pxe.c.

719 {
720 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
723 sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
724 int rc;
725
726 DBGC ( pxe, "PXE %s START %s\n",
727 pxe->name, ( use_ipv6 ? "IPv6" : "IPv4" ) );
728
729 /* Initialise mode structure */
730 memset ( mode, 0, sizeof ( *mode ) );
731 mode->AutoArp = TRUE;
732 mode->TTL = DEFAULT_TTL;
733 mode->ToS = DEFAULT_ToS;
734 mode->IpFilter.Filters =
739
740 /* Check for IPv4/IPv6 support */
741 mode->Ipv6Supported = ( ipv6 != NULL );
742 mode->Ipv6Available = ( ipv6 != NULL );
743 pxe->tcpip = tcpip_net_protocol ( family );
744 if ( ! pxe->tcpip ) {
745 DBGC ( pxe, "PXE %s has no support for %s\n",
746 pxe->name, socket_family_name ( family ) );
747 return EFI_UNSUPPORTED;
748 }
749 pxe->net = pxe->tcpip->net_protocol;
750 mode->UsingIpv6 = use_ipv6;
751
752 /* Populate station IP address */
753 if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
754 return rc;
755
756 /* Construct fake DHCP packets */
757 efi_pxe_fake_all ( pxe );
758
759 /* Record that base code is started */
760 mode->Started = TRUE;
761 DBGC ( pxe, "PXE %s using %s\n",
762 pxe->name, pxe->net->ntoa ( &mode->StationIp ) );
763
764 return 0;
765}
#define DEFAULT_ToS
Definition PxeBaseCode.h:41
#define DEFAULT_TTL
Default IP TTL and ToS.
Definition PxeBaseCode.h:40
#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:689
#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 773 of file efi_pxe.c.

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

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 798 of file efi_pxe.c.

799 {
800 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
801 struct net_device *netdev = pxe->netdev;
802 int rc;
803
804 DBGC ( pxe, "PXE %s DHCP %s\n",
805 pxe->name, ( sort ? "sorted" : "unsorted" ) );
806
807 /* Claim network devices */
809
810 /* Initiate configuration */
811 if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
812 DBGC ( pxe, "PXE %s could not initiate configuration: %s\n",
813 pxe->name, strerror ( rc ) );
814 goto err_configure;
815 }
816
817 /* Wait for configuration to complete (or time out) */
819 step();
820
821 /* Report timeout if configuration failed */
822 if ( ! netdev_configuration_ok ( netdev ) ) {
823 rc = -ETIMEDOUT;
824 goto err_timeout;
825 }
826
827 /* Update station IP address */
828 if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
829 goto err_ip;
830
831 /* Update faked DHCP packets */
832 efi_pxe_fake_all ( pxe );
833
834 err_ip:
835 err_timeout:
836 err_configure:
838 return EFIRC ( rc );
839}
static struct net_device * netdev
Definition gdbudp.c:53
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
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 852 of file efi_pxe.c.

853 {
854 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
856 unsigned int i;
857
858 DBGC ( pxe, "PXE %s DISCOVER type %d layer %d%s\n",
859 pxe->name, type, *layer, ( bis ? " bis" : "" ) );
860 if ( info ) {
861 DBGC ( pxe, "%s%s%s%s %s",
862 ( info->UseMCast ? " mcast" : "" ),
863 ( info->UseBCast ? " bcast" : "" ),
864 ( info->UseUCast ? " ucast" : "" ),
865 ( info->MustUseList ? " list" : "" ),
866 efi_pxe_ip_ntoa ( pxe, &info->ServerMCastIp ) );
867 for ( i = 0 ; i < info->IpCnt ; i++ ) {
868 ip = &info->SrvList[i].IpAddr;
869 DBGC ( pxe, " %d%s:%s", info->SrvList[i].Type,
870 ( info->SrvList[i].AcceptAnyResponse ?
871 ":any" : "" ), efi_pxe_ip_ntoa ( pxe, ip ) );
872 }
873 }
874 DBGC ( pxe, "\n" );
875
876 /* Not used by any bootstrap I can find to test with */
877 return EFI_UNSUPPORTED;
878}
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 896 of file efi_pxe.c.

900 {
901 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
902 int rc;
903
904 DBGC ( pxe, "PXE %s MTFTP %d%s %p+%llx", pxe->name, opcode,
905 ( overwrite ? " overwrite" : "" ), data, *len );
906 if ( blksize )
907 DBGC ( pxe, " blksize %zd", ( ( size_t ) *blksize ) );
908 DBGC ( pxe, " %s:%s", efi_pxe_ip_ntoa ( pxe, ip ), filename );
909 if ( info ) {
910 DBGC ( pxe, " %s:%d:%d:%d:%d",
911 efi_pxe_ip_ntoa ( pxe, &info->MCastIp ),
912 info->CPort, info->SPort, info->ListenTimeout,
913 info->TransmitTimeout );
914 }
915 DBGC ( pxe, "%s\n", ( callback ? " callback" : "" ) );
916
917 /* Fail unless operation is supported */
921 DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
922 pxe->name, opcode );
923 rc = -ENOTSUP;
924 goto err_opcode;
925 }
926
927 /* Claim network devices */
929
930 /* Determine block size. Ignore the requested block size
931 * unless we are using callbacks, since limiting HTTP to a
932 * 512-byte TCP window is not sensible.
933 */
934 pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
935
936 /* Initialise data transfer buffer */
937 memset ( &pxe->buf, 0, sizeof ( pxe->buf ) );
939 xferbuf_void_init ( &pxe->buf );
940 } else {
941 xferbuf_fixed_init ( &pxe->buf, data, *len );
942 }
943
944 /* Open download */
945 if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
946 ( ( const char * ) filename ) ) ) != 0 )
947 goto err_open;
948
949 /* Wait for download to complete */
950 pxe->opcode = opcode;
951 pxe->rc = -EINPROGRESS;
952 while ( pxe->rc == -EINPROGRESS )
953 step();
954 *len = pxe->buf.max;
955 if ( ( rc = pxe->rc ) != 0 ) {
956 DBGC ( pxe, "PXE %s MTFTP %d failed: %s\n",
957 pxe->name, opcode, strerror ( rc ) );
958 goto err_download;
959 }
960 DBGC ( pxe, "PXE %s MTFTP %d %p+%llx complete\n",
961 pxe->name, opcode, data, *len );
962
963 err_download:
964 efi_pxe_tftp_close ( pxe, rc );
965 err_open:
966 xferbuf_fixed_init ( &pxe->buf, NULL, 0 );
968 err_opcode:
969 return EFIRC ( rc );
970}
@ 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:393
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:419
uint32_t blksize
Cipher block size.
Definition pccrr.h:1
size_t max
Maximum required size of data.
Definition xferbuf.h:25
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition xferbuf.h:83
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition xferbuf.h:98

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 989 of file efi_pxe.c.

994 {
995 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
997 struct io_buffer *iobuf;
998 struct xfer_metadata meta;
999 union {
1000 struct sockaddr_tcpip st;
1001 struct sockaddr sa;
1002 } dest;
1003 union {
1004 struct sockaddr_tcpip st;
1005 struct sockaddr sa;
1006 } src;
1007 int rc;
1008
1009 DBGC2 ( pxe, "PXE %s UDP WRITE ", pxe->name );
1010 if ( src_ip )
1011 DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1012 DBGC2 ( pxe, ":" );
1013 if ( src_port &&
1015 DBGC2 ( pxe, "%d", *src_port );
1016 } else {
1017 DBGC2 ( pxe, "*" );
1018 }
1019 DBGC2 ( pxe, "->%s:%d", efi_pxe_ip_ntoa ( pxe, dest_ip ), *dest_port );
1020 if ( gateway )
1021 DBGC2 ( pxe, " via %s", efi_pxe_ip_ntoa ( pxe, gateway ) );
1022 if ( hdr_len )
1023 DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1024 DBGC2 ( pxe, " %p+%zx", data, ( ( size_t ) *len ) );
1026 DBGC2 ( pxe, " frag" );
1027 DBGC2 ( pxe, "\n" );
1028
1029 /* Open UDP connection (if applicable) */
1030 if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1031 goto err_open;
1032
1033 /* Construct destination address */
1034 efi_pxe_ip_sockaddr ( pxe, dest_ip, &dest.sa );
1035 dest.st.st_port = htons ( *dest_port );
1036
1037 /* Construct source address */
1038 efi_pxe_ip_sockaddr ( pxe, ( src_ip ? src_ip : &mode->StationIp ),
1039 &src.sa );
1040 if ( src_port &&
1042 src.st.st_port = htons ( *src_port );
1043 } else {
1044 /* The API does not allow for a sensible concept of
1045 * binding to a local port, so just use a random value.
1046 */
1047 src.st.st_port = ( random() | htons ( 1024 ) );
1048 if ( src_port )
1049 *src_port = ntohs ( src.st.st_port );
1050 }
1051
1052 /* Allocate I/O buffer */
1053 iobuf = xfer_alloc_iob ( &pxe->udp,
1054 ( *len + ( hdr_len ? *hdr_len : 0 ) ) );
1055 if ( ! iobuf ) {
1056 rc = -ENOMEM;
1057 goto err_alloc;
1058 }
1059
1060 /* Populate I/O buffer */
1061 if ( hdr_len )
1062 memcpy ( iob_put ( iobuf, *hdr_len ), hdr, *hdr_len );
1063 memcpy ( iob_put ( iobuf, *len ), data, *len );
1064
1065 /* Construct metadata */
1066 memset ( &meta, 0, sizeof ( meta ) );
1067 meta.src = &src.sa;
1068 meta.dest = &dest.sa;
1069 meta.netdev = pxe->netdev;
1070
1071 /* Deliver I/O buffer */
1072 if ( ( rc = xfer_deliver ( &pxe->udp, iob_disown ( iobuf ),
1073 &meta ) ) != 0 ) {
1074 DBGC ( pxe, "PXE %s could not transmit: %s\n",
1075 pxe->name, strerror ( rc ) );
1076 goto err_deliver;
1077 }
1078
1079 err_deliver:
1080 free_iob ( iobuf );
1081 err_alloc:
1083 err_open:
1084 return EFIRC ( rc );
1085}
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:540
static void efi_pxe_udp_schedule_close(struct efi_pxe *pxe)
Schedule close of UDP interface.
Definition efi_pxe.c:567
uint8_t flags
Flags.
Definition ena.h:7
#define DBGC2(...)
Definition compiler.h:522
#define ENOMEM
Not enough space.
Definition errno.h:535
#define htons(value)
Definition byteswap.h:136
#define iob_put(iobuf, len)
Definition iobuf.h:125
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 1103 of file efi_pxe.c.

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

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

References base, container_of, DBGC, efi_pxe_ip_ntoa(), filter, 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 1312 of file efi_pxe.c.

1314 {
1315 struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1316
1317 DBGC ( pxe, "PXE %s ARP %s %p\n",
1318 pxe->name, efi_pxe_ip_ntoa ( pxe, ip ), mac );
1319
1320 /* Not used by any bootstrap I can find to test with */
1321 return EFI_UNSUPPORTED;
1322}
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 1336 of file efi_pxe.c.

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

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 1381 of file efi_pxe.c.

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

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 1421 of file efi_pxe.c.

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

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 1499 of file efi_pxe.c.

1500 {
1501
1502 /* Check length */
1503 if ( *len < sizeof ( *packet ) ) {
1504 *len = sizeof ( *packet );
1505 return EFI_BUFFER_TOO_SMALL;
1506 }
1507
1508 /* Copy packet */
1509 memcpy ( data, packet, sizeof ( *packet ) );
1510 *len = sizeof ( *packet );
1511
1512 return EFI_SUCCESS;
1513}
#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 1524 of file efi_pxe.c.

1525 {
1526 struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1527
1528 return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
1529}
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:1499
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 1540 of file efi_pxe.c.

1541 {
1542 struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1543
1544 return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
1545}
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 1567 of file efi_pxe.c.

1567 {
1568 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1570 struct efi_pxe *pxe;
1571 struct in_addr ip;
1572 BOOLEAN use_ipv6;
1573 int leak = 0;
1574 EFI_STATUS efirc;
1575 int rc;
1576
1577 /* Allocate and initialise structure */
1578 pxe = zalloc ( sizeof ( *pxe ) );
1579 if ( ! pxe ) {
1580 rc = -ENOMEM;
1581 goto err_alloc;
1582 }
1583 ref_init ( &pxe->refcnt, efi_pxe_free );
1584 pxe->netdev = netdev_get ( netdev );
1585 pxe->name = netdev->name;
1586 pxe->handle = handle;
1587 memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
1588 pxe->base.Mode = &pxe->mode;
1590 sizeof ( pxe->apple ) );
1591 intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
1592 intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
1593 INIT_LIST_HEAD ( &pxe->queue );
1595 &pxe->refcnt );
1596
1597 /* Crude heuristic: assume that we prefer to use IPv4 if we
1598 * have an IPv4 address for the network device, otherwise
1599 * prefer IPv6 (if available).
1600 */
1602 use_ipv6 = ( ip.s_addr ? FALSE : ( ipv6 != NULL ) );
1603
1604 /* Start base code */
1605 efi_pxe_start ( &pxe->base, use_ipv6 );
1606
1607 /* Install PXE base code protocol */
1608 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1609 &handle,
1612 NULL ) ) != 0 ) {
1613 rc = -EEFI ( efirc );
1614 DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
1615 pxe->name, strerror ( rc ) );
1616 goto err_install_protocol;
1617 }
1618
1619 /* Transfer reference to list and return */
1620 list_add_tail ( &pxe->list, &efi_pxes );
1621 DBGC ( pxe, "PXE %s installed for %s\n",
1622 pxe->name, efi_handle_name ( handle ) );
1623 return 0;
1624
1625 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1626 handle,
1629 NULL ) ) != 0 ) {
1630 DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1631 pxe->name, strerror ( -EEFI ( efirc ) ) );
1632 leak = 1;
1633 }
1634 efi_nullify_pxe ( &pxe->base );
1635 efi_nullify_apple ( &pxe->apple );
1636 err_install_protocol:
1637 if ( ! leak )
1638 ref_put ( &pxe->refcnt );
1639 err_alloc:
1640 if ( leak )
1641 DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1642 return rc;
1643}
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:321
EFI_GUID efi_apple_net_boot_protocol_guid
Apple NetBoot protocol GUID.
Definition efi_guid.c:133
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:531
static struct interface_descriptor efi_pxe_tftp_desc
PXE file data transfer interface descriptor.
Definition efi_pxe.c:382
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:1467
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition efi_pxe.c:718
static struct process_descriptor efi_pxe_process_desc
UDP close process descriptor.
Definition efi_pxe.c:591
static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol
Apple NetBoot protocol.
Definition efi_pxe.c:1548
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
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:662
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:1931
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
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 1650 of file efi_pxe.c.

1650 {
1651 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1652 struct efi_pxe *pxe;
1653 int leak = efi_shutdown_in_progress;
1654 EFI_STATUS efirc;
1655
1656 /* Locate PXE base code */
1657 pxe = efi_pxe_find ( handle );
1658 if ( ! pxe ) {
1659 DBG ( "PXE could not find base code for %s\n",
1660 efi_handle_name ( handle ) );
1661 return;
1662 }
1663
1664 /* Stop base code */
1665 efi_pxe_stop ( &pxe->base );
1666
1667 /* Uninstall PXE base code protocol */
1668 if ( ( ! efi_shutdown_in_progress ) &&
1669 ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1670 handle,
1673 NULL ) ) != 0 ) ) {
1674 DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1675 pxe->name, strerror ( -EEFI ( efirc ) ) );
1676 leak = 1;
1677 }
1678 efi_nullify_pxe ( &pxe->base );
1679 efi_nullify_apple ( &pxe->apple );
1680
1681 /* Remove from list and drop list's reference */
1682 list_del ( &pxe->list );
1683 if ( ! leak )
1684 ref_put ( &pxe->refcnt );
1685
1686 /* Report leakage, if applicable */
1687 if ( leak && ( ! efi_shutdown_in_progress ) )
1688 DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1689}
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:773
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:498

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:337
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:351
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 375 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:375
#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 382 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:474

PXE UDP interface operations.

Definition at line 525 of file efi_pxe.c.

525 {
528};

◆ 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:525

PXE UDP interface descriptor.

Definition at line 531 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:584
#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 591 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:896
static EFI_STATUS EFIAPI efi_pxe_dhcp(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
Perform DHCP.
Definition efi_pxe.c:798
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:1284
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:989
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:1421
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:1381
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:852
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:1312
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:1336
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:1103

PXE base code protocol.

Definition at line 1467 of file efi_pxe.c.

1467 {
1469 .Start = efi_pxe_start,
1470 .Stop = efi_pxe_stop,
1471 .Dhcp = efi_pxe_dhcp,
1472 .Discover = efi_pxe_discover,
1473 .Mtftp = efi_pxe_mtftp,
1474 .UdpWrite = efi_pxe_udp_write,
1475 .UdpRead = efi_pxe_udp_read,
1476 .SetIpFilter = efi_pxe_set_ip_filter,
1477 .Arp = efi_pxe_arp,
1478 .SetParameters = efi_pxe_set_parameters,
1479 .SetStationIp = efi_pxe_set_station_ip,
1480 .SetPackets = efi_pxe_set_packets,
1481};

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:1540
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:1524

Apple NetBoot protocol.

Definition at line 1548 of file efi_pxe.c.

1548 {
1549 .GetDhcpResponse = efi_apple_get_dhcp_response,
1550 .GetBsdpResponse = efi_apple_get_bsdp_response,
1551};

Referenced by efi_pxe_install().