iPXE
pxe_udp.c File Reference

PXE UDP API. More...

#include <string.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/udp.h>
#include <ipxe/process.h>
#include <ipxe/netdevice.h>
#include <ipxe/malloc.h>
#include <realmode.h>
#include <pxe.h>

Go to the source code of this file.

Data Structures

struct  pxe_udp_pseudo_header
 A PXE UDP pseudo-header. More...
struct  pxe_udp_connection
 A PXE UDP connection. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int pxe_udp_deliver (struct pxe_udp_connection *pxe_udp, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive PXE UDP data.
static PXENV_EXIT_t pxenv_udp_open (struct s_PXENV_UDP_OPEN *pxenv_udp_open)
 UDP OPEN.
static PXENV_EXIT_t pxenv_udp_close (struct s_PXENV_UDP_CLOSE *pxenv_udp_close)
 UDP CLOSE.
static PXENV_EXIT_t pxenv_udp_write (struct s_PXENV_UDP_WRITE *pxenv_udp_write)
 UDP WRITE.
static PXENV_EXIT_t pxenv_udp_read (struct s_PXENV_UDP_READ *pxenv_udp_read)
 UDP READ.
static unsigned int pxe_udp_discard (void)
 Discard some cached PXE UDP data.
struct cache_discarder pxe_udp_discarder __cache_discarder (CACHE_NORMAL)
 PXE UDP cache discarder.

Variables

static struct interface_operation pxe_udp_xfer_operations []
 PXE UDP data transfer interface operations.
static struct interface_descriptor pxe_udp_xfer_desc
 PXE UDP data transfer interface descriptor.
static struct pxe_udp_connection pxe_udp
 The PXE UDP connection.
struct pxe_api_call pxe_udp_api[] __pxe_api_call
 PXE UDP API.

Detailed Description

PXE UDP API.

Definition in file pxe_udp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ pxe_udp_deliver()

int pxe_udp_deliver ( struct pxe_udp_connection * pxe_udp,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Receive PXE UDP data.

Parameters
pxe_udpPXE UDP connection
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Receives a packet as part of the current pxenv_udp_read() operation.

Definition at line 76 of file pxe_udp.c.

78 {
79 struct pxe_udp_pseudo_header *pshdr;
80 struct sockaddr_in *sin_src;
81 struct sockaddr_in *sin_dest;
82 int rc;
83
84 /* Extract metadata */
85 assert ( meta );
86 sin_src = ( struct sockaddr_in * ) meta->src;
87 assert ( sin_src );
88 assert ( sin_src->sin_family == AF_INET );
89 sin_dest = ( struct sockaddr_in * ) meta->dest;
90 assert ( sin_dest );
91 assert ( sin_dest->sin_family == AF_INET );
92
93 /* Construct pseudo-header */
94 if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *pshdr ) ) ) != 0 ) {
95 DBG ( "PXE could not prepend pseudo-header\n" );
96 rc = -ENOMEM;
97 goto drop;
98 }
99 pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
100 pshdr->src_ip = sin_src->sin_addr.s_addr;
101 pshdr->s_port = sin_src->sin_port;
102 pshdr->dest_ip = sin_dest->sin_addr.s_addr;
103 pshdr->d_port = sin_dest->sin_port;
104
105 /* Add to queue */
106 list_add_tail ( &iobuf->list, &pxe_udp->list );
107
108 return 0;
109
110 drop:
111 free_iob ( iobuf );
112 return rc;
113}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint8_t meta
Metadata flags.
Definition ena.h:3
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOMEM
Not enough space.
Definition errno.h:535
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition iobuf.c:235
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
static struct pxe_udp_connection pxe_udp
The PXE UDP connection.
Definition pxe_udp.c:125
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
A PXE UDP pseudo-header.
Definition pxe_udp.c:44
IPv4 socket address.
Definition in.h:85

References AF_INET, assert, pxe_udp_pseudo_header::d_port, DBG, pxe_udp_pseudo_header::dest_ip, ENOMEM, free_iob(), iob_ensure_headroom(), iob_push, io_buffer::list, list_add_tail, meta, pxe_udp, rc, in_addr::s_addr, pxe_udp_pseudo_header::s_port, sockaddr_in::sin_addr, sockaddr_in::sin_family, sockaddr_in::sin_port, and pxe_udp_pseudo_header::src_ip.

◆ pxenv_udp_open()

PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN * pxenv_udp_open)
static

UDP OPEN.

Parameters
pxenv_udp_openPointer to a struct s_PXENV_UDP_OPEN
s_PXENV_UDP_OPEN::src_ipIP address of this station, or 0.0.0.0
Return values
PXENV_EXIT_SUCCESSAlways
s_PXENV_UDP_OPEN::StatusPXE status code
Exceptions
PXENV_STATUS_UDP_OPENUDP connection already open
PXENV_STATUS_OUT_OF_RESOURCESCould not open connection

Prepares the PXE stack for communication using pxenv_udp_write() and pxenv_udp_read().

The IP address supplied in s_PXENV_UDP_OPEN::src_ip will be recorded and used as the local station's IP address for all further communication, including communication by means other than pxenv_udp_write() and pxenv_udp_read(). (If s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the local station's IP address will remain unchanged.)

You can only have one open UDP connection at a time. This is not a meaningful restriction, since pxenv_udp_write() and pxenv_udp_read() allow you to specify arbitrary local and remote ports and an arbitrary remote address for each packet. According to the PXE specifiation, you cannot have a UDP connection open at the same time as a TFTP connection; this restriction does not apply to Etherboot.

On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)

Note
The PXE specification does not make it clear whether the IP address supplied in s_PXENV_UDP_OPEN::src_ip should be used only for this UDP connection, or retained for all future communication. The latter seems more consistent with typical PXE stack behaviour.
Etherboot currently ignores the s_PXENV_UDP_OPEN::src_ip parameter.

Definition at line 175 of file pxe_udp.c.

175 {
176 int rc;
177
178 DBG ( "PXENV_UDP_OPEN" );
179
180 /* Record source IP address */
181 pxe_udp.local.sin_addr.s_addr = pxenv_udp_open->src_ip;
182 DBG ( " %s\n", inet_ntoa ( pxe_udp.local.sin_addr ) );
183
184 /* Open network device, if necessary */
185 if ( pxe_netdev && ( ! netdev_is_open ( pxe_netdev ) ) &&
186 ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) ) {
187 DBG ( "PXENV_UDP_OPEN could not (implicitly) open %s: %s\n",
188 pxe_netdev->name, strerror ( rc ) );
189 pxenv_udp_open->Status = PXENV_STATUS ( rc );
190 return PXENV_EXIT_FAILURE;
191 }
192
193 /* Open promiscuous UDP connection */
194 intf_restart ( &pxe_udp.xfer, 0 );
195 if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {
196 DBG ( "PXENV_UDP_OPEN could not open promiscuous socket: %s\n",
197 strerror ( rc ) );
198 pxenv_udp_open->Status = PXENV_STATUS ( rc );
199 return PXENV_EXIT_FAILURE;
200 }
201
203 return PXENV_EXIT_SUCCESS;
204}
#define PXENV_EXIT_FAILURE
An error occurred.
Definition pxe_types.h:46
#define PXENV_EXIT_SUCCESS
No error occurred.
Definition pxe_types.h:45
#define PXENV_STATUS_SUCCESS
Definition pxe_error.h:19
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
#define PXENV_STATUS(rc)
Derive PXENV_STATUS code from iPXE error number.
Definition pxe_error.h:121
static PXENV_EXIT_t pxenv_udp_open(struct s_PXENV_UDP_OPEN *pxenv_udp_open)
UDP OPEN.
Definition pxe_udp.c:175
struct net_device * pxe_netdev
Definition pxe_undi.c:59
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int udp_open_promisc(struct interface *xfer)
Open a promiscuous UDP connection.
Definition udp.c:145

References DBG, inet_ntoa(), intf_restart(), netdev_is_open(), netdev_open(), pxe_netdev, pxe_udp, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, PXENV_STATUS_SUCCESS, pxenv_udp_open(), rc, strerror(), and udp_open_promisc().

Referenced by pxenv_udp_open().

◆ pxenv_udp_close()

PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE * pxenv_udp_close)
static

UDP CLOSE.

Parameters
pxenv_udp_closePointer to a struct s_PXENV_UDP_CLOSE
Return values
PXENV_EXIT_SUCCESSAlways
s_PXENV_UDP_CLOSE::StatusPXE status code
Exceptions
None-

Closes a UDP connection opened with pxenv_udp_open().

You can only have one open UDP connection at a time. You cannot have a UDP connection open at the same time as a TFTP connection. You cannot use pxenv_udp_close() to close a TFTP connection; use pxenv_tftp_close() instead.

On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)

Definition at line 228 of file pxe_udp.c.

228 {
229 struct io_buffer *iobuf;
230 struct io_buffer *tmp;
231
232 DBG ( "PXENV_UDP_CLOSE\n" );
233
234 /* Close UDP connection */
235 intf_restart ( &pxe_udp.xfer, 0 );
236
237 /* Discard any received packets */
238 list_for_each_entry_safe ( iobuf, tmp, &pxe_udp.list, list ) {
239 list_del ( &iobuf->list );
240 free_iob ( iobuf );
241 }
242
244 return PXENV_EXIT_SUCCESS;
245}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static PXENV_EXIT_t pxenv_udp_close(struct s_PXENV_UDP_CLOSE *pxenv_udp_close)
UDP CLOSE.
Definition pxe_udp.c:228
A persistent I/O buffer.
Definition iobuf.h:38

References DBG, free_iob(), intf_restart(), io_buffer::list, list_del, list_for_each_entry_safe, pxe_udp, PXENV_EXIT_SUCCESS, PXENV_STATUS_SUCCESS, pxenv_udp_close(), and tmp.

Referenced by pxenv_udp_close().

◆ pxenv_udp_write()

PXENV_EXIT_t pxenv_udp_write ( struct s_PXENV_UDP_WRITE * pxenv_udp_write)
static

UDP WRITE.

Parameters
pxenv_udp_writePointer to a struct s_PXENV_UDP_WRITE
s_PXENV_UDP_WRITE::ipDestination IP address
s_PXENV_UDP_WRITE::gwRelay agent IP address, or 0.0.0.0
s_PXENV_UDP_WRITE::src_portSource UDP port, or 0
s_PXENV_UDP_WRITE::dst_portDestination UDP port
s_PXENV_UDP_WRITE::buffer_sizeLength of the UDP payload
s_PXENV_UDP_WRITE::bufferAddress of the UDP payload
Return values
PXENV_EXIT_SUCCESSPacket was transmitted successfully
PXENV_EXIT_FAILUREPacket could not be transmitted
s_PXENV_UDP_WRITE::StatusPXE status code
Exceptions
PXENV_STATUS_UDP_CLOSEDUDP connection is not open
PXENV_STATUS_UNDI_TRANSMIT_ERRORCould not transmit packet

Transmits a single UDP packet. A valid IP and UDP header will be prepended to the payload in s_PXENV_UDP_WRITE::buffer; the buffer should not contain precomputed IP and UDP headers, nor should it contain space allocated for these headers. The first byte of the buffer will be transmitted as the first byte following the UDP header.

If s_PXENV_UDP_WRITE::gw is 0.0.0.0, normal IP routing will take place. See the relevant implementation note for more details.

If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.

You must have opened a UDP connection with pxenv_udp_open() before calling pxenv_udp_write().

On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)

Note
Etherboot currently ignores the s_PXENV_UDP_WRITE::gw parameter.

Definition at line 289 of file pxe_udp.c.

289 {
290 struct sockaddr_in dest;
291 struct xfer_metadata meta = {
292 .src = ( struct sockaddr * ) &pxe_udp.local,
293 .dest = ( struct sockaddr * ) &dest,
294 .netdev = pxe_netdev,
295 };
296 size_t len;
297 struct io_buffer *iobuf;
298 const void *buffer;
299 int rc;
300
301 DBG ( "PXENV_UDP_WRITE" );
302
303 /* Construct destination socket address */
304 memset ( &dest, 0, sizeof ( dest ) );
305 dest.sin_family = AF_INET;
306 dest.sin_addr.s_addr = pxenv_udp_write->ip;
307 dest.sin_port = pxenv_udp_write->dst_port;
308
309 /* Set local (source) port. PXE spec says source port is 2069
310 * if not specified. Really, this ought to be set at UDP open
311 * time but hey, we didn't design this API.
312 */
313 pxe_udp.local.sin_port = pxenv_udp_write->src_port;
314 if ( ! pxe_udp.local.sin_port )
315 pxe_udp.local.sin_port = htons ( 2069 );
316
317 /* FIXME: we ignore the gateway specified, since we're
318 * confident of being able to do our own routing. We should
319 * probably allow for multiple gateways.
320 */
321
322 /* Allocate and fill data buffer */
323 len = pxenv_udp_write->buffer_size;
324 iobuf = xfer_alloc_iob ( &pxe_udp.xfer, len );
325 if ( ! iobuf ) {
326 DBG ( " out of memory\n" );
328 return PXENV_EXIT_FAILURE;
329 }
330 buffer = real_to_virt ( pxenv_udp_write->buffer.segment,
331 pxenv_udp_write->buffer.offset );
332 memcpy ( iob_put ( iobuf, len ), buffer, len );
333
334 DBG ( " %04x:%04x+%x %d->%s:%d\n", pxenv_udp_write->buffer.segment,
335 pxenv_udp_write->buffer.offset, pxenv_udp_write->buffer_size,
336 ntohs ( pxenv_udp_write->src_port ),
337 inet_ntoa ( dest.sin_addr ),
338 ntohs ( pxenv_udp_write->dst_port ) );
339
340 /* Transmit packet */
341 if ( ( rc = xfer_deliver ( &pxe_udp.xfer, iobuf, &meta ) ) != 0 ) {
342 DBG ( "PXENV_UDP_WRITE could not transmit: %s\n",
343 strerror ( rc ) );
344 pxenv_udp_write->Status = PXENV_STATUS ( rc );
345 return PXENV_EXIT_FAILURE;
346 }
347
349 return PXENV_EXIT_SUCCESS;
350}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
ring len
Length.
Definition dwmac.h:226
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define PXENV_STATUS_OUT_OF_RESOURCES
Definition pxe_error.h:25
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
#define iob_put(iobuf, len)
Definition iobuf.h:125
static PXENV_EXIT_t pxenv_udp_write(struct s_PXENV_UDP_WRITE *pxenv_udp_write)
UDP WRITE.
Definition pxe_udp.c:289
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77
Generalized socket address structure.
Definition socket.h:97
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

References AF_INET, buffer, DBG, dest, htons, inet_ntoa(), iob_put, len, memcpy(), memset(), meta, ntohs, pxe_netdev, pxe_udp, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, PXENV_STATUS_OUT_OF_RESOURCES, PXENV_STATUS_SUCCESS, pxenv_udp_write(), rc, real_to_virt(), strerror(), xfer_alloc_iob(), and xfer_deliver().

Referenced by pxenv_udp_write().

◆ pxenv_udp_read()

PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ * pxenv_udp_read)
static

UDP READ.

Parameters
pxenv_udp_readPointer to a struct s_PXENV_UDP_READ
s_PXENV_UDP_READ::dest_ipDestination IP address, or 0.0.0.0
s_PXENV_UDP_READ::d_portDestination UDP port, or 0
s_PXENV_UDP_READ::buffer_sizeSize of the UDP payload buffer
s_PXENV_UDP_READ::bufferAddress of the UDP payload buffer
Return values
PXENV_EXIT_SUCCESSA packet has been received
PXENV_EXIT_FAILURENo packet has been received
s_PXENV_UDP_READ::StatusPXE status code
s_PXENV_UDP_READ::src_ipSource IP address
s_PXENV_UDP_READ::dest_ipDestination IP address
s_PXENV_UDP_READ::s_portSource UDP port
s_PXENV_UDP_READ::d_portDestination UDP port
s_PXENV_UDP_READ::buffer_sizeLength of UDP payload
Exceptions
PXENV_STATUS_UDP_CLOSEDUDP connection is not open
PXENV_STATUS_FAILURENo packet was ready to read

Receive a single UDP packet. This is a non-blocking call; if no packet is ready to read, the call will return instantly with s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.

If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to any IP address will be accepted and may be returned to the caller.

If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP port will be accepted and may be returned to the caller.

You must have opened a UDP connection with pxenv_udp_open() before calling pxenv_udp_read().

On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)

Note
The PXE specification (version 2.1) does not state that we should fill in s_PXENV_UDP_READ::dest_ip and s_PXENV_UDP_READ::d_port, but Microsoft Windows' NTLDR program expects us to do so, and will fail if we don't.

Definition at line 395 of file pxe_udp.c.

395 {
396 struct in_addr dest_ip_wanted = { .s_addr = pxenv_udp_read->dest_ip };
397 struct in_addr dest_ip;
398 struct io_buffer *iobuf;
399 struct pxe_udp_pseudo_header *pshdr;
400 uint16_t d_port_wanted = pxenv_udp_read->d_port;
402 void *buffer;
403 size_t len;
404
405 /* Try receiving a packet, if the queue is empty */
406 if ( list_empty ( &pxe_udp.list ) )
407 step();
408
409 /* Remove first packet from the queue */
410 iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list );
411 if ( ! iobuf ) {
412 /* No packet received */
413 DBG2 ( "PXENV_UDP_READ\n" );
414 goto no_packet;
415 }
416 list_del ( &iobuf->list );
417
418 /* Strip pseudo-header */
419 assert ( iob_len ( iobuf ) >= sizeof ( *pshdr ) );
420 pshdr = iobuf->data;
421 iob_pull ( iobuf, sizeof ( *pshdr ) );
422 dest_ip.s_addr = pshdr->dest_ip;
423 d_port = pshdr->d_port;
424 DBG ( "PXENV_UDP_READ" );
425
426 /* Filter on destination address and/or port */
427 if ( dest_ip_wanted.s_addr &&
428 ( dest_ip_wanted.s_addr != dest_ip.s_addr ) ) {
429 DBG ( " wrong IP %s", inet_ntoa ( dest_ip ) );
430 DBG ( " (wanted %s)\n", inet_ntoa ( dest_ip_wanted ) );
431 goto drop;
432 }
433 if ( d_port_wanted && ( d_port_wanted != d_port ) ) {
434 DBG ( " wrong port %d", htons ( d_port ) );
435 DBG ( " (wanted %d)\n", htons ( d_port_wanted ) );
436 goto drop;
437 }
438
439 /* Copy packet to buffer and record length */
440 buffer = real_to_virt ( pxenv_udp_read->buffer.segment,
441 pxenv_udp_read->buffer.offset );
442 len = iob_len ( iobuf );
443 if ( len > pxenv_udp_read->buffer_size )
444 len = pxenv_udp_read->buffer_size;
445 memcpy ( buffer, iobuf->data, len );
446 pxenv_udp_read->buffer_size = len;
447
448 /* Fill in source/dest information */
449 pxenv_udp_read->src_ip = pshdr->src_ip;
450 pxenv_udp_read->s_port = pshdr->s_port;
451 pxenv_udp_read->dest_ip = pshdr->dest_ip;
452 pxenv_udp_read->d_port = pshdr->d_port;
453
454 DBG ( " %04x:%04x+%x %s:", pxenv_udp_read->buffer.segment,
455 pxenv_udp_read->buffer.offset, pxenv_udp_read->buffer_size,
456 inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->src_ip ) ));
457 DBG ( "%d<-%s:%d\n", ntohs ( pxenv_udp_read->s_port ),
458 inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->dest_ip ) ),
459 ntohs ( pxenv_udp_read->d_port ) );
460
461 /* Free I/O buffer */
462 free_iob ( iobuf );
463
465 return PXENV_EXIT_SUCCESS;
466
467 drop:
468 free_iob ( iobuf );
469 no_packet:
471 return PXENV_EXIT_FAILURE;
472}
unsigned short uint16_t
Definition stdint.h:11
#define DBG2(...)
Definition compiler.h:515
#define PXENV_STATUS_FAILURE
Definition pxe_error.h:20
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
void step(void)
Single-step a single process.
Definition process.c:99
IP4_t dest_ip
Destination IP address.
Definition pxe_api.h:2
UDP_PORT_t d_port
Destination UDP port.
Definition pxe_api.h:4
static PXENV_EXIT_t pxenv_udp_read(struct s_PXENV_UDP_READ *pxenv_udp_read)
UDP READ.
Definition pxe_udp.c:395
IP address structure.
Definition in.h:42
uint32_t s_addr
Definition in.h:43
void * data
Start of data.
Definition iobuf.h:53
IP4_t dest_ip
Destination IP address.
Definition pxe_udp.c:50
UDP_PORT_t s_port
Source port.
Definition pxe_udp.c:48
IP4_t src_ip
Source IP address.
Definition pxe_udp.c:46
UDP_PORT_t d_port
Destination port.
Definition pxe_udp.c:52

References assert, buffer, d_port, pxe_udp_pseudo_header::d_port, io_buffer::data, DBG, DBG2, dest_ip, pxe_udp_pseudo_header::dest_ip, free_iob(), htons, inet_ntoa(), iob_len(), iob_pull, len, io_buffer::list, list_del, list_empty, list_first_entry, memcpy(), ntohs, pxe_udp, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS_FAILURE, PXENV_STATUS_SUCCESS, pxenv_udp_read(), real_to_virt(), in_addr::s_addr, pxe_udp_pseudo_header::s_port, pxe_udp_pseudo_header::src_ip, and step().

Referenced by pxenv_udp_read().

◆ pxe_udp_discard()

unsigned int pxe_udp_discard ( void )
static

Discard some cached PXE UDP data.

Return values
discardedNumber of cached items discarded

Definition at line 491 of file pxe_udp.c.

491 {
492 struct io_buffer *iobuf;
493 unsigned int discarded = 0;
494
495 /* Try to discard the oldest received UDP packet */
496 iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list );
497 if ( iobuf ) {
498 list_del ( &iobuf->list );
499 free_iob ( iobuf );
500 discarded++;
501 }
502
503 return discarded;
504}

References free_iob(), io_buffer::list, list_del, list_first_entry, and pxe_udp.

Referenced by __cache_discarder().

◆ __cache_discarder()

struct cache_discarder pxe_udp_discarder __cache_discarder ( CACHE_NORMAL )

PXE UDP cache discarder.

References __cache_discarder, CACHE_NORMAL, and pxe_udp_discard().

Variable Documentation

◆ pxe_udp_xfer_operations

struct interface_operation pxe_udp_xfer_operations[]
static
Initial value:
= {
}
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
static int pxe_udp_deliver(struct pxe_udp_connection *pxe_udp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive PXE UDP data.
Definition pxe_udp.c:76
A PXE UDP connection.
Definition pxe_udp.c:56

PXE UDP data transfer interface operations.

Definition at line 116 of file pxe_udp.c.

116 {
118};

◆ pxe_udp_xfer_desc

struct interface_descriptor pxe_udp_xfer_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation pxe_udp_xfer_operations[]
PXE UDP data transfer interface operations.
Definition pxe_udp.c:116

PXE UDP data transfer interface descriptor.

Definition at line 121 of file pxe_udp.c.

◆ pxe_udp

struct pxe_udp_connection pxe_udp
static
Initial value:
= {
.local = {
.sin_family = AF_INET,
},
.list = LIST_HEAD_INIT ( pxe_udp.list ),
}
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition interface.h:218
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
static struct interface_descriptor pxe_udp_xfer_desc
PXE UDP data transfer interface descriptor.
Definition pxe_udp.c:121

The PXE UDP connection.

Definition at line 125 of file pxe_udp.c.

125 {
126 .xfer = INTF_INIT ( pxe_udp_xfer_desc ),
127 .local = {
128 .sin_family = AF_INET,
129 },
130 .list = LIST_HEAD_INIT ( pxe_udp.list ),
131};

Referenced by pxe_udp_deliver(), pxe_udp_discard(), pxenv_udp_close(), pxenv_udp_open(), pxenv_udp_read(), pxenv_udp_write(), and REQUIRE_OBJECT().

◆ __pxe_api_call

struct pxe_api_call pxe_udp_api [] __pxe_api_call
Initial value:
= {
struct s_PXENV_UDP_OPEN ),
struct s_PXENV_UDP_READ ),
}
#define PXENV_UDP_CLOSE
PXE API function code for pxenv_udp_close()
Definition pxe_api.h:737
#define PXENV_UDP_OPEN
PXE API function code for pxenv_udp_open()
Definition pxe_api.h:717
#define PXENV_UDP_READ
PXE API function code for pxenv_udp_read()
Definition pxe_api.h:781
#define PXENV_UDP_WRITE
PXE API function code for pxenv_udp_write()
Definition pxe_api.h:756
#define PXE_API_CALL(_opcode, _entry, _params_type)
Define a PXE API call.
Definition pxe.h:106
Parameter block for pxenv_udp_close()
Definition pxe_api.h:740
Parameter block for pxenv_udp_open()
Definition pxe_api.h:720
Parameter block for pxenv_udp_read()
Definition pxe_api.h:784
Parameter block for pxenv_udp_write()
Definition pxe_api.h:759

PXE UDP API.

Definition at line 475 of file pxe_udp.c.