iPXE
pxe_udp.c
Go to the documentation of this file.
1/** @file
2 *
3 * PXE UDP API
4 *
5 */
6
7#include <string.h>
8#include <byteswap.h>
9#include <ipxe/iobuf.h>
10#include <ipxe/xfer.h>
11#include <ipxe/udp.h>
12#include <ipxe/process.h>
13#include <ipxe/netdevice.h>
14#include <ipxe/malloc.h>
15#include <realmode.h>
16#include <pxe.h>
17
18/*
19 * Copyright (C) 2004 Michael Brown <mbrown@fensystems.co.uk>.
20 *
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License as
23 * published by the Free Software Foundation; either version 2 of the
24 * License, or any later version.
25 *
26 * This program is distributed in the hope that it will be useful, but
27 * WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 * 02110-1301, USA.
35 *
36 * You can also choose to distribute this program under the terms of
37 * the Unmodified Binary Distribution Licence (as given in the file
38 * COPYING.UBDL), provided that you have satisfied its requirements.
39 */
40
41FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
42
43/** A PXE UDP pseudo-header */
45 /** Source IP address */
47 /** Source port */
49 /** Destination IP address */
51 /** Destination port */
53} __attribute__ (( packed ));
54
55/** A PXE UDP connection */
57 /** Data transfer interface to UDP stack */
59 /** Local address */
61 /** List of received packets */
63};
64
65/**
66 * Receive PXE UDP data
67 *
68 * @v pxe_udp PXE UDP connection
69 * @v iobuf I/O buffer
70 * @v meta Data transfer metadata
71 * @ret rc Return status code
72 *
73 * Receives a packet as part of the current pxenv_udp_read()
74 * operation.
75 */
77 struct io_buffer *iobuf,
78 struct xfer_metadata *meta ) {
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}
114
115/** PXE UDP data transfer interface operations */
119
120/** PXE UDP data transfer interface descriptor */
123
124/** The PXE UDP connection */
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};
132
133/**
134 * UDP OPEN
135 *
136 * @v pxenv_udp_open Pointer to a struct s_PXENV_UDP_OPEN
137 * @v s_PXENV_UDP_OPEN::src_ip IP address of this station, or 0.0.0.0
138 * @ret #PXENV_EXIT_SUCCESS Always
139 * @ret s_PXENV_UDP_OPEN::Status PXE status code
140 * @err #PXENV_STATUS_UDP_OPEN UDP connection already open
141 * @err #PXENV_STATUS_OUT_OF_RESOURCES Could not open connection
142 *
143 * Prepares the PXE stack for communication using pxenv_udp_write()
144 * and pxenv_udp_read().
145 *
146 * The IP address supplied in s_PXENV_UDP_OPEN::src_ip will be
147 * recorded and used as the local station's IP address for all further
148 * communication, including communication by means other than
149 * pxenv_udp_write() and pxenv_udp_read(). (If
150 * s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the local station's IP address
151 * will remain unchanged.)
152 *
153 * You can only have one open UDP connection at a time. This is not a
154 * meaningful restriction, since pxenv_udp_write() and
155 * pxenv_udp_read() allow you to specify arbitrary local and remote
156 * ports and an arbitrary remote address for each packet. According
157 * to the PXE specifiation, you cannot have a UDP connection open at
158 * the same time as a TFTP connection; this restriction does not apply
159 * to Etherboot.
160 *
161 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
162 * value before calling this function in protected mode. You cannot
163 * call this function with a 32-bit stack segment. (See the relevant
164 * @ref pxe_x86_pmode16 "implementation note" for more details.)
165 *
166 * @note The PXE specification does not make it clear whether the IP
167 * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only
168 * for this UDP connection, or retained for all future communication.
169 * The latter seems more consistent with typical PXE stack behaviour.
170 *
171 * @note Etherboot currently ignores the s_PXENV_UDP_OPEN::src_ip
172 * parameter.
173 *
174 */
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}
205
206/**
207 * UDP CLOSE
208 *
209 * @v pxenv_udp_close Pointer to a struct s_PXENV_UDP_CLOSE
210 * @ret #PXENV_EXIT_SUCCESS Always
211 * @ret s_PXENV_UDP_CLOSE::Status PXE status code
212 * @err None -
213 *
214 * Closes a UDP connection opened with pxenv_udp_open().
215 *
216 * You can only have one open UDP connection at a time. You cannot
217 * have a UDP connection open at the same time as a TFTP connection.
218 * You cannot use pxenv_udp_close() to close a TFTP connection; use
219 * pxenv_tftp_close() instead.
220 *
221 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
222 * value before calling this function in protected mode. You cannot
223 * call this function with a 32-bit stack segment. (See the relevant
224 * @ref pxe_x86_pmode16 "implementation note" for more details.)
225 *
226 */
227static PXENV_EXIT_t
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}
246
247/**
248 * UDP WRITE
249 *
250 * @v pxenv_udp_write Pointer to a struct s_PXENV_UDP_WRITE
251 * @v s_PXENV_UDP_WRITE::ip Destination IP address
252 * @v s_PXENV_UDP_WRITE::gw Relay agent IP address, or 0.0.0.0
253 * @v s_PXENV_UDP_WRITE::src_port Source UDP port, or 0
254 * @v s_PXENV_UDP_WRITE::dst_port Destination UDP port
255 * @v s_PXENV_UDP_WRITE::buffer_size Length of the UDP payload
256 * @v s_PXENV_UDP_WRITE::buffer Address of the UDP payload
257 * @ret #PXENV_EXIT_SUCCESS Packet was transmitted successfully
258 * @ret #PXENV_EXIT_FAILURE Packet could not be transmitted
259 * @ret s_PXENV_UDP_WRITE::Status PXE status code
260 * @err #PXENV_STATUS_UDP_CLOSED UDP connection is not open
261 * @err #PXENV_STATUS_UNDI_TRANSMIT_ERROR Could not transmit packet
262 *
263 * Transmits a single UDP packet. A valid IP and UDP header will be
264 * prepended to the payload in s_PXENV_UDP_WRITE::buffer; the buffer
265 * should not contain precomputed IP and UDP headers, nor should it
266 * contain space allocated for these headers. The first byte of the
267 * buffer will be transmitted as the first byte following the UDP
268 * header.
269 *
270 * If s_PXENV_UDP_WRITE::gw is 0.0.0.0, normal IP routing will take
271 * place. See the relevant @ref pxe_routing "implementation note" for
272 * more details.
273 *
274 * If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.
275 *
276 * You must have opened a UDP connection with pxenv_udp_open() before
277 * calling pxenv_udp_write().
278 *
279 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
280 * value before calling this function in protected mode. You cannot
281 * call this function with a 32-bit stack segment. (See the relevant
282 * @ref pxe_x86_pmode16 "implementation note" for more details.)
283 *
284 * @note Etherboot currently ignores the s_PXENV_UDP_WRITE::gw
285 * parameter.
286 *
287 */
288static PXENV_EXIT_t
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}
351
352/**
353 * UDP READ
354 *
355 * @v pxenv_udp_read Pointer to a struct s_PXENV_UDP_READ
356 * @v s_PXENV_UDP_READ::dest_ip Destination IP address, or 0.0.0.0
357 * @v s_PXENV_UDP_READ::d_port Destination UDP port, or 0
358 * @v s_PXENV_UDP_READ::buffer_size Size of the UDP payload buffer
359 * @v s_PXENV_UDP_READ::buffer Address of the UDP payload buffer
360 * @ret #PXENV_EXIT_SUCCESS A packet has been received
361 * @ret #PXENV_EXIT_FAILURE No packet has been received
362 * @ret s_PXENV_UDP_READ::Status PXE status code
363 * @ret s_PXENV_UDP_READ::src_ip Source IP address
364 * @ret s_PXENV_UDP_READ::dest_ip Destination IP address
365 * @ret s_PXENV_UDP_READ::s_port Source UDP port
366 * @ret s_PXENV_UDP_READ::d_port Destination UDP port
367 * @ret s_PXENV_UDP_READ::buffer_size Length of UDP payload
368 * @err #PXENV_STATUS_UDP_CLOSED UDP connection is not open
369 * @err #PXENV_STATUS_FAILURE No packet was ready to read
370 *
371 * Receive a single UDP packet. This is a non-blocking call; if no
372 * packet is ready to read, the call will return instantly with
373 * s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.
374 *
375 * If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to
376 * any IP address will be accepted and may be returned to the caller.
377 *
378 * If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP
379 * port will be accepted and may be returned to the caller.
380 *
381 * You must have opened a UDP connection with pxenv_udp_open() before
382 * calling pxenv_udp_read().
383 *
384 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
385 * value before calling this function in protected mode. You cannot
386 * call this function with a 32-bit stack segment. (See the relevant
387 * @ref pxe_x86_pmode16 "implementation note" for more details.)
388 *
389 * @note The PXE specification (version 2.1) does not state that we
390 * should fill in s_PXENV_UDP_READ::dest_ip and
391 * s_PXENV_UDP_READ::d_port, but Microsoft Windows' NTLDR program
392 * expects us to do so, and will fail if we don't.
393 *
394 */
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}
473
474/** PXE UDP API */
485
486/**
487 * Discard some cached PXE UDP data
488 *
489 * @ret discarded Number of cached items discarded
490 */
491static unsigned int pxe_udp_discard ( void ) {
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}
505
506/** PXE UDP cache discarder */
507struct cache_discarder pxe_udp_discarder __cache_discarder ( CACHE_NORMAL ) = {
508 .discard = pxe_udp_discard,
509};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
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
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
ring len
Length.
Definition dwmac.h:226
uint8_t meta
Metadata flags.
Definition ena.h:3
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define CACHE_NORMAL
Items with a normal replacement cost.
Definition malloc.h:114
#define DBG2(...)
Definition compiler.h:515
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define PXENV_EXIT_FAILURE
An error occurred.
Definition pxe_types.h:46
#define PXENV_EXIT_SUCCESS
No error occurred.
Definition pxe_types.h:45
UINT16_t PXENV_EXIT_t
A PXE exit code.
Definition pxe_types.h:44
UINT32_t IP4_t
An IPv4 address.
Definition pxe_types.h:60
UINT16_t UDP_PORT_t
A UDP port.
Definition pxe_types.h:67
#define PXENV_STATUS_FAILURE
Definition pxe_error.h:20
#define PXENV_STATUS_SUCCESS
Definition pxe_error.h:19
#define PXENV_STATUS_OUT_OF_RESOURCES
Definition pxe_error.h:25
#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 htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
#define __attribute__(x)
Definition compiler.h:10
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition interface.h:218
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
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
I/O buffers.
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define iob_put(iobuf, len)
Definition iobuf.h:125
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
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
unsigned long tmp
Definition linux_pci.h:65
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#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_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
Dynamic memory allocation.
#define __cache_discarder(cost)
Declare a cache discarder.
Definition malloc.h:106
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
Network device management.
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
void step(void)
Single-step a single process.
Definition process.c:99
Processes.
#define PXE_API_CALL(_opcode, _entry, _params_type)
Define a PXE API call.
Definition pxe.h:106
#define __pxe_api_call
Declare a PXE API call.
Definition pxe.h:96
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
#define PXENV_STATUS(rc)
Derive PXENV_STATUS code from iPXE error number.
Definition pxe_error.h:121
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
static PXENV_EXIT_t pxenv_udp_read(struct s_PXENV_UDP_READ *pxenv_udp_read)
UDP READ.
Definition pxe_udp.c:395
static PXENV_EXIT_t pxenv_udp_open(struct s_PXENV_UDP_OPEN *pxenv_udp_open)
UDP OPEN.
Definition pxe_udp.c:175
static struct interface_descriptor pxe_udp_xfer_desc
PXE UDP data transfer interface descriptor.
Definition pxe_udp.c:121
static unsigned int pxe_udp_discard(void)
Discard some cached PXE UDP data.
Definition pxe_udp.c:491
static struct pxe_udp_connection pxe_udp
The PXE UDP connection.
Definition pxe_udp.c:125
static PXENV_EXIT_t pxenv_udp_close(struct s_PXENV_UDP_CLOSE *pxenv_udp_close)
UDP CLOSE.
Definition pxe_udp.c:228
static PXENV_EXIT_t pxenv_udp_write(struct s_PXENV_UDP_WRITE *pxenv_udp_write)
UDP WRITE.
Definition pxe_udp.c:289
static struct interface_operation pxe_udp_xfer_operations[]
PXE UDP data transfer interface operations.
Definition pxe_udp.c:116
struct net_device * pxe_netdev
Definition pxe_undi.c:59
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A cache discarder.
Definition malloc.h:93
IP address structure.
Definition in.h:42
uint32_t s_addr
Definition in.h:43
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
A doubly-linked list entry (or list head)
Definition list.h:19
A PXE API call.
Definition pxe.h:81
A PXE UDP connection.
Definition pxe_udp.c:56
struct list_head list
List of received packets.
Definition pxe_udp.c:62
struct interface xfer
Data transfer interface to UDP stack.
Definition pxe_udp.c:58
struct sockaddr_in local
Local address.
Definition pxe_udp.c:60
A PXE UDP pseudo-header.
Definition pxe_udp.c:44
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
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
IPv4 socket address.
Definition in.h:85
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
Definition in.h:94
struct in_addr sin_addr
IPv4 address.
Definition in.h:101
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition in.h:90
Generalized socket address structure.
Definition socket.h:97
Data transfer metadata.
Definition xfer.h:23
int udp_open_promisc(struct interface *xfer)
Open a promiscuous UDP connection.
Definition udp.c:145
UDP protocol.
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
Data transfer interfaces.