iPXE
Data Structures | Functions | Variables
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)
 
static void efi_pxe_free (struct refcnt *refcnt)
 Free PXE base code. More...
 
static LIST_HEAD (efi_pxes)
 List of PXE base codes. More...
 
static struct efi_pxeefi_pxe_find (EFI_HANDLE handle)
 Locate PXE base code. More...
 
static void efi_pxe_ip_sockaddr (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, struct sockaddr *sa)
 Populate socket address from EFI IP address. More...
 
static const char * efi_pxe_ip_ntoa (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
 Transcribe EFI IP address (for debugging) More...
 
static int efi_pxe_ip (struct efi_pxe *pxe)
 Populate local IP address. More...
 
static int efi_pxe_ip_filter (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
 Check if IP address matches filter. More...
 
static int efi_pxe_buf_realloc (struct xfer_buffer *xferbuf __unused, size_t len __unused)
 Reallocate PXE data transfer buffer. More...
 
static void efi_pxe_buf_write (struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
 Write data to PXE data transfer buffer. More...
 
static void efi_pxe_tftp_close (struct efi_pxe *pxe, int rc)
 Close PXE (M)TFTP download interface. More...
 
static size_t efi_pxe_tftp_window (struct efi_pxe *pxe)
 Check PXE (M)TFTP download flow control window. More...
 
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. More...
 
static int efi_pxe_tftp_open (struct efi_pxe *pxe, EFI_IP_ADDRESS *ip, const char *filename)
 Open (M)TFTP download interface. More...
 
static void efi_pxe_udp_close (struct efi_pxe *pxe, int rc)
 Close UDP interface. More...
 
static int efi_pxe_udp_deliver (struct efi_pxe *pxe, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive UDP packet. More...
 
static int efi_pxe_udp_open (struct efi_pxe *pxe)
 Open UDP interface. More...
 
static void efi_pxe_udp_schedule_close (struct efi_pxe *pxe)
 Schedule close of UDP interface. More...
 
static void efi_pxe_udp_scheduled_close (struct efi_pxe *pxe)
 Scheduled close of UDP interface. More...
 
static const char * efi_pxe_fake_name (struct efi_pxe *pxe, EFI_PXE_BASE_CODE_PACKET *packet)
 Name fake DHCP packet. More...
 
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. More...
 
static void efi_pxe_fake_all (struct efi_pxe *pxe)
 Construct fake DHCP packets. More...
 
static EFI_STATUS EFIAPI efi_pxe_start (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
 Start PXE base code. More...
 
static EFI_STATUS EFIAPI efi_pxe_stop (EFI_PXE_BASE_CODE_PROTOCOL *base)
 Stop PXE base code. More...
 
static EFI_STATUS EFIAPI efi_pxe_dhcp (EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
 Perform DHCP. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static EFI_STATUS EFIAPI efi_pxe_arp (EFI_PXE_BASE_CODE_PROTOCOL *base, EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac)
 Resolve MAC address. More...
 
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. More...
 
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. More...
 
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. More...
 
static EFI_STATUS EFIAPI efi_apple_get_response (EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len, VOID *data)
 Get DHCP/BSDP response. More...
 
static EFI_STATUS EFIAPI efi_apple_get_dhcp_response (EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
 Get DHCP response. More...
 
static EFI_STATUS EFIAPI efi_apple_get_bsdp_response (EFI_APPLE_NET_BOOT_PROTOCOL *apple, UINTN *len, VOID *data)
 Get BSDP response. More...
 
int efi_pxe_install (EFI_HANDLE handle, struct net_device *netdev)
 Install PXE base code protocol. More...
 
void efi_pxe_uninstall (EFI_HANDLE handle)
 Uninstall PXE base code protocol. More...
 

Variables

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

Detailed Description

EFI PXE base code protocol.

Definition in file efi_pxe.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ efi_pxe_free()

static void efi_pxe_free ( struct refcnt refcnt)
static

Free PXE base code.

Parameters
refcntReference count

Definition at line 116 of file efi_pxe.c.

116  {
117  struct efi_pxe *pxe = container_of ( refcnt, struct efi_pxe, refcnt );
118 
119  netdev_put ( pxe->netdev );
120  free ( pxe );
121 }
A PXE base code.
Definition: efi_pxe.c:69
A reference counter.
Definition: refcnt.h:26
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

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

Referenced by efi_pxe_install().

◆ LIST_HEAD()

static LIST_HEAD ( efi_pxes  )
static

List of PXE base codes.

◆ efi_pxe_find()

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

132  {
133  struct efi_pxe *pxe;
134 
135  /* Locate base code */
136  list_for_each_entry ( pxe, &efi_pxes, list ) {
137  if ( pxe->handle == handle )
138  return pxe;
139  }
140 
141  return NULL;
142 }
struct list_head list
List of PXE base codes.
Definition: efi_pxe.c:77
A PXE base code.
Definition: efi_pxe.c:69
EFI_HANDLE handle
Installed handle.
Definition: efi_pxe.c:80
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by efi_pxe_uninstall().

◆ efi_pxe_ip_sockaddr()

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

192  {
193  union {
194  struct sockaddr sa;
195  struct sockaddr_efi se;
196  } *sockaddr = container_of ( sa, typeof ( *sockaddr ), sa );
197 
198  /* Initialise socket address */
199  memset ( sockaddr, 0, sizeof ( *sockaddr ) );
200  sockaddr->sa.sa_family = pxe->tcpip->sa_family;
201  memcpy ( &sockaddr->se.se_addr, ip, pxe->net->net_addr_len );
202  sockaddr->se.se_scope_id = pxe->netdev->scope_id;
203 }
An EFI socket address.
Definition: efi_pxe.c:155
sa_family_t sa_family
Socket address family.
Definition: socket.h:101
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct sockaddr sa
Definition: syslog.c:55
Generalized socket address structure.
Definition: socket.h:96
sa_family_t sa_family
Network address family.
Definition: tcpip.h:144
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:91
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
struct tcpip_net_protocol * tcpip
TCP/IP network-layer protocol.
Definition: efi_pxe.c:89
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:101
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
void * memset(void *dest, int character, size_t len) __nonnull

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()

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

213  {
214 
215  return pxe->net->ntoa ( ip );
216 }
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition: netdevice.h:94
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:91
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58

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()

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

224  {
225  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
226  struct in_addr address;
227  struct in_addr netmask;
228 
229  /* It's unclear which of the potentially many IPv6 addresses
230  * is supposed to be used.
231  */
232  if ( mode->UsingIpv6 )
233  return -ENOTSUP;
234 
235  /* Fetch IP address and subnet mask */
236  fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &ip_setting,
237  &address );
238  fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &netmask_setting,
239  &netmask );
240 
241  /* Populate IP address and subnet mask */
242  memset ( &mode->StationIp, 0, sizeof ( mode->StationIp ) );
243  memcpy ( &mode->StationIp, &address, sizeof ( address ) );
244  memset ( &mode->SubnetMask, 0, sizeof ( mode->SubnetMask ) );
245  memcpy ( &mode->SubnetMask, &netmask, sizeof ( netmask ) );
246 
247  return 0;
248 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
uint64_t address
Base address.
Definition: ena.h:24
EFI_IP_ADDRESS SubnetMask
Definition: PxeBaseCode.h:292
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
IP address structure.
Definition: in.h:39
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:291
void * memset(void *dest, int character, size_t len) __nonnull

References address, ENOTSUP, fetch_ipv4_setting(), memcpy(), memset(), efi_pxe::mode, efi_pxe::netdev, netdev_settings(), EFI_PXE_BASE_CODE_MODE::StationIp, EFI_PXE_BASE_CODE_MODE::SubnetMask, and EFI_PXE_BASE_CODE_MODE::UsingIpv6.

Referenced by efi_pxe_dhcp(), and efi_pxe_start().

◆ efi_pxe_ip_filter()

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

257  {
258  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
260  uint8_t filters = filter->Filters;
261  union {
263  struct in_addr in;
264  struct in6_addr in6;
265  } *u = container_of ( ip, typeof ( *u ), ip );
266  size_t addr_len = pxe->net->net_addr_len;
267  unsigned int i;
268 
269  /* Match everything, if applicable */
271  return 1;
272 
273  /* Match all multicasts, if applicable */
275  if ( mode->UsingIpv6 ) {
276  if ( IN6_IS_ADDR_MULTICAST ( &u->in6 ) )
277  return 1;
278  } else {
279  if ( IN_IS_MULTICAST ( u->in.s_addr ) )
280  return 1;
281  }
282  }
283 
284  /* Match IPv4 broadcasts, if applicable */
285  if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST ) {
286  if ( ( ! mode->UsingIpv6 ) &&
287  ( u->in.s_addr == INADDR_BROADCAST ) )
288  return 1;
289  }
290 
291  /* Match station address, if applicable */
292  if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP ) {
293  if ( memcmp ( ip, &mode->StationIp, addr_len ) == 0 )
294  return 1;
295  }
296 
297  /* Match explicit addresses, if applicable */
298  for ( i = 0 ; i < filter->IpCnt ; i++ ) {
299  if ( memcmp ( ip, &filter->IpList[i], addr_len ) == 0 )
300  return 1;
301  }
302 
303  return 0;
304 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition: PxeBaseCode.h:85
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
__be32 in[4]
Definition: CIB_PRM.h:35
UINT8_t filter
Receive packet filter.
Definition: pxe_api.h:68
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST
Definition: PxeBaseCode.h:87
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition: PxeBaseCode.h:86
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
16-byte buffer aligned on a 4-byte boundary.
Definition: UefiBaseType.h:105
#define INADDR_BROADCAST
Definition: in.h:21
IP6 address structure.
Definition: in.h:48
IP address structure.
Definition: in.h:39
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:91
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
unsigned char uint8_t
Definition: stdint.h:10
IP Receive Filter structure.
Definition: PxeBaseCode.h:77
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition: PxeBaseCode.h:84
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:101
union @17 u
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:65
EFI_PXE_BASE_CODE_IP_FILTER IpFilter
Definition: PxeBaseCode.h:299
#define IN_IS_MULTICAST(addr)
Definition: in.h:33
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:291
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114

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, EFI_PXE_BASE_CODE_MODE::IpFilter, memcmp(), efi_pxe::mode, efi_pxe::net, net_protocol::net_addr_len, EFI_PXE_BASE_CODE_MODE::StationIp, typeof(), u, and EFI_PXE_BASE_CODE_MODE::UsingIpv6.

Referenced by efi_pxe_udp_read().

◆ efi_pxe_buf_realloc()

static int efi_pxe_buf_realloc ( struct xfer_buffer *xferbuf  __unused,
size_t len  __unused 
)
static

Reallocate PXE data transfer buffer.

Parameters
xferbufData transfer buffer
lenNew length (or zero to free buffer)
Return values
rcReturn status code

Definition at line 320 of file efi_pxe.c.

321  {
322 
323  /* Can never reallocate: return EFI_BUFFER_TOO_SMALL */
324  return -ERANGE;
325 }
#define ERANGE
Result too large.
Definition: errno.h:639

References ERANGE.

◆ efi_pxe_buf_write()

static void efi_pxe_buf_write ( struct xfer_buffer xferbuf,
size_t  offset,
const void *  data,
size_t  len 
)
static

Write data to PXE data transfer buffer.

Parameters
xferbufData transfer buffer
offsetStarting offset
dataData to copy
lenLength of data

Definition at line 335 of file efi_pxe.c.

336  {
337 
338  /* Copy data to buffer */
339  memcpy ( ( xferbuf->data + offset ), data, len );
340 }
void * data
Data.
Definition: xferbuf.h:21
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References xfer_buffer::data, data, len, memcpy(), and offset.

◆ efi_pxe_tftp_close()

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

361  {
362 
363  /* Restart interface */
364  intf_restart ( &pxe->tftp, rc );
365 
366  /* Record overall status */
367  pxe->rc = rc;
368 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
int rc
Overall return status.
Definition: efi_pxe.c:101
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:97

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()

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

376  {
377 
378  /* Return requested blocksize */
379  return pxe->blksize;
380 }
size_t blksize
Block size (for TFTP)
Definition: efi_pxe.c:99

References efi_pxe::blksize.

◆ efi_pxe_tftp_deliver()

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

392  {
393  int rc;
394 
395  /* Deliver to data transfer buffer */
396  if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
397  meta ) ) != 0 )
398  goto err_deliver;
399 
400  return 0;
401 
402  err_deliver:
403  efi_pxe_tftp_close ( pxe, rc );
404  return rc;
405 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:152
struct xfer_buffer buf
Data transfer buffer.
Definition: efi_pxe.c:94
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
int meta(WINDOW *, bool)
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition: efi_pxe.c:361

References efi_pxe::buf, efi_pxe_tftp_close(), iob_disown, meta(), rc, and xferbuf_deliver().

◆ efi_pxe_tftp_open()

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

427  {
428  struct sockaddr server;
429  struct uri *uri;
430  int rc;
431 
432  /* Parse server address and filename */
433  efi_pxe_ip_sockaddr ( pxe, ip, &server );
434  uri = pxe_uri ( &server, filename );
435  if ( ! uri ) {
436  DBGC ( pxe, "PXE %s could not parse %s:%s\n", pxe->name,
437  efi_pxe_ip_ntoa ( pxe, ip ), filename );
438  rc = -ENOTSUP;
439  goto err_parse;
440  }
441 
442  /* Open URI */
443  if ( ( rc = xfer_open_uri ( &pxe->tftp, uri ) ) != 0 ) {
444  DBGC ( pxe, "PXE %s could not open: %s\n",
445  pxe->name, strerror ( rc ) );
446  goto err_open;
447  }
448 
449  err_open:
450  uri_put ( uri );
451  err_parse:
452  return rc;
453 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:191
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
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:212
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition: uri.c:808
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:67
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: efi_pxe.c:75
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:97
A Uniform Resource Identifier.
Definition: uri.h:64

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()

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

478  {
479  struct io_buffer *iobuf;
480  struct io_buffer *tmp;
481 
482  /* Release our claim on SNP devices, if applicable */
483  if ( process_running ( &pxe->process ) )
484  efi_snp_release();
485 
486  /* Stop process */
487  process_del ( &pxe->process );
488 
489  /* Restart UDP interface */
490  intf_restart ( &pxe->udp, rc );
491 
492  /* Flush any received UDP packets */
493  list_for_each_entry_safe ( iobuf, tmp, &pxe->queue, list ) {
494  list_del ( &iobuf->list );
495  free_iob ( iobuf );
496  }
497 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
struct interface udp
UDP interface.
Definition: efi_pxe.c:104
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
unsigned long tmp
Definition: linux_pci.h:53
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#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:458
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:99
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:175
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
struct process process
UDP interface closer process.
Definition: efi_pxe.c:108
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:106
A persistent I/O buffer.
Definition: iobuf.h:33

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()

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

508  {
509  struct sockaddr_efi *se_src;
510  struct sockaddr_efi *se_dest;
511  struct tcpip_net_protocol *tcpip;
512  struct net_protocol *net;
513  struct efi_pxe_udp_pseudo_header *pshdr;
514  size_t addr_len;
515  size_t pshdr_len;
516  int rc;
517 
518  /* Sanity checks */
519  assert ( meta != NULL );
520  se_src = ( ( struct sockaddr_efi * ) meta->src );
521  assert ( se_src != NULL );
522  se_dest = ( ( struct sockaddr_efi * ) meta->dest );
523  assert ( se_dest != NULL );
524  assert ( se_src->se_family == se_dest->se_family );
525 
526  /* Determine protocol */
527  tcpip = tcpip_net_protocol ( se_src->se_family );
528  if ( ! tcpip ) {
529  rc = -ENOTSUP;
530  goto err_unsupported;
531  }
532  net = tcpip->net_protocol;
533  addr_len = net->net_addr_len;
534 
535  /* Construct pseudo-header */
536  pshdr_len = ( sizeof ( *pshdr ) + ( 2 * addr_len ) );
537  if ( ( rc = iob_ensure_headroom ( iobuf, pshdr_len ) ) != 0 )
538  goto err_headroom;
539  memcpy ( iob_push ( iobuf, addr_len ), &se_src->se_addr, addr_len );
540  memcpy ( iob_push ( iobuf, addr_len ), &se_dest->se_addr, addr_len );
541  pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
542  pshdr->net = net;
543  pshdr->dest_port = ntohs ( se_dest->se_port );
544  pshdr->src_port = ntohs ( se_src->se_port );
545 
546  /* Add to queue */
547  list_add_tail ( &iobuf->list, &pxe->queue );
548 
549  return 0;
550 
551  err_unsupported:
552  err_headroom:
553  free_iob ( iobuf );
554  return rc;
555 }
EFI UDP pseudo-header.
Definition: efi_pxe.c:463
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t dest_port
Destination port.
Definition: efi_pxe.c:467
An EFI socket address.
Definition: efi_pxe.c:155
#define iob_push(iobuf, len)
Definition: iobuf.h:84
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
EFI_IP_ADDRESS se_addr
IP address.
Definition: efi_pxe.c:169
#define ntohs(value)
Definition: byteswap.h:136
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:465
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct tcpip_net_protocol * tcpip_net_protocol(sa_family_t sa_family)
Find TCP/IP network-layer protocol.
Definition: tcpip.c:68
uint16_t se_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition: efi_pxe.c:161
struct net_protocol * net_protocol
Network-layer protocol.
Definition: tcpip.h:148
int meta(WINDOW *, bool)
uint16_t src_port
Source port.
Definition: efi_pxe.c:469
A network-layer protocol.
Definition: netdevice.h:64
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:101
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:106
A network-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:140
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition: iobuf.c:228
sa_family_t se_family
Socket address family (part of struct sockaddr)
Definition: efi_pxe.c:157
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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()

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

573  {
574  int rc;
575 
576  /* If interface is already open, then cancel the scheduled close */
577  if ( process_running ( &pxe->process ) ) {
578  process_del ( &pxe->process );
579  return 0;
580  }
581 
582  /* Open promiscuous UDP interface */
583  if ( ( rc = udp_open_promisc ( &pxe->udp ) ) != 0 ) {
584  DBGC ( pxe, "PXE %s could not open UDP connection: %s\n",
585  pxe->name, strerror ( rc ) );
586  return rc;
587  }
588 
589  /* Claim network devices */
590  efi_snp_claim();
591 
592  return 0;
593 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
struct interface udp
UDP interface.
Definition: efi_pxe.c:104
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
const char * name
Name.
Definition: efi_pxe.c:75
int udp_open_promisc(struct interface *xfer)
Open a promiscuous UDP connection.
Definition: udp.c:144
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:175
struct process process
UDP interface closer process.
Definition: efi_pxe.c:108

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()

static void efi_pxe_udp_schedule_close ( struct efi_pxe pxe)
static

Schedule close of UDP interface.

Parameters
pxePXE base code

Definition at line 600 of file efi_pxe.c.

600  {
601 
602  /* The EFI PXE base code protocol does not provide any
603  * explicit UDP open/close methods. To avoid the overhead of
604  * reopening a socket for each read/write operation, we start
605  * a process which will close the socket immediately if the
606  * next call into iPXE is anything other than a UDP
607  * read/write.
608  */
609  process_add ( &pxe->process );
610 }
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct process process
UDP interface closer process.
Definition: efi_pxe.c:108

References efi_pxe::process, and process_add().

Referenced by efi_pxe_udp_read(), and efi_pxe_udp_write().

◆ efi_pxe_udp_scheduled_close()

static void efi_pxe_udp_scheduled_close ( struct efi_pxe pxe)
static

Scheduled close of UDP interface.

Parameters
pxePXE base code

Definition at line 617 of file efi_pxe.c.

617  {
618 
619  /* Close UDP interface */
620  efi_pxe_udp_close ( pxe, 0 );
621 }
static void efi_pxe_udp_close(struct efi_pxe *pxe, int rc)
Close UDP interface.
Definition: efi_pxe.c:478

References efi_pxe_udp_close().

◆ efi_pxe_fake_name()

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

642  {
643  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
644 
645  if ( packet == &mode->DhcpDiscover ) {
646  return "DhcpDiscover";
647  } else if ( packet == &mode->DhcpAck ) {
648  return "DhcpAck";
649  } else if ( packet == &mode->ProxyOffer ) {
650  return "ProxyOffer";
651  } else if ( packet == &mode->PxeDiscover ) {
652  return "PxeDiscover";
653  } else if ( packet == &mode->PxeReply ) {
654  return "PxeReply";
655  } else if ( packet == &mode->PxeBisReply ) {
656  return "PxeBisReply";
657  } else {
658  return "<UNKNOWN>";
659  }
660 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:297
EFI_PXE_BASE_CODE_PACKET PxeBisReply
Definition: PxeBaseCode.h:298
EFI_PXE_BASE_CODE_PACKET DhcpDiscover
Definition: PxeBaseCode.h:293
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:294
EFI_PXE_BASE_CODE_PACKET PxeDiscover
Definition: PxeBaseCode.h:296
EFI_PXE_BASE_CODE_PACKET ProxyOffer
Definition: PxeBaseCode.h:295

References EFI_PXE_BASE_CODE_MODE::DhcpAck, EFI_PXE_BASE_CODE_MODE::DhcpDiscover, efi_pxe::mode, EFI_PXE_BASE_CODE_MODE::ProxyOffer, EFI_PXE_BASE_CODE_MODE::PxeBisReply, EFI_PXE_BASE_CODE_MODE::PxeDiscover, and EFI_PXE_BASE_CODE_MODE::PxeReply.

Referenced by efi_pxe_fake().

◆ efi_pxe_fake()

static BOOLEAN efi_pxe_fake ( struct efi_pxe pxe,
int(*)(struct net_device *netdev, void *data, size_t len fake,
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 670 of file efi_pxe.c.

673  {
674  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
675  struct dhcp_packet dhcppkt;
676  struct dhcphdr *dhcphdr;
677  unsigned int len;
678  int rc;
679 
680  /* The fake packet constructors do not support IPv6 */
681  if ( mode->UsingIpv6 )
682  return FALSE;
683 
684  /* Attempt to construct packet */
685  if ( ( rc = fake ( pxe->netdev, packet, sizeof ( *packet ) ) != 0 ) ) {
686  DBGC ( pxe, "PXE %s could not fake %s: %s\n", pxe->name,
687  efi_pxe_fake_name ( pxe, packet ), strerror ( rc ) );
688  return FALSE;
689  }
690 
691  /* The WDS bootstrap wdsmgfw.efi has a buggy DHCPv4 packet
692  * parser which does not correctly handle DHCP padding bytes.
693  * Specifically, if a padding byte (i.e. a zero) is
694  * encountered, the parse will first increment the pointer by
695  * one to skip over the padding byte but will then drop into
696  * the code path for handling normal options, which increments
697  * the pointer by two to skip over the (already-skipped) type
698  * field and the (non-existent) length field.
699  *
700  * The upshot of this bug in WDS is that the parser will fail
701  * with an error 0xc0000023 if the number of spare bytes after
702  * the end of the options is not an exact multiple of three.
703  *
704  * Work around this buggy parser by adding an explicit
705  * DHCP_END tag.
706  */
707  dhcphdr = container_of ( &packet->Dhcpv4.BootpOpcode,
708  struct dhcphdr, op );
709  dhcppkt_init ( &dhcppkt, dhcphdr, sizeof ( *packet ) );
710  len = dhcppkt_len ( &dhcppkt );
711  if ( len < sizeof ( *packet ) )
712  packet->Raw[len] = DHCP_END;
713 
714  return TRUE;
715 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A DHCP packet.
Definition: dhcppkt.h:20
#define DBGC(...)
Definition: compiler.h:505
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:641
EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4
Definition: PxeBaseCode.h:255
const char * name
Name.
Definition: efi_pxe.c:75
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define TRUE
Definition: tlan.h:46
A DHCP header.
Definition: dhcp.h:613
void dhcppkt_init(struct dhcp_packet *dhcppkt, struct dhcphdr *data, size_t len)
Initialise DHCP packet.
Definition: dhcppkt.c:300
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
uint32_t len
Length.
Definition: ena.h:14
static size_t dhcppkt_len(struct dhcp_packet *dhcppkt)
Get used length of DHCP packet.
Definition: dhcppkt.h:59
#define FALSE
Definition: tlan.h:45
#define DHCP_END
End of options.
Definition: dhcp.h:546

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

Referenced by efi_pxe_fake_all().

◆ efi_pxe_fake_all()

static void efi_pxe_fake_all ( struct efi_pxe pxe)
static

Construct fake DHCP packets.

Parameters
pxePXE base code

Definition at line 722 of file efi_pxe.c.

722  {
723  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
724 
725  /* Construct fake packets */
726  mode->DhcpDiscoverValid =
728  &mode->DhcpDiscover );
729  mode->DhcpAckReceived =
731  &mode->DhcpAck );
732  mode->PxeReplyReceived =
734  &mode->PxeReply );
735 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
int create_fakedhcpack(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPACK packet.
Definition: fakedhcp.c:136
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:297
int create_fakedhcpdiscover(struct net_device *netdev, void *data, size_t max_len)
Create fake DHCPDISCOVER packet.
Definition: fakedhcp.c:109
EFI_PXE_BASE_CODE_PACKET DhcpDiscover
Definition: PxeBaseCode.h:293
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:294
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:670
int create_fakepxebsack(struct net_device *netdev, void *data, size_t max_len)
Create fake PXE Boot Server ACK packet.
Definition: fakedhcp.c:178

References create_fakedhcpack(), create_fakedhcpdiscover(), create_fakepxebsack(), EFI_PXE_BASE_CODE_MODE::DhcpAck, EFI_PXE_BASE_CODE_MODE::DhcpAckReceived, EFI_PXE_BASE_CODE_MODE::DhcpDiscover, EFI_PXE_BASE_CODE_MODE::DhcpDiscoverValid, efi_pxe_fake(), efi_pxe::mode, EFI_PXE_BASE_CODE_MODE::PxeReply, and EFI_PXE_BASE_CODE_MODE::PxeReplyReceived.

Referenced by efi_pxe_dhcp(), and efi_pxe_start().

◆ efi_pxe_start()

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

752  {
753  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
756  sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
757  int rc;
758 
759  DBGC ( pxe, "PXE %s START %s\n",
760  pxe->name, ( use_ipv6 ? "IPv6" : "IPv4" ) );
761 
762  /* Initialise mode structure */
763  memset ( mode, 0, sizeof ( *mode ) );
764  mode->AutoArp = TRUE;
765  mode->TTL = DEFAULT_TTL;
766  mode->ToS = DEFAULT_ToS;
767  mode->IpFilter.Filters =
772 
773  /* Check for IPv4/IPv6 support */
774  mode->Ipv6Supported = ( ipv6 != NULL );
775  mode->Ipv6Available = ( ipv6 != NULL );
776  pxe->tcpip = tcpip_net_protocol ( family );
777  if ( ! pxe->tcpip ) {
778  DBGC ( pxe, "PXE %s has no support for %s\n",
779  pxe->name, socket_family_name ( family ) );
780  return EFI_UNSUPPORTED;
781  }
782  pxe->net = pxe->tcpip->net_protocol;
783  mode->UsingIpv6 = use_ipv6;
784 
785  /* Populate station IP address */
786  if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
787  return rc;
788 
789  /* Construct fake DHCP packets */
790  efi_pxe_fake_all ( pxe );
791 
792  /* Record that base code is started */
793  mode->Started = TRUE;
794  DBGC ( pxe, "PXE %s using %s\n",
795  pxe->name, pxe->net->ntoa ( &mode->StationIp ) );
796 
797  return 0;
798 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition: PxeBaseCode.h:85
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST
Definition: PxeBaseCode.h:87
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
static int efi_pxe_ip(struct efi_pxe *pxe)
Populate local IP address.
Definition: efi_pxe.c:224
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition: PxeBaseCode.h:86
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition: netdevice.h:94
struct tcpip_net_protocol * tcpip_net_protocol(sa_family_t sa_family)
Find TCP/IP network-layer protocol.
Definition: tcpip.c:68
uint16_t sa_family_t
A socket address family.
Definition: socket.h:85
struct net_protocol * net_protocol
Network-layer protocol.
Definition: tcpip.h:148
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:91
#define DEFAULT_TTL
Default IP TTL and ToS.
Definition: PxeBaseCode.h:39
#define DEFAULT_ToS
Definition: PxeBaseCode.h:40
static const char * socket_family_name(int family)
Name address family.
Definition: socket.h:75
static void efi_pxe_fake_all(struct efi_pxe *pxe)
Construct fake DHCP packets.
Definition: efi_pxe.c:722
#define TRUE
Definition: tlan.h:46
struct tcpip_net_protocol * tcpip
TCP/IP network-layer protocol.
Definition: efi_pxe.c:89
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition: PxeBaseCode.h:84
EFI_PXE_BASE_CODE_IP_FILTER IpFilter
Definition: PxeBaseCode.h:299
A network-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:140
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:291
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
void * memset(void *dest, int character, size_t len) __nonnull

References AF_INET, AF_INET6, EFI_PXE_BASE_CODE_MODE::AutoArp, 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, EFI_PXE_BASE_CODE_IP_FILTER::Filters, EFI_PXE_BASE_CODE_MODE::IpFilter, EFI_PXE_BASE_CODE_MODE::Ipv6Available, EFI_PXE_BASE_CODE_MODE::Ipv6Supported, memset(), efi_pxe::mode, efi_pxe::name, efi_pxe::net, tcpip_net_protocol::net_protocol, net_protocol::ntoa, NULL, rc, socket_family_name(), EFI_PXE_BASE_CODE_MODE::Started, EFI_PXE_BASE_CODE_MODE::StationIp, efi_pxe::tcpip, tcpip_net_protocol(), EFI_PXE_BASE_CODE_MODE::ToS, TRUE, EFI_PXE_BASE_CODE_MODE::TTL, and EFI_PXE_BASE_CODE_MODE::UsingIpv6.

Referenced by efi_pxe_install().

◆ efi_pxe_stop()

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

806  {
807  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
809 
810  DBGC ( pxe, "PXE %s STOP\n", pxe->name );
811 
812  /* Record that base code is stopped */
813  mode->Started = FALSE;
814 
815  /* Close TFTP */
816  efi_pxe_tftp_close ( pxe, 0 );
817 
818  /* Close UDP */
819  efi_pxe_udp_close ( pxe, 0 );
820 
821  return 0;
822 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition: efi_pxe.c:361
#define FALSE
Definition: tlan.h:45
static void efi_pxe_udp_close(struct efi_pxe *pxe, int rc)
Close UDP interface.
Definition: efi_pxe.c:478

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

Referenced by efi_pxe_uninstall().

◆ efi_pxe_dhcp()

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

832  {
833  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
834  struct net_device *netdev = pxe->netdev;
835  int rc;
836 
837  DBGC ( pxe, "PXE %s DHCP %s\n",
838  pxe->name, ( sort ? "sorted" : "unsorted" ) );
839 
840  /* Claim network devices */
841  efi_snp_claim();
842 
843  /* Initiate configuration */
844  if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
845  DBGC ( pxe, "PXE %s could not initiate configuration: %s\n",
846  pxe->name, strerror ( rc ) );
847  goto err_configure;
848  }
849 
850  /* Wait for configuration to complete (or time out) */
852  step();
853 
854  /* Report timeout if configuration failed */
855  if ( ! netdev_configuration_ok ( netdev ) ) {
856  rc = -ETIMEDOUT;
857  goto err_timeout;
858  }
859 
860  /* Update station IP address */
861  if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
862  goto err_ip;
863 
864  /* Update faked DHCP packets */
865  efi_pxe_fake_all ( pxe );
866 
867  err_ip:
868  err_timeout:
869  err_configure:
870  efi_snp_release();
871  return EFIRC ( rc );
872 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int netdev_configuration_in_progress(struct net_device *netdev)
Check if network device configuration is in progress.
Definition: netdevice.c:1379
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
int netdev_configure_all(struct net_device *netdev)
Start network device configuration via all supported configurators.
Definition: netdevice.c:1335
static int efi_pxe_ip(struct efi_pxe *pxe)
Populate local IP address.
Definition: efi_pxe.c:224
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A network device.
Definition: netdevice.h:352
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:99
static void efi_pxe_fake_all(struct efi_pxe *pxe)
Construct fake DHCP packets.
Definition: efi_pxe.c:722
void step(void)
Single-step a single process.
Definition: process.c:98
int netdev_configuration_ok(struct net_device *netdev)
Check if network device has at least one successful configuration.
Definition: netdevice.c:1391
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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

◆ efi_pxe_discover()

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

886  {
887  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
889  unsigned int i;
890 
891  DBGC ( pxe, "PXE %s DISCOVER type %d layer %d%s\n",
892  pxe->name, type, *layer, ( bis ? " bis" : "" ) );
893  if ( info ) {
894  DBGC ( pxe, "%s%s%s%s %s",
895  ( info->UseMCast ? " mcast" : "" ),
896  ( info->UseBCast ? " bcast" : "" ),
897  ( info->UseUCast ? " ucast" : "" ),
898  ( info->MustUseList ? " list" : "" ),
899  efi_pxe_ip_ntoa ( pxe, &info->ServerMCastIp ) );
900  for ( i = 0 ; i < info->IpCnt ; i++ ) {
901  ip = &info->SrvList[i].IpAddr;
902  DBGC ( pxe, " %d%s:%s", info->SrvList[i].Type,
903  ( info->SrvList[i].AcceptAnyResponse ?
904  ":any" : "" ), efi_pxe_ip_ntoa ( pxe, ip ) );
905  }
906  }
907  DBGC ( pxe, "\n" );
908 
909  /* Not used by any bootstrap I can find to test with */
910  return EFI_UNSUPPORTED;
911 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
u32 info
Definition: ar9003_mac.h:67
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:212
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
16-byte buffer aligned on a 4-byte boundary.
Definition: UefiBaseType.h:105
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
uint32_t type
Operating system type.
Definition: ena.h:12

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

◆ efi_pxe_mtftp()

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

933  {
934  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
935  int rc;
936 
937  DBGC ( pxe, "PXE %s MTFTP %d%s %p+%llx", pxe->name, opcode,
938  ( overwrite ? " overwrite" : "" ), data, *len );
939  if ( blksize )
940  DBGC ( pxe, " blksize %zd", ( ( size_t ) *blksize ) );
941  DBGC ( pxe, " %s:%s", efi_pxe_ip_ntoa ( pxe, ip ), filename );
942  if ( info ) {
943  DBGC ( pxe, " %s:%d:%d:%d:%d",
944  efi_pxe_ip_ntoa ( pxe, &info->MCastIp ),
945  info->CPort, info->SPort, info->ListenTimeout,
946  info->TransmitTimeout );
947  }
948  DBGC ( pxe, "%s\n", ( callback ? " callback" : "" ) );
949 
950  /* Fail unless operation is supported */
951  if ( ! ( ( opcode == EFI_PXE_BASE_CODE_TFTP_READ_FILE ) ||
953  DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
954  pxe->name, opcode );
955  rc = -ENOTSUP;
956  goto err_opcode;
957  }
958 
959  /* Claim network devices */
960  efi_snp_claim();
961 
962  /* Determine block size. Ignore the requested block size
963  * unless we are using callbacks, since limiting HTTP to a
964  * 512-byte TCP window is not sensible.
965  */
966  pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
967 
968  /* Initialise data transfer buffer */
969  pxe->buf.data = data;
970  pxe->buf.len = *len;
971 
972  /* Open download */
973  if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
974  ( ( const char * ) filename ) ) ) != 0 )
975  goto err_open;
976 
977  /* Wait for download to complete */
978  pxe->rc = -EINPROGRESS;
979  while ( pxe->rc == -EINPROGRESS )
980  step();
981  if ( ( rc = pxe->rc ) != 0 ) {
982  DBGC ( pxe, "PXE %s download failed: %s\n",
983  pxe->name, strerror ( rc ) );
984  goto err_download;
985  }
986 
987  err_download:
988  efi_pxe_tftp_close ( pxe, rc );
989  err_open:
990  efi_snp_release();
991  err_opcode:
992  return EFIRC ( rc );
993 }
void * data
Data.
Definition: xferbuf.h:21
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
u32 info
Definition: ar9003_mac.h:67
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:212
uint8_t opcode
Opcode.
Definition: ena.h:16
A PXE base code.
Definition: efi_pxe.c:69
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:426
#define DBGC(...)
Definition: compiler.h:505
uint32_t blksize
Block size for this segment.
Definition: pccrc.h:24
struct xfer_buffer buf
Data transfer buffer.
Definition: efi_pxe.c:94
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
static const void * base
Base address.
Definition: crypto.h:335
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: efi_pxe.c:75
size_t len
Size of data.
Definition: xferbuf.h:23
size_t blksize
Block size (for TFTP)
Definition: efi_pxe.c:99
int rc
Overall return status.
Definition: efi_pxe.c:101
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:99
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition: efi_pxe.c:361
uint32_t len
Length.
Definition: ena.h:14
void step(void)
Single-step a single process.
Definition: process.c:98
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int overwrite(const WINDOW *, WINDOW *)
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

References base, blksize, efi_pxe::blksize, efi_pxe::buf, container_of, xfer_buffer::data, data, DBGC, EFI_PXE_BASE_CODE_MTFTP_READ_FILE, 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::len, efi_pxe::name, opcode, overwrite(), efi_pxe::rc, rc, step(), and strerror().

◆ efi_pxe_udp_write()

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

1017  {
1018  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1019  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1020  struct io_buffer *iobuf;
1021  struct xfer_metadata meta;
1022  union {
1023  struct sockaddr_tcpip st;
1024  struct sockaddr sa;
1025  } dest;
1026  union {
1027  struct sockaddr_tcpip st;
1028  struct sockaddr sa;
1029  } src;
1030  int rc;
1031 
1032  DBGC2 ( pxe, "PXE %s UDP WRITE ", pxe->name );
1033  if ( src_ip )
1034  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1035  DBGC2 ( pxe, ":" );
1036  if ( src_port &&
1038  DBGC2 ( pxe, "%d", *src_port );
1039  } else {
1040  DBGC2 ( pxe, "*" );
1041  }
1042  DBGC2 ( pxe, "->%s:%d", efi_pxe_ip_ntoa ( pxe, dest_ip ), *dest_port );
1043  if ( gateway )
1044  DBGC2 ( pxe, " via %s", efi_pxe_ip_ntoa ( pxe, gateway ) );
1045  if ( hdr_len )
1046  DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1047  DBGC2 ( pxe, " %p+%zx", data, ( ( size_t ) *len ) );
1049  DBGC2 ( pxe, " frag" );
1050  DBGC2 ( pxe, "\n" );
1051 
1052  /* Open UDP connection (if applicable) */
1053  if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1054  goto err_open;
1055 
1056  /* Construct destination address */
1057  efi_pxe_ip_sockaddr ( pxe, dest_ip, &dest.sa );
1058  dest.st.st_port = htons ( *dest_port );
1059 
1060  /* Construct source address */
1061  efi_pxe_ip_sockaddr ( pxe, ( src_ip ? src_ip : &mode->StationIp ),
1062  &src.sa );
1063  if ( src_port &&
1065  src.st.st_port = htons ( *src_port );
1066  } else {
1067  /* The API does not allow for a sensible concept of
1068  * binding to a local port, so just use a random value.
1069  */
1070  src.st.st_port = ( random() | htons ( 1024 ) );
1071  if ( src_port )
1072  *src_port = ntohs ( src.st.st_port );
1073  }
1074 
1075  /* Allocate I/O buffer */
1076  iobuf = xfer_alloc_iob ( &pxe->udp,
1077  ( *len + ( hdr_len ? *hdr_len : 0 ) ) );
1078  if ( ! iobuf ) {
1079  rc = -ENOMEM;
1080  goto err_alloc;
1081  }
1082 
1083  /* Populate I/O buffer */
1084  if ( hdr_len )
1085  memcpy ( iob_put ( iobuf, *hdr_len ), hdr, *hdr_len );
1086  memcpy ( iob_put ( iobuf, *len ), data, *len );
1087 
1088  /* Construct metadata */
1089  memset ( &meta, 0, sizeof ( meta ) );
1090  meta.src = &src.sa;
1091  meta.dest = &dest.sa;
1092  meta.netdev = pxe->netdev;
1093 
1094  /* Deliver I/O buffer */
1095  if ( ( rc = xfer_deliver ( &pxe->udp, iob_disown ( iobuf ),
1096  &meta ) ) != 0 ) {
1097  DBGC ( pxe, "PXE %s could not transmit: %s\n",
1098  pxe->name, strerror ( rc ) );
1099  goto err_deliver;
1100  }
1101 
1102  err_deliver:
1103  free_iob ( iobuf );
1104  err_alloc:
1106  err_open:
1107  return EFIRC ( rc );
1108 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
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:191
#define iob_put(iobuf, len)
Definition: iobuf.h:120
Data transfer metadata.
Definition: xfer.h:22
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:212
A PXE base code.
Definition: efi_pxe.c:69
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static void const void * src
Definition: crypto.h:244
#define DBGC(...)
Definition: compiler.h:505
struct interface udp
UDP interface.
Definition: efi_pxe.c:104
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
#define ntohs(value)
Definition: byteswap.h:136
IP4_t src_ip
IP address of this station.
Definition: pxe_api.h:58
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
struct sockaddr_tcpip st
Definition: syslog.c:56
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
UDP_PORT_t src_port
Source UDP port.
Definition: pxe_api.h:60
struct sockaddr sa
Definition: syslog.c:55
static void * dest
Definition: strings.h:176
int meta(WINDOW *, bool)
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void efi_pxe_udp_schedule_close(struct efi_pxe *pxe)
Schedule close of UDP interface.
Definition: efi_pxe.c:600
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT
Definition: PxeBaseCode.h:112
IP4_t dest_ip
Destination IP address.
Definition: pxe_api.h:59
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT
Definition: PxeBaseCode.h:116
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
static int efi_pxe_udp_open(struct efi_pxe *pxe)
Open UDP interface.
Definition: efi_pxe.c:573
uint8_t data[48]
Additional event data.
Definition: ena.h:22
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:291
#define htons(value)
Definition: byteswap.h:135
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33
uint8_t flags
Flags.
Definition: ena.h:18

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, efi_pxe::name, efi_pxe::netdev, ntohs, random(), rc, sa, src, src_ip, src_port, st, EFI_PXE_BASE_CODE_MODE::StationIp, strerror(), efi_pxe::udp, xfer_alloc_iob(), and xfer_deliver().

◆ efi_pxe_udp_read()

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

1131  {
1132  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1133  struct io_buffer *iobuf;
1134  struct efi_pxe_udp_pseudo_header *pshdr;
1135  EFI_IP_ADDRESS *actual_dest_ip;
1136  EFI_IP_ADDRESS *actual_src_ip;
1137  size_t addr_len;
1138  size_t frag_len;
1139  int rc;
1140 
1141  DBGC2 ( pxe, "PXE %s UDP READ ", pxe->name );
1143  DBGC2 ( pxe, "(filter)" );
1145  DBGC2 ( pxe, "*" );
1146  } else if ( dest_ip ) {
1147  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, dest_ip ) );
1148  }
1149  DBGC2 ( pxe, ":" );
1151  DBGC2 ( pxe, "*" );
1152  } else if ( dest_port ) {
1153  DBGC2 ( pxe, "%d", *dest_port );
1154  } else {
1155  DBGC2 ( pxe, "<NULL>" );
1156  }
1157  DBGC2 ( pxe, "<-" );
1159  DBGC2 ( pxe, "*" );
1160  } else if ( src_ip ) {
1161  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1162  } else {
1163  DBGC2 ( pxe, "<NULL>" );
1164  }
1165  DBGC2 ( pxe, ":" );
1167  DBGC2 ( pxe, "*" );
1168  } else if ( src_port ) {
1169  DBGC2 ( pxe, "%d", *src_port );
1170  } else {
1171  DBGC2 ( pxe, "<NULL>" );
1172  }
1173  if ( hdr_len )
1174  DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1175  DBGC2 ( pxe, " %p+%zx\n", data, ( ( size_t ) *len ) );
1176 
1177  /* Open UDP connection (if applicable) */
1178  if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1179  goto err_open;
1180 
1181  /* Try receiving a packet, if the queue is empty */
1182  if ( list_empty ( &pxe->queue ) )
1183  step();
1184 
1185  /* Remove first packet from the queue */
1186  iobuf = list_first_entry ( &pxe->queue, struct io_buffer, list );
1187  if ( ! iobuf ) {
1188  rc = -ETIMEDOUT; /* "no packet" */
1189  goto err_empty;
1190  }
1191  list_del ( &iobuf->list );
1192 
1193  /* Strip pseudo-header */
1194  pshdr = iobuf->data;
1195  addr_len = ( pshdr->net->net_addr_len );
1196  iob_pull ( iobuf, sizeof ( *pshdr ) );
1197  actual_dest_ip = iobuf->data;
1198  iob_pull ( iobuf, addr_len );
1199  actual_src_ip = iobuf->data;
1200  iob_pull ( iobuf, addr_len );
1201  DBGC2 ( pxe, "PXE %s UDP RX %s:%d", pxe->name,
1202  pshdr->net->ntoa ( actual_dest_ip ), pshdr->dest_port );
1203  DBGC2 ( pxe, "<-%s:%d len %#zx\n", pshdr->net->ntoa ( actual_src_ip ),
1204  pshdr->src_port, iob_len ( iobuf ) );
1205 
1206  /* Filter based on network-layer protocol */
1207  if ( pshdr->net != pxe->net ) {
1208  DBGC2 ( pxe, "PXE %s filtered out %s packet\n",
1209  pxe->name, pshdr->net->name );
1210  rc = -ETIMEDOUT; /* "no packet" */
1211  goto err_filter;
1212  }
1213 
1214  /* Filter based on port numbers */
1216  ( dest_port && ( *dest_port == pshdr->dest_port ) ) ) ) {
1217  DBGC2 ( pxe, "PXE %s filtered out destination port %d\n",
1218  pxe->name, pshdr->dest_port );
1219  rc = -ETIMEDOUT; /* "no packet" */
1220  goto err_filter;
1221  }
1223  ( src_port && ( *src_port == pshdr->src_port ) ) ) ) {
1224  DBGC2 ( pxe, "PXE %s filtered out source port %d\n",
1225  pxe->name, pshdr->src_port );
1226  rc = -ETIMEDOUT; /* "no packet" */
1227  goto err_filter;
1228  }
1229 
1230  /* Filter based on source IP address */
1232  ( src_ip &&
1233  ( memcmp ( src_ip, actual_src_ip, addr_len ) == 0 ) ) ) ) {
1234  DBGC2 ( pxe, "PXE %s filtered out source IP %s\n",
1235  pxe->name, pshdr->net->ntoa ( actual_src_ip ) );
1236  rc = -ETIMEDOUT; /* "no packet" */
1237  goto err_filter;
1238  }
1239 
1240  /* Filter based on destination IP address */
1242  efi_pxe_ip_filter ( pxe, actual_dest_ip ) ) ||
1245  ( dest_ip && ( memcmp ( dest_ip, actual_dest_ip,
1246  addr_len ) == 0 ) ) ) ) ) ) {
1247  DBGC2 ( pxe, "PXE %s filtered out destination IP %s\n",
1248  pxe->name, pshdr->net->ntoa ( actual_dest_ip ) );
1249  rc = -ETIMEDOUT; /* "no packet" */
1250  goto err_filter;
1251  }
1252 
1253  /* Fill in addresses and port numbers */
1254  if ( dest_ip )
1255  memcpy ( dest_ip, actual_dest_ip, addr_len );
1256  if ( dest_port )
1257  *dest_port = pshdr->dest_port;
1258  if ( src_ip )
1259  memcpy ( src_ip, actual_src_ip, addr_len );
1260  if ( src_port )
1261  *src_port = pshdr->src_port;
1262 
1263  /* Fill in header, if applicable */
1264  if ( hdr_len ) {
1265  frag_len = iob_len ( iobuf );
1266  if ( frag_len > *hdr_len )
1267  frag_len = *hdr_len;
1268  memcpy ( hdr, iobuf->data, frag_len );
1269  iob_pull ( iobuf, frag_len );
1270  *hdr_len = frag_len;
1271  }
1272 
1273  /* Fill in data buffer */
1274  frag_len = iob_len ( iobuf );
1275  if ( frag_len > *len )
1276  frag_len = *len;
1277  memcpy ( data, iobuf->data, frag_len );
1278  iob_pull ( iobuf, frag_len );
1279  *len = frag_len;
1280 
1281  /* Check for overflow */
1282  if ( iob_len ( iobuf ) ) {
1283  rc = -ERANGE;
1284  goto err_too_short;
1285  }
1286 
1287  /* Success */
1288  rc = 0;
1289 
1290  err_too_short:
1291  err_filter:
1292  free_iob ( iobuf );
1293  err_empty:
1295  err_open:
1296  return EFIRC ( rc );
1297 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
EFI UDP pseudo-header.
Definition: efi_pxe.c:463
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t dest_port
Destination port.
Definition: efi_pxe.c:467
const char * name
Protocol name.
Definition: netdevice.h:66
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:212
A PXE base code.
Definition: efi_pxe.c:69
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static int efi_pxe_ip_filter(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
Check if IP address matches filter.
Definition: efi_pxe.c:257
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:465
IP4_t src_ip
IP address of this station.
Definition: pxe_api.h:58
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT
Definition: PxeBaseCode.h:114
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER
Definition: PxeBaseCode.h:115
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
16-byte buffer aligned on a 4-byte boundary.
Definition: UefiBaseType.h:105
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition: netdevice.h:94
UDP_PORT_t src_port
Source UDP port.
Definition: pxe_api.h:60
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP
Definition: PxeBaseCode.h:113
#define ERANGE
Result too large.
Definition: errno.h:639
static void efi_pxe_udp_schedule_close(struct efi_pxe *pxe)
Schedule close of UDP interface.
Definition: efi_pxe.c:600
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:91
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT
Definition: PxeBaseCode.h:112
IP4_t dest_ip
Destination IP address.
Definition: pxe_api.h:59
uint16_t src_port
Source port.
Definition: efi_pxe.c:469
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP
Definition: PxeBaseCode.h:111
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:101
void * data
Start of data.
Definition: iobuf.h:48
void step(void)
Single-step a single process.
Definition: process.c:98
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:106
static int efi_pxe_udp_open(struct efi_pxe *pxe)
Open UDP interface.
Definition: efi_pxe.c:573
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
A persistent I/O buffer.
Definition: iobuf.h:33
uint8_t flags
Flags.
Definition: ena.h:18

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(), net_protocol::name, efi_pxe::name, efi_pxe::net, efi_pxe_udp_pseudo_header::net, net_protocol::net_addr_len, net_protocol::ntoa, efi_pxe::queue, rc, src_ip, src_port, efi_pxe_udp_pseudo_header::src_port, and step().

◆ efi_pxe_set_ip_filter()

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

1308  {
1309  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1310  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1311  unsigned int i;
1312 
1313  DBGC ( pxe, "PXE %s SET IP FILTER %02x",
1314  pxe->name, filter->Filters );
1315  for ( i = 0 ; i < filter->IpCnt ; i++ ) {
1316  DBGC ( pxe, " %s",
1317  efi_pxe_ip_ntoa ( pxe, &filter->IpList[i] ) );
1318  }
1319  DBGC ( pxe, "\n" );
1320 
1321  /* Update filter */
1322  memcpy ( &mode->IpFilter, filter, sizeof ( mode->IpFilter ) );
1323 
1324  return 0;
1325 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
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:212
UINT8_t filter
Receive packet filter.
Definition: pxe_api.h:68
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_PXE_BASE_CODE_IP_FILTER IpFilter
Definition: PxeBaseCode.h:299

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

◆ efi_pxe_arp()

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

1337  {
1338  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1339 
1340  DBGC ( pxe, "PXE %s ARP %s %p\n",
1341  pxe->name, efi_pxe_ip_ntoa ( pxe, ip ), mac );
1342 
1343  /* Not used by any bootstrap I can find to test with */
1344  return EFI_UNSUPPORTED;
1345 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
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:212
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58

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

◆ efi_pxe_set_parameters()

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

1361  {
1362  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1363  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1364 
1365  DBGC ( pxe, "PXE %s SET PARAMETERS", pxe->name );
1366  if ( autoarp )
1367  DBGC ( pxe, " %s", ( *autoarp ? "autoarp" : "noautoarp" ) );
1368  if ( sendguid )
1369  DBGC ( pxe, " %s", ( *sendguid ? "sendguid" : "sendmac" ) );
1370  if ( ttl )
1371  DBGC ( pxe, " ttl %d", *ttl );
1372  if ( tos )
1373  DBGC ( pxe, " tos %d", *tos );
1374  if ( callback ) {
1375  DBGC ( pxe, " %s",
1376  ( *callback ? "callback" : "nocallback" ) );
1377  }
1378  DBGC ( pxe, "\n" );
1379 
1380  /* Update parameters */
1381  if ( autoarp )
1382  mode->AutoArp = *autoarp;
1383  if ( sendguid )
1384  mode->SendGUID = *sendguid;
1385  if ( ttl )
1386  mode->TTL = *ttl;
1387  if ( tos )
1388  mode->ToS = *tos;
1389  if ( callback )
1390  mode->MakeCallbacks = *callback;
1391 
1392  return 0;
1393 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35

References EFI_PXE_BASE_CODE_MODE::AutoArp, base, container_of, DBGC, EFI_PXE_BASE_CODE_MODE::MakeCallbacks, efi_pxe::mode, efi_pxe::name, EFI_PXE_BASE_CODE_MODE::SendGUID, EFI_PXE_BASE_CODE_MODE::ToS, and EFI_PXE_BASE_CODE_MODE::TTL.

◆ efi_pxe_set_station_ip()

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

1405  {
1406  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1407  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1408 
1409  DBGC ( pxe, "PXE %s SET STATION IP ", pxe->name );
1410  if ( ip )
1411  DBGC ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, ip ) );
1412  if ( netmask )
1413  DBGC ( pxe, "/%s", efi_pxe_ip_ntoa ( pxe, netmask ) );
1414  DBGC ( pxe, "\n" );
1415 
1416  /* Update IP address and netmask */
1417  if ( ip )
1418  memcpy ( &mode->StationIp, ip, sizeof ( mode->StationIp ) );
1419  if ( netmask )
1420  memcpy ( &mode->SubnetMask, netmask, sizeof (mode->SubnetMask));
1421 
1422  return 0;
1423 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
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:212
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
EFI_IP_ADDRESS SubnetMask
Definition: PxeBaseCode.h:292
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:291

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

◆ efi_pxe_set_packets()

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

1452  {
1453  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1454  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1455 
1456  DBGC ( pxe, "PXE %s SET PACKETS\n", pxe->name );
1457 
1458  /* Update fake packet flags */
1459  if ( dhcpdisc_ok )
1460  mode->DhcpDiscoverValid = *dhcpdisc_ok;
1461  if ( dhcpack_ok )
1462  mode->DhcpAckReceived = *dhcpack_ok;
1463  if ( proxyoffer_ok )
1464  mode->ProxyOfferReceived = *proxyoffer_ok;
1465  if ( pxebsdisc_ok )
1466  mode->PxeDiscoverValid = *pxebsdisc_ok;
1467  if ( pxebsack_ok )
1468  mode->PxeReplyReceived = *pxebsack_ok;
1469  if ( pxebsbis_ok )
1470  mode->PxeBisReplyReceived = *pxebsbis_ok;
1471 
1472  /* Update fake packet contents */
1473  if ( dhcpdisc )
1474  memcpy ( &mode->DhcpDiscover, dhcpdisc, sizeof ( *dhcpdisc ) );
1475  if ( dhcpack )
1476  memcpy ( &mode->DhcpAck, dhcpack, sizeof ( *dhcpack ) );
1477  if ( proxyoffer )
1478  memcpy ( &mode->ProxyOffer, proxyoffer, sizeof ( *proxyoffer ));
1479  if ( pxebsdisc )
1480  memcpy ( &mode->PxeDiscover, pxebsdisc, sizeof ( *pxebsdisc ) );
1481  if ( pxebsack )
1482  memcpy ( &mode->PxeReply, pxebsack, sizeof ( *pxebsack ) );
1483  if ( pxebsbis )
1484  memcpy ( &mode->PxeBisReply, pxebsbis, sizeof ( *pxebsbis ) );
1485 
1486  return 0;
1487 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:271
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A PXE base code.
Definition: efi_pxe.c:69
#define DBGC(...)
Definition: compiler.h:505
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:297
static const void * base
Base address.
Definition: crypto.h:335
const char * name
Name.
Definition: efi_pxe.c:75
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_PXE_BASE_CODE_PACKET PxeBisReply
Definition: PxeBaseCode.h:298
EFI_PXE_BASE_CODE_PACKET DhcpDiscover
Definition: PxeBaseCode.h:293
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:294
EFI_PXE_BASE_CODE_PACKET PxeDiscover
Definition: PxeBaseCode.h:296
EFI_PXE_BASE_CODE_PACKET ProxyOffer
Definition: PxeBaseCode.h:295

References base, container_of, DBGC, EFI_PXE_BASE_CODE_MODE::DhcpAck, EFI_PXE_BASE_CODE_MODE::DhcpAckReceived, EFI_PXE_BASE_CODE_MODE::DhcpDiscover, EFI_PXE_BASE_CODE_MODE::DhcpDiscoverValid, memcpy(), efi_pxe::mode, efi_pxe::name, EFI_PXE_BASE_CODE_MODE::ProxyOffer, EFI_PXE_BASE_CODE_MODE::ProxyOfferReceived, EFI_PXE_BASE_CODE_MODE::PxeBisReply, EFI_PXE_BASE_CODE_MODE::PxeBisReplyReceived, EFI_PXE_BASE_CODE_MODE::PxeDiscover, EFI_PXE_BASE_CODE_MODE::PxeDiscoverValid, EFI_PXE_BASE_CODE_MODE::PxeReply, and EFI_PXE_BASE_CODE_MODE::PxeReplyReceived.

◆ efi_apple_get_response()

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

1523  {
1524 
1525  /* Check length */
1526  if ( *len < sizeof ( *packet ) ) {
1527  *len = sizeof ( *packet );
1528  return EFI_BUFFER_TOO_SMALL;
1529  }
1530 
1531  /* Copy packet */
1532  memcpy ( data, packet, sizeof ( *packet ) );
1533  *len = sizeof ( *packet );
1534 
1535  return EFI_SUCCESS;
1536 }
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t len
Length.
Definition: ena.h:14
#define EFI_SUCCESS
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:114
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by efi_apple_get_bsdp_response(), and efi_apple_get_dhcp_response().

◆ efi_apple_get_dhcp_response()

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

1548  {
1549  struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1550 
1551  return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
1552 }
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A PXE base code.
Definition: efi_pxe.c:69
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:86
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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:1522
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:294
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

◆ efi_apple_get_bsdp_response()

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

1564  {
1565  struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1566 
1567  return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
1568 }
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
A PXE base code.
Definition: efi_pxe.c:69
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:86
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:297
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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:1522
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

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

1590  {
1592  struct tcpip_net_protocol *ipv6 = tcpip_net_protocol ( AF_INET6 );
1593  struct efi_pxe *pxe;
1594  struct in_addr ip;
1595  BOOLEAN use_ipv6;
1596  int leak = 0;
1597  EFI_STATUS efirc;
1598  int rc;
1599 
1600  /* Allocate and initialise structure */
1601  pxe = zalloc ( sizeof ( *pxe ) );
1602  if ( ! pxe ) {
1603  rc = -ENOMEM;
1604  goto err_alloc;
1605  }
1606  ref_init ( &pxe->refcnt, efi_pxe_free );
1607  pxe->netdev = netdev_get ( netdev );
1608  pxe->name = netdev->name;
1609  pxe->handle = handle;
1610  memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
1611  pxe->base.Mode = &pxe->mode;
1613  sizeof ( pxe->apple ) );
1614  pxe->buf.op = &efi_pxe_buf_operations;
1615  intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
1616  intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
1617  INIT_LIST_HEAD ( &pxe->queue );
1619  &pxe->refcnt );
1620 
1621  /* Crude heuristic: assume that we prefer to use IPv4 if we
1622  * have an IPv4 address for the network device, otherwise
1623  * prefer IPv6 (if available).
1624  */
1625  fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting, &ip );
1626  use_ipv6 = ( ip.s_addr ? FALSE : ( ipv6 != NULL ) );
1627 
1628  /* Start base code */
1629  efi_pxe_start ( &pxe->base, use_ipv6 );
1630 
1631  /* Install PXE base code protocol */
1632  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1633  &handle,
1636  NULL ) ) != 0 ) {
1637  rc = -EEFI ( efirc );
1638  DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
1639  pxe->name, strerror ( rc ) );
1640  goto err_install_protocol;
1641  }
1642 
1643  /* Transfer reference to list and return */
1644  list_add_tail ( &pxe->list, &efi_pxes );
1645  DBGC ( pxe, "PXE %s installed for %s\n",
1646  pxe->name, efi_handle_name ( handle ) );
1647  return 0;
1648 
1649  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1650  handle,
1653  NULL ) ) != 0 ) {
1654  DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1655  pxe->name, strerror ( -EEFI ( efirc ) ) );
1656  leak = 1;
1657  }
1658  efi_nullify_pxe ( &pxe->base );
1659  efi_nullify_apple ( &pxe->apple );
1660  err_install_protocol:
1661  if ( ! leak )
1662  ref_put ( &pxe->refcnt );
1663  err_alloc:
1664  if ( leak )
1665  DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1666  return rc;
1667 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:84
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
struct list_head list
List of PXE base codes.
Definition: efi_pxe.c:77
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition: efi_pxe.c:751
struct refcnt refcnt
Reference count.
Definition: efi_pxe.c:71
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
A PXE base code.
Definition: efi_pxe.c:69
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:912
unsigned char BOOLEAN
static struct interface_descriptor efi_pxe_tftp_desc
PXE file data transfer interface descriptor.
Definition: efi_pxe.c:415
EFI_PXE_BASE_CODE_PROTOCOL base
PXE base code protocol.
Definition: efi_pxe.c:82
#define DBGC(...)
Definition: compiler.h:505
struct interface udp
UDP interface.
Definition: efi_pxe.c:104
struct xfer_buffer buf
Data transfer buffer.
Definition: efi_pxe.c:94
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1996
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:86
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition: efi_guid.c:291
static struct process_descriptor efi_pxe_process_desc
UDP close process descriptor.
Definition: efi_pxe.c:624
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
const char * name
Name.
Definition: efi_pxe.c:75
EFI_HANDLE handle
Installed handle.
Definition: efi_pxe.c:80
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:73
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct tcpip_net_protocol * tcpip_net_protocol(sa_family_t sa_family)
Find TCP/IP network-layer protocol.
Definition: tcpip.c:68
void efi_nullify_pxe(EFI_PXE_BASE_CODE_PROTOCOL *pxe)
Nullify PXE base code protocol.
Definition: efi_null.c:536
static struct net_device * netdev
Definition: gdbudp.c:52
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
struct xfer_buffer_operations * op
Data transfer buffer operations.
Definition: xferbuf.h:27
static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol
Apple NetBoot protocol.
Definition: efi_pxe.c:1571
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static struct xfer_buffer_operations efi_pxe_buf_operations
PXE data transfer buffer operations.
Definition: efi_pxe.c:343
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1917
IP address structure.
Definition: in.h:39
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
static struct interface_descriptor efi_pxe_udp_desc
PXE UDP interface descriptor.
Definition: efi_pxe.c:564
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
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:145
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:97
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
EFI_GUID efi_apple_net_boot_protocol_guid
Apple NetBoot protocol GUID.
Definition: efi_guid.c:107
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
struct process process
UDP interface closer process.
Definition: efi_pxe.c:108
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:106
#define FALSE
Definition: tlan.h:45
A network-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:140
EFI_SYSTEM_TABLE * efi_systab
void efi_nullify_apple(EFI_APPLE_NET_BOOT_PROTOCOL *apple)
Nullify Apple Net Boot protocol.
Definition: efi_null.c:571
EFI_PXE_BASE_CODE_MODE * Mode
The pointer to the EFI_PXE_BASE_CODE_MODE data for this device.
Definition: PxeBaseCode.h:930
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
static void efi_pxe_free(struct refcnt *refcnt)
Free PXE base code.
Definition: efi_pxe.c:116
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol
PXE base code protocol.
Definition: efi_pxe.c:1490
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References AF_INET6, efi_pxe::apple, efi_pxe::base, EFI_SYSTEM_TABLE::BootServices, efi_pxe::buf, DBGC, EEFI, efi_apple_net_boot_protocol, efi_apple_net_boot_protocol_guid, efi_handle_name(), efi_nullify_apple(), efi_nullify_pxe(), efi_pxe_base_code_protocol, efi_pxe_base_code_protocol_guid, efi_pxe_buf_operations, 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(), handle, efi_pxe::handle, INIT_LIST_HEAD, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, intf_init(), ip, efi_pxe::list, list_add_tail, memcpy(), efi_pxe::mode, _EFI_PXE_BASE_CODE_PROTOCOL::Mode, efi_pxe::name, net_device::name, netdev, efi_pxe::netdev, netdev_get(), netdev_settings(), NULL, xfer_buffer::op, 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 1674 of file efi_pxe.c.

1674  {
1676  struct efi_pxe *pxe;
1677  int leak = efi_shutdown_in_progress;
1678  EFI_STATUS efirc;
1679 
1680  /* Locate PXE base code */
1681  pxe = efi_pxe_find ( handle );
1682  if ( ! handle ) {
1683  DBG ( "PXE could not find base code for %s\n",
1684  efi_handle_name ( handle ) );
1685  return;
1686  }
1687 
1688  /* Stop base code */
1689  efi_pxe_stop ( &pxe->base );
1690 
1691  /* Uninstall PXE base code protocol */
1692  if ( ( ! efi_shutdown_in_progress ) &&
1693  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1694  handle,
1697  NULL ) ) != 0 ) ) {
1698  DBGC ( pxe, "PXE %s could not uninstall: %s\n",
1699  pxe->name, strerror ( -EEFI ( efirc ) ) );
1700  leak = 1;
1701  }
1702  efi_nullify_pxe ( &pxe->base );
1703  efi_nullify_apple ( &pxe->apple );
1704 
1705  /* Remove from list and drop list's reference */
1706  list_del ( &pxe->list );
1707  if ( ! leak )
1708  ref_put ( &pxe->refcnt );
1709 
1710  /* Report leakage, if applicable */
1711  if ( leak && ( ! efi_shutdown_in_progress ) )
1712  DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
1713 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
static struct efi_pxe * efi_pxe_find(EFI_HANDLE handle)
Locate PXE base code.
Definition: efi_pxe.c:132
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
struct list_head list
List of PXE base codes.
Definition: efi_pxe.c:77
struct refcnt refcnt
Reference count.
Definition: efi_pxe.c:71
A PXE base code.
Definition: efi_pxe.c:69
EFI_PXE_BASE_CODE_PROTOCOL base
PXE base code protocol.
Definition: efi_pxe.c:82
#define DBGC(...)
Definition: compiler.h:505
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:86
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition: efi_guid.c:291
const char * name
Name.
Definition: efi_pxe.c:75
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void efi_nullify_pxe(EFI_PXE_BASE_CODE_PROTOCOL *pxe)
Nullify PXE base code protocol.
Definition: efi_null.c:536
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
EFI_GUID efi_apple_net_boot_protocol_guid
Apple NetBoot protocol GUID.
Definition: efi_guid.c:107
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
EFI_SYSTEM_TABLE * efi_systab
void efi_nullify_apple(EFI_APPLE_NET_BOOT_PROTOCOL *apple)
Nullify Apple Net Boot protocol.
Definition: efi_null.c:571
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static EFI_STATUS EFIAPI efi_pxe_stop(EFI_PXE_BASE_CODE_PROTOCOL *base)
Stop PXE base code.
Definition: efi_pxe.c:806
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58

References efi_pxe::apple, efi_pxe::base, EFI_SYSTEM_TABLE::BootServices, DBG, DBGC, EEFI, efi_apple_net_boot_protocol_guid, 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_buf_operations

struct xfer_buffer_operations efi_pxe_buf_operations
static
Initial value:
= {
.realloc = efi_pxe_buf_realloc,
}
static void efi_pxe_buf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write data to PXE data transfer buffer.
Definition: efi_pxe.c:335
static int efi_pxe_buf_realloc(struct xfer_buffer *xferbuf __unused, size_t len __unused)
Reallocate PXE data transfer buffer.
Definition: efi_pxe.c:320

PXE data transfer buffer operations.

Definition at line 343 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ 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:376
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
A PXE base code.
Definition: efi_pxe.c:69
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
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:390
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition: efi_pxe.c:361

PXE file data transfer interface operations.

Definition at line 408 of file efi_pxe.c.

◆ efi_pxe_tftp_desc

struct interface_descriptor efi_pxe_tftp_desc
static
Initial value:
=
A PXE base code.
Definition: efi_pxe.c:69
static struct interface_operation efi_pxe_tftp_operations[]
PXE file data transfer interface operations.
Definition: efi_pxe.c:408
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:97
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

PXE file data transfer interface descriptor.

Definition at line 415 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ efi_pxe_udp_operations

struct interface_operation efi_pxe_udp_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
A PXE base code.
Definition: efi_pxe.c:69
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
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:507
static void efi_pxe_udp_close(struct efi_pxe *pxe, int rc)
Close UDP interface.
Definition: efi_pxe.c:478

PXE UDP interface operations.

Definition at line 558 of file efi_pxe.c.

◆ efi_pxe_udp_desc

struct interface_descriptor efi_pxe_udp_desc
static
Initial value:
=
A PXE base code.
Definition: efi_pxe.c:69
struct interface udp
UDP interface.
Definition: efi_pxe.c:104
static struct interface_operation efi_pxe_udp_operations[]
PXE UDP interface operations.
Definition: efi_pxe.c:558
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

PXE UDP interface descriptor.

Definition at line 564 of file efi_pxe.c.

Referenced by efi_pxe_install().

◆ efi_pxe_process_desc

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

UDP close process descriptor.

Definition at line 624 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,
}
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:1335
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:1444
static EFI_STATUS EFIAPI efi_pxe_dhcp(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
Perform DHCP.
Definition: efi_pxe.c:831
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition: efi_pxe.c:751
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:1307
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:1359
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:1126
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:1404
#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION
Definition: PxeBaseCode.h:893
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:885
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:1012
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:929
static EFI_STATUS EFIAPI efi_pxe_stop(EFI_PXE_BASE_CODE_PROTOCOL *base)
Stop PXE base code.
Definition: efi_pxe.c:806

PXE base code protocol.

Definition at line 1490 of file efi_pxe.c.

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:1563
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:1547

Apple NetBoot protocol.

Definition at line 1571 of file efi_pxe.c.

Referenced by efi_pxe_install().