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

115  {
116  struct efi_pxe *pxe = container_of ( refcnt, struct efi_pxe, refcnt );
117 
118  netdev_put ( pxe->netdev );
119  free ( pxe );
120 }
A PXE base code.
Definition: efi_pxe.c:68
A reference counter.
Definition: refcnt.h:26
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:72
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
#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 131 of file efi_pxe.c.

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

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

191  {
192  union {
193  struct sockaddr sa;
194  struct sockaddr_efi se;
195  } *sockaddr = container_of ( sa, typeof ( *sockaddr ), sa );
196 
197  /* Initialise socket address */
198  memset ( sockaddr, 0, sizeof ( *sockaddr ) );
199  sockaddr->sa.sa_family = pxe->tcpip->sa_family;
200  memcpy ( &sockaddr->se.se_addr, ip, pxe->net->net_addr_len );
201  sockaddr->se.se_scope_id = pxe->netdev->index;
202 }
An EFI socket address.
Definition: efi_pxe.c:154
sa_family_t sa_family
Socket address family.
Definition: socket.h:101
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:72
#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:90
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:88
unsigned int index
Index of this network device.
Definition: netdevice.h:356
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:101
void * memset(void *dest, int character, size_t len) __nonnull

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

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

212  {
213 
214  return pxe->net->ntoa ( ip );
215 }
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:90
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 223 of file efi_pxe.c.

223  {
224  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
225  struct in_addr address;
226  struct in_addr netmask;
227 
228  /* It's unclear which of the potentially many IPv6 addresses
229  * is supposed to be used.
230  */
231  if ( mode->UsingIpv6 )
232  return -ENOTSUP;
233 
234  /* Fetch IP address and subnet mask */
235  fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &ip_setting,
236  &address );
237  fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &netmask_setting,
238  &netmask );
239 
240  /* Populate IP address and subnet mask */
241  memset ( &mode->StationIp, 0, sizeof ( mode->StationIp ) );
242  memcpy ( &mode->StationIp, &address, sizeof ( address ) );
243  memset ( &mode->SubnetMask, 0, sizeof ( mode->SubnetMask ) );
244  memcpy ( &mode->SubnetMask, &netmask, sizeof ( netmask ) );
245 
246  return 0;
247 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:916
uint64_t address
Base address.
Definition: ena.h:24
EFI_IP_ADDRESS SubnetMask
Definition: PxeBaseCode.h:293
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
#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:72
IP address structure.
Definition: in.h:39
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:292
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 256 of file efi_pxe.c.

256  {
257  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
259  uint8_t filters = filter->Filters;
260  union {
262  struct in_addr in;
263  struct in6_addr in6;
264  } *u = container_of ( ip, typeof ( *u ), ip );
265  size_t addr_len = pxe->net->net_addr_len;
266  unsigned int i;
267 
268  /* Match everything, if applicable */
270  return 1;
271 
272  /* Match all multicasts, if applicable */
274  if ( mode->UsingIpv6 ) {
275  if ( IN6_IS_ADDR_MULTICAST ( &u->in6 ) )
276  return 1;
277  } else {
278  if ( IN_IS_MULTICAST ( u->in.s_addr ) )
279  return 1;
280  }
281  }
282 
283  /* Match IPv4 broadcasts, if applicable */
284  if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST ) {
285  if ( ( ! mode->UsingIpv6 ) &&
286  ( u->in.s_addr == INADDR_BROADCAST ) )
287  return 1;
288  }
289 
290  /* Match station address, if applicable */
291  if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP ) {
292  if ( memcmp ( ip, &mode->StationIp, addr_len ) == 0 )
293  return 1;
294  }
295 
296  /* Match explicit addresses, if applicable */
297  for ( i = 0 ; i < filter->IpCnt ; i++ ) {
298  if ( memcmp ( ip, &filter->IpList[i], addr_len ) == 0 )
299  return 1;
300  }
301 
302  return 0;
303 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition: PxeBaseCode.h:87
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
__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:89
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition: PxeBaseCode.h:88
#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:110
#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:90
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:79
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition: PxeBaseCode.h:86
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:300
#define IN_IS_MULTICAST(addr)
Definition: in.h:33
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:292
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113

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

320  {
321 
322  /* Can never reallocate: return EFI_BUFFER_TOO_SMALL */
323  return -ERANGE;
324 }
#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 334 of file efi_pxe.c.

335  {
336 
337  /* Copy data to buffer */
338  memcpy ( ( xferbuf->data + offset ), data, len );
339 }
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
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, xfer_buffer::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 360 of file efi_pxe.c.

360  {
361 
362  /* Restart interface */
363  intf_restart ( &pxe->tftp, rc );
364 
365  /* Record overall status */
366  pxe->rc = rc;
367 }
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:337
int rc
Overall return status.
Definition: efi_pxe.c:100
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:96

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

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

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

391  {
392  int rc;
393 
394  /* Deliver to data transfer buffer */
395  if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
396  meta ) ) != 0 )
397  goto err_deliver;
398 
399  return 0;
400 
401  err_deliver:
402  efi_pxe_tftp_close ( pxe, rc );
403  return rc;
404 }
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:93
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
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:360

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

426  {
427  struct sockaddr server;
428  struct uri *uri;
429  int rc;
430 
431  /* Parse server address and filename */
432  efi_pxe_ip_sockaddr ( pxe, ip, &server );
433  uri = pxe_uri ( &server, filename );
434  if ( ! uri ) {
435  DBGC ( pxe, "PXE %s could not parse %s:%s\n", pxe->name,
436  efi_pxe_ip_ntoa ( pxe, ip ), filename );
437  rc = -ENOTSUP;
438  goto err_parse;
439  }
440 
441  /* Open URI */
442  if ( ( rc = xfer_open_uri ( &pxe->tftp, uri ) ) != 0 ) {
443  DBGC ( pxe, "PXE %s could not open: %s\n",
444  pxe->name, strerror ( rc ) );
445  goto err_open;
446  }
447 
448  err_open:
449  uri_put ( uri );
450  err_parse:
451  return rc;
452 }
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:190
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
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:211
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition: uri.c:774
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:66
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: efi_pxe.c:74
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:96
A Uniform Resource Identifier.
Definition: uri.h:50

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

477  {
478  struct io_buffer *iobuf;
479  struct io_buffer *tmp;
480 
481  /* Release our claim on SNP devices, if applicable */
482  if ( process_running ( &pxe->process ) )
483  efi_snp_release();
484 
485  /* Stop process */
486  process_del ( &pxe->process );
487 
488  /* Restart UDP interface */
489  intf_restart ( &pxe->udp, rc );
490 
491  /* Flush any received UDP packets */
492  list_for_each_entry_safe ( iobuf, tmp, &pxe->queue, list ) {
493  list_del ( &iobuf->list );
494  free_iob ( iobuf );
495  }
496 }
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:337
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
struct interface udp
UDP interface.
Definition: efi_pxe.c:103
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
#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:447
uint8_t * tmp
Definition: entropy.h:156
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
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:39
struct process process
UDP interface closer process.
Definition: efi_pxe.c:107
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:105
A persistent I/O buffer.
Definition: iobuf.h:32

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

507  {
508  struct sockaddr_efi *se_src;
509  struct sockaddr_efi *se_dest;
510  struct tcpip_net_protocol *tcpip;
511  struct net_protocol *net;
512  struct efi_pxe_udp_pseudo_header *pshdr;
513  size_t addr_len;
514  size_t pshdr_len;
515  int rc;
516 
517  /* Sanity checks */
518  assert ( meta != NULL );
519  se_src = ( ( struct sockaddr_efi * ) meta->src );
520  assert ( se_src != NULL );
521  se_dest = ( ( struct sockaddr_efi * ) meta->dest );
522  assert ( se_dest != NULL );
523  assert ( se_src->se_family == se_dest->se_family );
524 
525  /* Determine protocol */
526  tcpip = tcpip_net_protocol ( se_src->se_family );
527  if ( ! tcpip ) {
528  rc = -ENOTSUP;
529  goto err_unsupported;
530  }
531  net = tcpip->net_protocol;
532  addr_len = net->net_addr_len;
533 
534  /* Construct pseudo-header */
535  pshdr_len = ( sizeof ( *pshdr ) + ( 2 * addr_len ) );
536  if ( ( rc = iob_ensure_headroom ( iobuf, pshdr_len ) ) != 0 )
537  goto err_headroom;
538  memcpy ( iob_push ( iobuf, addr_len ), &se_src->se_addr, addr_len );
539  memcpy ( iob_push ( iobuf, addr_len ), &se_dest->se_addr, addr_len );
540  pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
541  pshdr->net = net;
542  pshdr->dest_port = ntohs ( se_dest->se_port );
543  pshdr->src_port = ntohs ( se_src->se_port );
544 
545  /* Add to queue */
546  list_add_tail ( &iobuf->list, &pxe->queue );
547 
548  return 0;
549 
550  err_unsupported:
551  err_headroom:
552  free_iob ( iobuf );
553  return rc;
554 }
EFI UDP pseudo-header.
Definition: efi_pxe.c:462
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t dest_port
Destination port.
Definition: efi_pxe.c:466
An EFI socket address.
Definition: efi_pxe.c:154
#define iob_push(iobuf, len)
Definition: iobuf.h:80
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
EFI_IP_ADDRESS se_addr
IP address.
Definition: efi_pxe.c:168
#define ntohs(value)
Definition: byteswap.h:136
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:464
#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:160
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:468
A network-layer protocol.
Definition: netdevice.h:64
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
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:105
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:183
sa_family_t se_family
Socket address family (part of struct sockaddr)
Definition: efi_pxe.c:156
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

572  {
573  int rc;
574 
575  /* If interface is already open, then cancel the scheduled close */
576  if ( process_running ( &pxe->process ) ) {
577  process_del ( &pxe->process );
578  return 0;
579  }
580 
581  /* Open promiscuous UDP interface */
582  if ( ( rc = udp_open_promisc ( &pxe->udp ) ) != 0 ) {
583  DBGC ( pxe, "PXE %s could not open UDP connection: %s\n",
584  pxe->name, strerror ( rc ) );
585  return rc;
586  }
587 
588  /* Claim network devices */
589  efi_snp_claim();
590 
591  return 0;
592 }
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:103
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
const char * name
Name.
Definition: efi_pxe.c:74
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:107

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

599  {
600 
601  /* The EFI PXE base code protocol does not provide any
602  * explicit UDP open/close methods. To avoid the overhead of
603  * reopening a socket for each read/write operation, we start
604  * a process which will close the socket immediately if the
605  * next call into iPXE is anything other than a UDP
606  * read/write.
607  */
608  process_add ( &pxe->process );
609 }
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:107

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

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

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

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

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

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

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

721  {
722  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
723 
724  /* Construct fake packets */
725  mode->DhcpDiscoverValid =
727  &mode->DhcpDiscover );
728  mode->DhcpAckReceived =
730  &mode->DhcpAck );
731  mode->PxeReplyReceived =
733  &mode->PxeReply );
734 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
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:298
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:294
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:295
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:669
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 750 of file efi_pxe.c.

751  {
752  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
755  sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
756  int rc;
757 
758  DBGC ( pxe, "PXE %s START %s\n", pxe->name, ( ipv6 ? "IPv6" : "IPv4" ));
759 
760  /* Initialise mode structure */
761  memset ( mode, 0, sizeof ( *mode ) );
762  mode->AutoArp = TRUE;
763  mode->TTL = DEFAULT_TTL;
764  mode->ToS = DEFAULT_ToS;
765  mode->IpFilter.Filters =
770 
771  /* Check for IPv4/IPv6 support */
772  mode->Ipv6Supported = ( ipv6 != NULL );
773  mode->Ipv6Available = ( ipv6 != NULL );
774  pxe->tcpip = tcpip_net_protocol ( family );
775  if ( ! pxe->tcpip ) {
776  DBGC ( pxe, "PXE %s has no support for %s\n",
777  pxe->name, socket_family_name ( family ) );
778  return EFI_UNSUPPORTED;
779  }
780  pxe->net = pxe->tcpip->net_protocol;
781  mode->UsingIpv6 = use_ipv6;
782 
783  /* Populate station IP address */
784  if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
785  return rc;
786 
787  /* Construct fake DHCP packets */
788  efi_pxe_fake_all ( pxe );
789 
790  /* Record that base code is started */
791  mode->Started = TRUE;
792  DBGC ( pxe, "PXE %s using %s\n",
793  pxe->name, pxe->net->ntoa ( &mode->StationIp ) );
794 
795  return 0;
796 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
Definition: PxeBaseCode.h:87
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
A PXE base code.
Definition: efi_pxe.c:68
#define DBGC(...)
Definition: compiler.h:505
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST
Definition: PxeBaseCode.h:89
const char * name
Name.
Definition: efi_pxe.c:74
static int efi_pxe_ip(struct efi_pxe *pxe)
Populate local IP address.
Definition: efi_pxe.c:223
#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS
Definition: PxeBaseCode.h:88
#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:90
#define DEFAULT_TTL
Default IP TTL and ToS.
Definition: PxeBaseCode.h:41
#define DEFAULT_ToS
Definition: PxeBaseCode.h:42
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:721
#define TRUE
Definition: tlan.h:46
uint16_t base
Base address.
Definition: edd.h:14
struct tcpip_net_protocol * tcpip
TCP/IP network-layer protocol.
Definition: efi_pxe.c:88
#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP
Definition: PxeBaseCode.h:86
EFI_PXE_BASE_CODE_IP_FILTER IpFilter
Definition: PxeBaseCode.h:300
A network-layer protocol of the TCP/IP stack (eg.
Definition: tcpip.h:140
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:292
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#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 804 of file efi_pxe.c.

804  {
805  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
807 
808  DBGC ( pxe, "PXE %s STOP\n", pxe->name );
809 
810  /* Record that base code is stopped */
811  mode->Started = FALSE;
812 
813  /* Close TFTP */
814  efi_pxe_tftp_close ( pxe, 0 );
815 
816  /* Close UDP */
817  efi_pxe_udp_close ( pxe, 0 );
818 
819  return 0;
820 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
A PXE base code.
Definition: efi_pxe.c:68
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: efi_pxe.c:74
#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:360
uint16_t base
Base address.
Definition: edd.h:14
#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:477

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

830  {
831  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
832  struct net_device *netdev = pxe->netdev;
833  int rc;
834 
835  DBGC ( pxe, "PXE %s DHCP %s\n",
836  pxe->name, ( sort ? "sorted" : "unsorted" ) );
837 
838  /* Claim network devices */
839  efi_snp_claim();
840 
841  /* Initiate configuration */
842  if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
843  DBGC ( pxe, "PXE %s could not initiate configuration: %s\n",
844  pxe->name, strerror ( rc ) );
845  goto err_configure;
846  }
847 
848  /* Wait for configuration to complete (or time out) */
850  step();
851 
852  /* Report timeout if configuration failed */
853  if ( ! netdev_configuration_ok ( netdev ) ) {
854  rc = -ETIMEDOUT;
855  goto err_timeout;
856  }
857 
858  /* Update station IP address */
859  if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
860  goto err_ip;
861 
862  /* Update faked DHCP packets */
863  efi_pxe_fake_all ( pxe );
864 
865  err_ip:
866  err_timeout:
867  err_configure:
868  efi_snp_release();
869  return EFIRC ( rc );
870 }
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:1303
A PXE base code.
Definition: efi_pxe.c:68
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
const char * name
Name.
Definition: efi_pxe.c:74
int netdev_configure_all(struct net_device *netdev)
Start network device configuration via all supported configurators.
Definition: netdevice.c:1259
static int efi_pxe_ip(struct efi_pxe *pxe)
Populate local IP address.
Definition: efi_pxe.c:223
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:72
#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:348
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
static void efi_pxe_fake_all(struct efi_pxe *pxe)
Construct fake DHCP packets.
Definition: efi_pxe.c:721
uint16_t base
Base address.
Definition: edd.h:14
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:1315
#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:151

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

884  {
885  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
887  unsigned int i;
888 
889  DBGC ( pxe, "PXE %s DISCOVER type %d layer %d%s\n",
890  pxe->name, type, *layer, ( bis ? " bis" : "" ) );
891  if ( info ) {
892  DBGC ( pxe, "%s%s%s%s %s",
893  ( info->UseMCast ? " mcast" : "" ),
894  ( info->UseBCast ? " bcast" : "" ),
895  ( info->UseUCast ? " ucast" : "" ),
896  ( info->MustUseList ? " list" : "" ),
897  efi_pxe_ip_ntoa ( pxe, &info->ServerMCastIp ) );
898  for ( i = 0 ; i < info->IpCnt ; i++ ) {
899  ip = &info->SrvList[i].IpAddr;
900  DBGC ( pxe, " %d%s:%s", info->SrvList[i].Type,
901  ( info->SrvList[i].AcceptAnyResponse ?
902  ":any" : "" ), efi_pxe_ip_ntoa ( pxe, ip ) );
903  }
904  }
905  DBGC ( pxe, "\n" );
906 
907  /* Not used by any bootstrap I can find to test with */
908  return EFI_UNSUPPORTED;
909 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
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:211
A PXE base code.
Definition: efi_pxe.c:68
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: efi_pxe.c:74
#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:110
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
uint16_t base
Base address.
Definition: edd.h:14

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

931  {
932  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
933  int rc;
934 
935  DBGC ( pxe, "PXE %s MTFTP %d%s %p+%llx", pxe->name, opcode,
936  ( overwrite ? " overwrite" : "" ), data, *len );
937  if ( blksize )
938  DBGC ( pxe, " blksize %zd", ( ( size_t ) *blksize ) );
939  DBGC ( pxe, " %s:%s", efi_pxe_ip_ntoa ( pxe, ip ), filename );
940  if ( info ) {
941  DBGC ( pxe, " %s:%d:%d:%d:%d",
942  efi_pxe_ip_ntoa ( pxe, &info->MCastIp ),
943  info->CPort, info->SPort, info->ListenTimeout,
944  info->TransmitTimeout );
945  }
946  DBGC ( pxe, "%s\n", ( callback ? " callback" : "" ) );
947 
948  /* Fail unless operation is supported */
949  if ( ! ( ( opcode == EFI_PXE_BASE_CODE_TFTP_READ_FILE ) ||
951  DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
952  pxe->name, opcode );
953  rc = -ENOTSUP;
954  goto err_opcode;
955  }
956 
957  /* Claim network devices */
958  efi_snp_claim();
959 
960  /* Determine block size. Ignore the requested block size
961  * unless we are using callbacks, since limiting HTTP to a
962  * 512-byte TCP window is not sensible.
963  */
964  pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
965 
966  /* Initialise data transfer buffer */
967  pxe->buf.data = data;
968  pxe->buf.len = *len;
969 
970  /* Open download */
971  if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
972  ( ( const char * ) filename ) ) ) != 0 )
973  goto err_open;
974 
975  /* Wait for download to complete */
976  pxe->rc = -EINPROGRESS;
977  while ( pxe->rc == -EINPROGRESS )
978  step();
979  if ( ( rc = pxe->rc ) != 0 ) {
980  DBGC ( pxe, "PXE %s download failed: %s\n",
981  pxe->name, strerror ( rc ) );
982  goto err_download;
983  }
984 
985  err_download:
986  efi_pxe_tftp_close ( pxe, rc );
987  err_open:
988  efi_snp_release();
989  err_opcode:
990  return EFIRC ( rc );
991 }
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:211
uint8_t opcode
Opcode.
Definition: ena.h:16
A PXE base code.
Definition: efi_pxe.c:68
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:425
#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:93
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: efi_pxe.c:74
size_t len
Size of data.
Definition: xferbuf.h:23
size_t blksize
Block size (for TFTP)
Definition: efi_pxe.c:98
int rc
Overall return status.
Definition: efi_pxe.c:100
#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:96
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:360
uint16_t base
Base address.
Definition: edd.h:14
uint32_t len
Length.
Definition: ena.h:14
void step(void)
Single-step a single process.
Definition: process.c:98
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int overwrite(const WINDOW *, WINDOW *)
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:151

References base, blksize, efi_pxe::blksize, efi_pxe::buf, container_of, data, xfer_buffer::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 1010 of file efi_pxe.c.

1015  {
1016  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1017  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1018  struct io_buffer *iobuf;
1019  struct xfer_metadata meta;
1020  union {
1021  struct sockaddr_tcpip st;
1022  struct sockaddr sa;
1023  } dest;
1024  union {
1025  struct sockaddr_tcpip st;
1026  struct sockaddr sa;
1027  } src;
1028  int rc;
1029 
1030  DBGC2 ( pxe, "PXE %s UDP WRITE ", pxe->name );
1031  if ( src_ip )
1032  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1033  DBGC2 ( pxe, ":" );
1034  if ( src_port &&
1036  DBGC2 ( pxe, "%d", *src_port );
1037  } else {
1038  DBGC2 ( pxe, "*" );
1039  }
1040  DBGC2 ( pxe, "->%s:%d", efi_pxe_ip_ntoa ( pxe, dest_ip ), *dest_port );
1041  if ( gateway )
1042  DBGC2 ( pxe, " via %s", efi_pxe_ip_ntoa ( pxe, gateway ) );
1043  if ( hdr_len )
1044  DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1045  DBGC2 ( pxe, " %p+%zx", data, ( ( size_t ) *len ) );
1047  DBGC2 ( pxe, " frag" );
1048  DBGC2 ( pxe, "\n" );
1049 
1050  /* Open UDP connection (if applicable) */
1051  if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1052  goto err_open;
1053 
1054  /* Construct destination address */
1055  efi_pxe_ip_sockaddr ( pxe, dest_ip, &dest.sa );
1056  dest.st.st_port = htons ( *dest_port );
1057 
1058  /* Construct source address */
1059  efi_pxe_ip_sockaddr ( pxe, ( src_ip ? src_ip : &mode->StationIp ),
1060  &src.sa );
1061  if ( src_port &&
1063  src.st.st_port = htons ( *src_port );
1064  } else {
1065  /* The API does not allow for a sensible concept of
1066  * binding to a local port, so just use a random value.
1067  */
1068  src.st.st_port = ( random() | htons ( 1024 ) );
1069  if ( src_port )
1070  *src_port = ntohs ( src.st.st_port );
1071  }
1072 
1073  /* Allocate I/O buffer */
1074  iobuf = xfer_alloc_iob ( &pxe->udp,
1075  ( *len + ( hdr_len ? *hdr_len : 0 ) ) );
1076  if ( ! iobuf ) {
1077  rc = -ENOMEM;
1078  goto err_alloc;
1079  }
1080 
1081  /* Populate I/O buffer */
1082  if ( hdr_len )
1083  memcpy ( iob_put ( iobuf, *hdr_len ), hdr, *hdr_len );
1084  memcpy ( iob_put ( iobuf, *len ), data, *len );
1085 
1086  /* Construct metadata */
1087  memset ( &meta, 0, sizeof ( meta ) );
1088  meta.src = &src.sa;
1089  meta.dest = &dest.sa;
1090  meta.netdev = pxe->netdev;
1091 
1092  /* Deliver I/O buffer */
1093  if ( ( rc = xfer_deliver ( &pxe->udp, iob_disown ( iobuf ),
1094  &meta ) ) != 0 ) {
1095  DBGC ( pxe, "PXE %s could not transmit: %s\n",
1096  pxe->name, strerror ( rc ) );
1097  goto err_deliver;
1098  }
1099 
1100  err_deliver:
1101  free_iob ( iobuf );
1102  err_alloc:
1104  err_open:
1105  return EFIRC ( rc );
1106 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
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:83
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:190
#define iob_put(iobuf, len)
Definition: iobuf.h:116
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:211
A PXE base code.
Definition: efi_pxe.c:68
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
struct interface udp
UDP interface.
Definition: efi_pxe.c:103
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
#define ntohs(value)
Definition: byteswap.h:136
IP4_t src_ip
IP address of this station.
Definition: pxe_api.h:58
const char * name
Name.
Definition: efi_pxe.c:74
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:208
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct net_device * netdev
Underlying network device.
Definition: efi_pxe.c:72
#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
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
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:599
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT
Definition: PxeBaseCode.h:114
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:30
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT
Definition: PxeBaseCode.h:118
uint16_t base
Base address.
Definition: edd.h:14
uint32_t hdr
Message header.
Definition: intelvf.h:12
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:572
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:292
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define htons(value)
Definition: byteswap.h:135
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:151
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:32
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 1124 of file efi_pxe.c.

1129  {
1130  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1131  struct io_buffer *iobuf;
1132  struct efi_pxe_udp_pseudo_header *pshdr;
1133  EFI_IP_ADDRESS *actual_dest_ip;
1134  EFI_IP_ADDRESS *actual_src_ip;
1135  size_t addr_len;
1136  size_t frag_len;
1137  int rc;
1138 
1139  DBGC2 ( pxe, "PXE %s UDP READ ", pxe->name );
1141  DBGC2 ( pxe, "(filter)" );
1143  DBGC2 ( pxe, "*" );
1144  } else if ( dest_ip ) {
1145  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, dest_ip ) );
1146  }
1147  DBGC2 ( pxe, ":" );
1149  DBGC2 ( pxe, "*" );
1150  } else if ( dest_port ) {
1151  DBGC2 ( pxe, "%d", *dest_port );
1152  } else {
1153  DBGC2 ( pxe, "<NULL>" );
1154  }
1155  DBGC2 ( pxe, "<-" );
1157  DBGC2 ( pxe, "*" );
1158  } else if ( src_ip ) {
1159  DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
1160  } else {
1161  DBGC2 ( pxe, "<NULL>" );
1162  }
1163  DBGC2 ( pxe, ":" );
1165  DBGC2 ( pxe, "*" );
1166  } else if ( src_port ) {
1167  DBGC2 ( pxe, "%d", *src_port );
1168  } else {
1169  DBGC2 ( pxe, "<NULL>" );
1170  }
1171  if ( hdr_len )
1172  DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
1173  DBGC2 ( pxe, " %p+%zx\n", data, ( ( size_t ) *len ) );
1174 
1175  /* Open UDP connection (if applicable) */
1176  if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
1177  goto err_open;
1178 
1179  /* Try receiving a packet, if the queue is empty */
1180  if ( list_empty ( &pxe->queue ) )
1181  step();
1182 
1183  /* Remove first packet from the queue */
1184  iobuf = list_first_entry ( &pxe->queue, struct io_buffer, list );
1185  if ( ! iobuf ) {
1186  rc = -ETIMEDOUT; /* "no packet" */
1187  goto err_empty;
1188  }
1189  list_del ( &iobuf->list );
1190 
1191  /* Strip pseudo-header */
1192  pshdr = iobuf->data;
1193  addr_len = ( pshdr->net->net_addr_len );
1194  iob_pull ( iobuf, sizeof ( *pshdr ) );
1195  actual_dest_ip = iobuf->data;
1196  iob_pull ( iobuf, addr_len );
1197  actual_src_ip = iobuf->data;
1198  iob_pull ( iobuf, addr_len );
1199  DBGC2 ( pxe, "PXE %s UDP RX %s:%d", pxe->name,
1200  pshdr->net->ntoa ( actual_dest_ip ), pshdr->dest_port );
1201  DBGC2 ( pxe, "<-%s:%d len %#zx\n", pshdr->net->ntoa ( actual_src_ip ),
1202  pshdr->src_port, iob_len ( iobuf ) );
1203 
1204  /* Filter based on network-layer protocol */
1205  if ( pshdr->net != pxe->net ) {
1206  DBGC2 ( pxe, "PXE %s filtered out %s packet\n",
1207  pxe->name, pshdr->net->name );
1208  rc = -ETIMEDOUT; /* "no packet" */
1209  goto err_filter;
1210  }
1211 
1212  /* Filter based on port numbers */
1214  ( dest_port && ( *dest_port == pshdr->dest_port ) ) ) ) {
1215  DBGC2 ( pxe, "PXE %s filtered out destination port %d\n",
1216  pxe->name, pshdr->dest_port );
1217  rc = -ETIMEDOUT; /* "no packet" */
1218  goto err_filter;
1219  }
1221  ( src_port && ( *src_port == pshdr->src_port ) ) ) ) {
1222  DBGC2 ( pxe, "PXE %s filtered out source port %d\n",
1223  pxe->name, pshdr->src_port );
1224  rc = -ETIMEDOUT; /* "no packet" */
1225  goto err_filter;
1226  }
1227 
1228  /* Filter based on source IP address */
1230  ( src_ip &&
1231  ( memcmp ( src_ip, actual_src_ip, addr_len ) == 0 ) ) ) ) {
1232  DBGC2 ( pxe, "PXE %s filtered out source IP %s\n",
1233  pxe->name, pshdr->net->ntoa ( actual_src_ip ) );
1234  rc = -ETIMEDOUT; /* "no packet" */
1235  goto err_filter;
1236  }
1237 
1238  /* Filter based on destination IP address */
1240  efi_pxe_ip_filter ( pxe, actual_dest_ip ) ) ||
1243  ( dest_ip && ( memcmp ( dest_ip, actual_dest_ip,
1244  addr_len ) == 0 ) ) ) ) ) ) {
1245  DBGC2 ( pxe, "PXE %s filtered out destination IP %s\n",
1246  pxe->name, pshdr->net->ntoa ( actual_dest_ip ) );
1247  rc = -ETIMEDOUT; /* "no packet" */
1248  goto err_filter;
1249  }
1250 
1251  /* Fill in addresses and port numbers */
1252  if ( dest_ip )
1253  memcpy ( dest_ip, actual_dest_ip, addr_len );
1254  if ( dest_port )
1255  *dest_port = pshdr->dest_port;
1256  if ( src_ip )
1257  memcpy ( src_ip, actual_src_ip, addr_len );
1258  if ( src_port )
1259  *src_port = pshdr->src_port;
1260 
1261  /* Fill in header, if applicable */
1262  if ( hdr_len ) {
1263  frag_len = iob_len ( iobuf );
1264  if ( frag_len > *hdr_len )
1265  frag_len = *hdr_len;
1266  memcpy ( hdr, iobuf->data, frag_len );
1267  iob_pull ( iobuf, frag_len );
1268  *hdr_len = frag_len;
1269  }
1270 
1271  /* Fill in data buffer */
1272  frag_len = iob_len ( iobuf );
1273  if ( frag_len > *len )
1274  frag_len = *len;
1275  memcpy ( data, iobuf->data, frag_len );
1276  iob_pull ( iobuf, frag_len );
1277  *len = frag_len;
1278 
1279  /* Check for overflow */
1280  if ( iob_len ( iobuf ) ) {
1281  rc = -ERANGE;
1282  goto err_too_short;
1283  }
1284 
1285  /* Success */
1286  rc = 0;
1287 
1288  err_too_short:
1289  err_filter:
1290  free_iob ( iobuf );
1291  err_empty:
1293  err_open:
1294  return EFIRC ( rc );
1295 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
EFI UDP pseudo-header.
Definition: efi_pxe.c:462
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t dest_port
Destination port.
Definition: efi_pxe.c:466
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:211
A PXE base code.
Definition: efi_pxe.c:68
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
static int efi_pxe_ip_filter(struct efi_pxe *pxe, EFI_IP_ADDRESS *ip)
Check if IP address matches filter.
Definition: efi_pxe.c:256
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:464
IP4_t src_ip
IP address of this station.
Definition: pxe_api.h:58
const char * name
Name.
Definition: efi_pxe.c:74
#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:116
#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:117
#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:110
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:115
#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:599
struct net_protocol * net
Network-layer protocol.
Definition: efi_pxe.c:90
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT
Definition: PxeBaseCode.h:114
IP4_t dest_ip
Destination IP address.
Definition: pxe_api.h:59
uint16_t src_port
Source port.
Definition: efi_pxe.c:468
uint16_t base
Base address.
Definition: edd.h:14
uint32_t hdr
Message header.
Definition: intelvf.h:12
#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP
Definition: PxeBaseCode.h:113
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
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:44
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:105
static int efi_pxe_udp_open(struct efi_pxe *pxe)
Open UDP interface.
Definition: efi_pxe.c:572
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
#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:151
A persistent I/O buffer.
Definition: iobuf.h:32
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 1305 of file efi_pxe.c.

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

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

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

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

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

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

1403  {
1404  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1405  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1406 
1407  DBGC ( pxe, "PXE %s SET STATION IP ", pxe->name );
1408  if ( ip )
1409  DBGC ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, ip ) );
1410  if ( netmask )
1411  DBGC ( pxe, "/%s", efi_pxe_ip_ntoa ( pxe, netmask ) );
1412  DBGC ( pxe, "\n" );
1413 
1414  /* Update IP address and netmask */
1415  if ( ip )
1416  memcpy ( &mode->StationIp, ip, sizeof ( mode->StationIp ) );
1417  if ( netmask )
1418  memcpy ( &mode->SubnetMask, netmask, sizeof (mode->SubnetMask));
1419 
1420  return 0;
1421 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
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:211
A PXE base code.
Definition: efi_pxe.c:68
#define DBGC(...)
Definition: compiler.h:505
EFI_IP_ADDRESS SubnetMask
Definition: PxeBaseCode.h:293
const char * name
Name.
Definition: efi_pxe.c:74
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
uint16_t base
Base address.
Definition: edd.h:14
EFI_IP_ADDRESS StationIp
Definition: PxeBaseCode.h:292

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

1450  {
1451  struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
1452  EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
1453 
1454  DBGC ( pxe, "PXE %s SET PACKETS\n", pxe->name );
1455 
1456  /* Update fake packet flags */
1457  if ( dhcpdisc_ok )
1458  mode->DhcpDiscoverValid = *dhcpdisc_ok;
1459  if ( dhcpack_ok )
1460  mode->DhcpAckReceived = *dhcpack_ok;
1461  if ( proxyoffer_ok )
1462  mode->ProxyOfferReceived = *proxyoffer_ok;
1463  if ( pxebsdisc_ok )
1464  mode->PxeDiscoverValid = *pxebsdisc_ok;
1465  if ( pxebsack_ok )
1466  mode->PxeReplyReceived = *pxebsack_ok;
1467  if ( pxebsbis_ok )
1468  mode->PxeBisReplyReceived = *pxebsbis_ok;
1469 
1470  /* Update fake packet contents */
1471  if ( dhcpdisc )
1472  memcpy ( &mode->DhcpDiscover, dhcpdisc, sizeof ( *dhcpdisc ) );
1473  if ( dhcpack )
1474  memcpy ( &mode->DhcpAck, dhcpack, sizeof ( *dhcpack ) );
1475  if ( proxyoffer )
1476  memcpy ( &mode->ProxyOffer, proxyoffer, sizeof ( *proxyoffer ));
1477  if ( pxebsdisc )
1478  memcpy ( &mode->PxeDiscover, pxebsdisc, sizeof ( *pxebsdisc ) );
1479  if ( pxebsack )
1480  memcpy ( &mode->PxeReply, pxebsack, sizeof ( *pxebsack ) );
1481  if ( pxebsbis )
1482  memcpy ( &mode->PxeBisReply, pxebsbis, sizeof ( *pxebsbis ) );
1483 
1484  return 0;
1485 }
EFI_PXE_BASE_CODE_MODE.
Definition: PxeBaseCode.h:272
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
A PXE base code.
Definition: efi_pxe.c:68
#define DBGC(...)
Definition: compiler.h:505
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:298
const char * name
Name.
Definition: efi_pxe.c:74
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:299
uint16_t base
Base address.
Definition: edd.h:14
EFI_PXE_BASE_CODE_PACKET DhcpDiscover
Definition: PxeBaseCode.h:294
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:295
EFI_PXE_BASE_CODE_PACKET PxeDiscover
Definition: PxeBaseCode.h:297
EFI_PXE_BASE_CODE_PACKET ProxyOffer
Definition: PxeBaseCode.h:296

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

1521  {
1522 
1523  /* Check length */
1524  if ( *len < sizeof ( *packet ) ) {
1525  *len = sizeof ( *packet );
1526  return EFI_BUFFER_TOO_SMALL;
1527  }
1528 
1529  /* Copy packet */
1530  memcpy ( data, packet, sizeof ( *packet ) );
1531  *len = sizeof ( *packet );
1532 
1533  return EFI_SUCCESS;
1534 }
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:125
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:120
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

1546  {
1547  struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1548 
1549  return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
1550 }
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
A PXE base code.
Definition: efi_pxe.c:68
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:85
#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:1520
EFI_PXE_BASE_CODE_PACKET DhcpAck
Definition: PxeBaseCode.h:295
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

1562  {
1563  struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
1564 
1565  return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
1566 }
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
A PXE base code.
Definition: efi_pxe.c:68
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:85
EFI_PXE_BASE_CODE_PACKET PxeReply
Definition: PxeBaseCode.h:298
#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:1520
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

1588  {
1590  struct tcpip_net_protocol *ipv6 = tcpip_net_protocol ( AF_INET6 );
1591  struct efi_pxe *pxe;
1592  struct in_addr ip;
1593  BOOLEAN use_ipv6;
1594  EFI_STATUS efirc;
1595  int rc;
1596 
1597  /* Allocate and initialise structure */
1598  pxe = zalloc ( sizeof ( *pxe ) );
1599  if ( ! pxe ) {
1600  rc = -ENOMEM;
1601  goto err_alloc;
1602  }
1603  ref_init ( &pxe->refcnt, efi_pxe_free );
1604  pxe->netdev = netdev_get ( netdev );
1605  pxe->name = netdev->name;
1606  pxe->handle = handle;
1607  memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
1608  pxe->base.Mode = &pxe->mode;
1610  sizeof ( pxe->apple ) );
1611  pxe->buf.op = &efi_pxe_buf_operations;
1612  intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
1613  intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
1614  INIT_LIST_HEAD ( &pxe->queue );
1616  &pxe->refcnt );
1617 
1618  /* Crude heuristic: assume that we prefer to use IPv4 if we
1619  * have an IPv4 address for the network device, otherwise
1620  * prefer IPv6 (if available).
1621  */
1622  fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting, &ip );
1623  use_ipv6 = ( ip.s_addr ? FALSE : ( ipv6 != NULL ) );
1624 
1625  /* Start base code */
1626  efi_pxe_start ( &pxe->base, use_ipv6 );
1627 
1628  /* Install PXE base code protocol */
1629  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1630  &handle,
1633  NULL ) ) != 0 ) {
1634  rc = -EEFI ( efirc );
1635  DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
1636  pxe->name, strerror ( rc ) );
1637  goto err_install_protocol;
1638  }
1639 
1640  /* Transfer reference to list and return */
1641  list_add_tail ( &pxe->list, &efi_pxes );
1642  DBGC ( pxe, "PXE %s installed for %s\n",
1643  pxe->name, efi_handle_name ( handle ) );
1644  return 0;
1645 
1647  handle,
1650  NULL );
1651  err_install_protocol:
1652  ref_put ( &pxe->refcnt );
1653  err_alloc:
1654  return rc;
1655 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_PXE_BASE_CODE_MODE mode
PXE base code mode.
Definition: efi_pxe.c:83
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:159
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
struct list_head list
List of PXE base codes.
Definition: efi_pxe.c:76
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition: efi_pxe.c:750
struct refcnt refcnt
Reference count.
Definition: efi_pxe.c:70
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
A PXE base code.
Definition: efi_pxe.c:68
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition: settings.c:916
unsigned char BOOLEAN
Definition: ProcessorBind.h:61
static struct interface_descriptor efi_pxe_tftp_desc
PXE file data transfer interface descriptor.
Definition: efi_pxe.c:414
EFI_PXE_BASE_CODE_PROTOCOL base
PXE base code protocol.
Definition: efi_pxe.c:81
#define DBGC(...)
Definition: compiler.h:505
struct interface udp
UDP interface.
Definition: efi_pxe.c:103
struct xfer_buffer buf
Data transfer buffer.
Definition: efi_pxe.c:93
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:85
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition: efi_guid.c:224
static struct process_descriptor efi_pxe_process_desc
UDP close process descriptor.
Definition: efi_pxe.c:623
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
const char * name
Name.
Definition: efi_pxe.c:74
EFI_HANDLE handle
Installed handle.
Definition: efi_pxe.c:79
#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:72
#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
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:713
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:1569
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:342
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1836
IP address structure.
Definition: in.h:39
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
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:563
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
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:96
#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:96
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
struct process process
UDP interface closer process.
Definition: efi_pxe.c:107
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
struct list_head queue
List of received UDP packets.
Definition: efi_pxe.c:105
#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
EFI_PXE_BASE_CODE_MODE * Mode
The pointer to the EFI_PXE_BASE_CODE_MODE data for this device.
Definition: PxeBaseCode.h:931
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
static void efi_pxe_free(struct refcnt *refcnt)
Free PXE base code.
Definition: efi_pxe.c:115
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol
PXE base code protocol.
Definition: efi_pxe.c:1488
#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_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 1662 of file efi_pxe.c.

1662  {
1664  struct efi_pxe *pxe;
1665 
1666  /* Locate PXE base code */
1667  pxe = efi_pxe_find ( handle );
1668  if ( ! handle ) {
1669  DBG ( "PXE could not find base code for %s\n",
1670  efi_handle_name ( handle ) );
1671  return;
1672  }
1673 
1674  /* Stop base code */
1675  efi_pxe_stop ( &pxe->base );
1676 
1677  /* Uninstall PXE base code protocol */
1679  handle,
1682  NULL );
1683 
1684  /* Remove from list and drop list's reference */
1685  list_del ( &pxe->list );
1686  ref_put ( &pxe->refcnt );
1687 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
static struct efi_pxe * efi_pxe_find(EFI_HANDLE handle)
Locate PXE base code.
Definition: efi_pxe.c:131
struct list_head list
List of PXE base codes.
Definition: efi_pxe.c:76
struct refcnt refcnt
Reference count.
Definition: efi_pxe.c:70
A PXE base code.
Definition: efi_pxe.c:68
EFI_PXE_BASE_CODE_PROTOCOL base
PXE base code protocol.
Definition: efi_pxe.c:81
EFI_APPLE_NET_BOOT_PROTOCOL apple
Apple NetBoot protocol.
Definition: efi_pxe.c:85
EFI_GUID efi_pxe_base_code_protocol_guid
PXE base code protocol GUID.
Definition: efi_guid.c:224
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:713
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
EFI_GUID efi_apple_net_boot_protocol_guid
Apple NetBoot protocol GUID.
Definition: efi_guid.c:96
EFI_SYSTEM_TABLE * efi_systab
#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:804
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References efi_pxe::apple, efi_pxe::base, EFI_SYSTEM_TABLE::BootServices, DBG, efi_apple_net_boot_protocol_guid, efi_handle_name(), efi_pxe_base_code_protocol_guid, efi_pxe_find(), efi_pxe_stop(), efi_systab, handle, efi_pxe::list, list_del, NULL, ref_put, efi_pxe::refcnt, 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:334
static int efi_pxe_buf_realloc(struct xfer_buffer *xferbuf __unused, size_t len __unused)
Reallocate PXE data transfer buffer.
Definition: efi_pxe.c:319

PXE data transfer buffer operations.

Definition at line 342 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:375
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
A PXE base code.
Definition: efi_pxe.c:68
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
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:389
#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:193
static void efi_pxe_tftp_close(struct efi_pxe *pxe, int rc)
Close PXE (M)TFTP download interface.
Definition: efi_pxe.c:360

PXE file data transfer interface operations.

Definition at line 407 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:68
static struct interface_operation efi_pxe_tftp_operations[]
PXE file data transfer interface operations.
Definition: efi_pxe.c:407
struct interface tftp
(M)TFTP download interface
Definition: efi_pxe.c:96
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

PXE file data transfer interface descriptor.

Definition at line 414 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:244
A PXE base code.
Definition: efi_pxe.c:68
#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:193
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:506
static void efi_pxe_udp_close(struct efi_pxe *pxe, int rc)
Close UDP interface.
Definition: efi_pxe.c:477

PXE UDP interface operations.

Definition at line 557 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:68
struct interface udp
UDP interface.
Definition: efi_pxe.c:103
static struct interface_operation efi_pxe_udp_operations[]
PXE UDP interface operations.
Definition: efi_pxe.c:557
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

PXE UDP interface descriptor.

Definition at line 563 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:68
#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:616

UDP close process descriptor.

Definition at line 623 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:1333
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:1442
static EFI_STATUS EFIAPI efi_pxe_dhcp(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN sort)
Perform DHCP.
Definition: efi_pxe.c:829
static EFI_STATUS EFIAPI efi_pxe_start(EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN use_ipv6)
Start PXE base code.
Definition: efi_pxe.c:750
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:1305
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:1357
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:1124
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:1402
#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION
Definition: PxeBaseCode.h:894
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:883
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:1010
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:927
static EFI_STATUS EFIAPI efi_pxe_stop(EFI_PXE_BASE_CODE_PROTOCOL *base)
Stop PXE base code.
Definition: efi_pxe.c:804

PXE base code protocol.

Definition at line 1488 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:1561
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:1545

Apple NetBoot protocol.

Definition at line 1569 of file efi_pxe.c.

Referenced by efi_pxe_install().