iPXE
pxe_tftp.c
Go to the documentation of this file.
1 /** @file
2  *
3  * PXE TFTP API
4  *
5  */
6 
7 /*
8  * Copyright (C) 2004 Michael Brown <mbrown@fensystems.co.uk>.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of the
13  * License, or any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23  * 02110-1301, USA.
24  *
25  * You can also choose to distribute this program under the terms of
26  * the Unmodified Binary Distribution Licence (as given in the file
27  * COPYING.UBDL), provided that you have satisfied its requirements.
28  */
29 
30 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <errno.h>
35 #include <byteswap.h>
36 #include <ipxe/in.h>
37 #include <ipxe/tftp.h>
38 #include <ipxe/iobuf.h>
39 #include <ipxe/xfer.h>
40 #include <ipxe/open.h>
41 #include <ipxe/process.h>
42 #include <ipxe/uri.h>
43 #include <realmode.h>
44 #include <pxe.h>
45 
46 /** A PXE TFTP connection */
48  /** Data transfer interface */
49  struct interface xfer;
50  /** Data buffer */
51  void *buffer;
52  /** Size of data buffer */
53  size_t size;
54  /** Starting offset of data buffer */
55  size_t start;
56  /** File position */
57  size_t offset;
58  /** Maximum file position */
59  size_t max_offset;
60  /** Block size */
61  size_t blksize;
62  /** Block index */
63  unsigned int blkidx;
64  /** Overall return status code */
65  int rc;
66 };
67 
68 /**
69  * Close PXE TFTP connection
70  *
71  * @v pxe_tftp PXE TFTP connection
72  * @v rc Final status code
73  */
74 static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) {
76  pxe_tftp->rc = rc;
77 }
78 
79 /**
80  * Check flow control window
81  *
82  * @v pxe_tftp PXE TFTP connection
83  * @ret len Length of window
84  */
86 
87  return pxe_tftp->blksize;
88 }
89 
90 /**
91  * Receive new data
92  *
93  * @v pxe_tftp PXE TFTP connection
94  * @v iobuf I/O buffer
95  * @v meta Transfer metadata
96  * @ret rc Return status code
97  */
99  struct io_buffer *iobuf,
100  struct xfer_metadata *meta ) {
101  size_t len = iob_len ( iobuf );
102  int rc = 0;
103 
104  /* Calculate new buffer position */
105  if ( meta->flags & XFER_FL_ABS_OFFSET )
106  pxe_tftp->offset = 0;
107  pxe_tftp->offset += meta->offset;
108 
109  /* Copy data block to buffer */
110  if ( len == 0 ) {
111  /* No data (pure seek); treat as success */
112  } else if ( pxe_tftp->offset < pxe_tftp->start ) {
113  DBG ( " buffer underrun at %zx (min %zx)",
115  rc = -ENOBUFS;
116  } else if ( ( pxe_tftp->offset + len ) >
117  ( pxe_tftp->start + pxe_tftp->size ) ) {
118  DBG ( " buffer overrun at %zx (max %zx)",
119  ( pxe_tftp->offset + len ),
120  ( pxe_tftp->start + pxe_tftp->size ) );
121  rc = -ENOBUFS;
122  } else {
124  pxe_tftp->start ), iobuf->data, len );
125  }
126 
127  /* Calculate new buffer position */
128  pxe_tftp->offset += len;
129 
130  /* Record maximum offset as the file size */
133 
134  /* Terminate transfer on error */
135  if ( rc != 0 )
137 
138  free_iob ( iobuf );
139  return rc;
140 }
141 
142 /** PXE TFTP connection interface operations */
149 };
150 
151 /** PXE TFTP connection interface descriptor */
154 
155 /** The PXE TFTP connection */
156 static struct pxe_tftp_connection pxe_tftp = {
158 };
159 
160 /**
161  * Open PXE TFTP connection
162  *
163  * @v ipaddress IP address
164  * @v port TFTP server port (in network byte order)
165  * @v filename File name
166  * @v blksize Requested block size
167  * @ret rc Return status code
168  */
169 static int pxe_tftp_open ( IP4_t ipaddress, UDP_PORT_t port,
170  UINT8_t *filename, UINT16_t blksize ) {
171  union {
172  struct sockaddr sa;
173  struct sockaddr_in sin;
174  } server;
175  struct uri *uri;
176  int rc;
177 
178  /* Reset PXE TFTP connection structure */
179  memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
185 
186  /* Construct URI */
187  memset ( &server, 0, sizeof ( server ) );
188  server.sin.sin_family = AF_INET;
189  server.sin.sin_addr.s_addr = ipaddress;
190  server.sin.sin_port = port;
191  DBG ( " %s", sock_ntoa ( &server.sa ) );
192  if ( port )
193  DBG ( ":%d", ntohs ( port ) );
194  DBG ( ":%s", filename );
195  uri = pxe_uri ( &server.sa, ( ( char * ) filename ) );
196  if ( ! uri ) {
197  DBG ( " could not create URI\n" );
198  return -ENOMEM;
199  }
200 
201  /* Open PXE TFTP connection */
202  if ( ( rc = xfer_open_uri ( &pxe_tftp.xfer, uri ) ) != 0 ) {
203  DBG ( " could not open (%s)\n", strerror ( rc ) );
204  return rc;
205  }
206 
207  return 0;
208 }
209 
210 /**
211  * TFTP OPEN
212  *
213  * @v tftp_open Pointer to a struct s_PXENV_TFTP_OPEN
214  * @v s_PXENV_TFTP_OPEN::ServerIPAddress TFTP server IP address
215  * @v s_PXENV_TFTP_OPEN::GatewayIPAddress Relay agent IP address, or 0.0.0.0
216  * @v s_PXENV_TFTP_OPEN::FileName Name of file to open
217  * @v s_PXENV_TFTP_OPEN::TFTPPort TFTP server UDP port
218  * @v s_PXENV_TFTP_OPEN::PacketSize TFTP blksize option to request
219  * @ret #PXENV_EXIT_SUCCESS File was opened
220  * @ret #PXENV_EXIT_FAILURE File was not opened
221  * @ret s_PXENV_TFTP_OPEN::Status PXE status code
222  * @ret s_PXENV_TFTP_OPEN::PacketSize Negotiated blksize
223  * @err #PXENV_STATUS_TFTP_INVALID_PACKET_SIZE Requested blksize too small
224  *
225  * Opens a TFTP connection for downloading a file a block at a time
226  * using pxenv_tftp_read().
227  *
228  * If s_PXENV_TFTP_OPEN::GatewayIPAddress is 0.0.0.0, normal IP
229  * routing will take place. See the relevant
230  * @ref pxe_routing "implementation note" for more details.
231  *
232  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
233  * value before calling this function in protected mode. You cannot
234  * call this function with a 32-bit stack segment. (See the relevant
235  * @ref pxe_x86_pmode16 "implementation note" for more details.)
236  *
237  * @note According to the PXE specification version 2.1, this call
238  * "opens a file for reading/writing", though how writing is to be
239  * achieved without the existence of an API call %pxenv_tftp_write()
240  * is not made clear.
241  *
242  * @note Despite the existence of the numerous statements within the
243  * PXE specification of the form "...if a TFTP/MTFTP or UDP connection
244  * is active...", you cannot use pxenv_tftp_open() and
245  * pxenv_tftp_read() to read a file via MTFTP; only via plain old
246  * TFTP. If you want to use MTFTP, use pxenv_tftp_read_file()
247  * instead. Astute readers will note that, since
248  * pxenv_tftp_read_file() is an atomic operation from the point of
249  * view of the PXE API, it is conceptually impossible to issue any
250  * other PXE API call "if an MTFTP connection is active".
251  */
253  int rc;
254 
255  DBG ( "PXENV_TFTP_OPEN" );
256 
257  /* Guard against callers that fail to close before re-opening */
258  pxe_tftp_close ( &pxe_tftp, 0 );
259 
260  /* Open connection */
261  if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress,
262  tftp_open->TFTPPort,
263  tftp_open->FileName,
264  tftp_open->PacketSize ) ) != 0 ) {
265  tftp_open->Status = PXENV_STATUS ( rc );
266  return PXENV_EXIT_FAILURE;
267  }
268 
269  /* Wait for OACK to arrive so that we have the block size */
270  while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
271  ( pxe_tftp.max_offset == 0 ) ) {
272  step();
273  }
275  tftp_open->PacketSize = pxe_tftp.blksize;
276  DBG ( " blksize=%d", tftp_open->PacketSize );
277 
278  /* EINPROGRESS is normal; we don't wait for the whole transfer */
279  if ( rc == -EINPROGRESS )
280  rc = 0;
281 
282  tftp_open->Status = PXENV_STATUS ( rc );
284 }
285 
286 /**
287  * TFTP CLOSE
288  *
289  * @v tftp_close Pointer to a struct s_PXENV_TFTP_CLOSE
290  * @ret #PXENV_EXIT_SUCCESS File was closed successfully
291  * @ret #PXENV_EXIT_FAILURE File was not closed
292  * @ret s_PXENV_TFTP_CLOSE::Status PXE status code
293  * @err None -
294  *
295  * Close a connection previously opened with pxenv_tftp_open(). You
296  * must have previously opened a connection with pxenv_tftp_open().
297  *
298  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
299  * value before calling this function in protected mode. You cannot
300  * call this function with a 32-bit stack segment. (See the relevant
301  * @ref pxe_x86_pmode16 "implementation note" for more details.)
302  */
304  DBG ( "PXENV_TFTP_CLOSE" );
305 
306  pxe_tftp_close ( &pxe_tftp, 0 );
308  return PXENV_EXIT_SUCCESS;
309 }
310 
311 /**
312  * TFTP READ
313  *
314  * @v tftp_read Pointer to a struct s_PXENV_TFTP_READ
315  * @v s_PXENV_TFTP_READ::Buffer Address of data buffer
316  * @ret #PXENV_EXIT_SUCCESS Data was read successfully
317  * @ret #PXENV_EXIT_FAILURE Data was not read
318  * @ret s_PXENV_TFTP_READ::Status PXE status code
319  * @ret s_PXENV_TFTP_READ::PacketNumber TFTP packet number
320  * @ret s_PXENV_TFTP_READ::BufferSize Length of data written into buffer
321  *
322  * Reads a single packet from a connection previously opened with
323  * pxenv_tftp_open() into the data buffer pointed to by
324  * s_PXENV_TFTP_READ::Buffer. You must have previously opened a
325  * connection with pxenv_tftp_open(). The data written into
326  * s_PXENV_TFTP_READ::Buffer is just the file data; the various
327  * network headers have already been removed.
328  *
329  * The buffer must be large enough to contain a packet of the size
330  * negotiated via the s_PXENV_TFTP_OPEN::PacketSize field in the
331  * pxenv_tftp_open() call. It is worth noting that the PXE
332  * specification does @b not require the caller to fill in
333  * s_PXENV_TFTP_READ::BufferSize before calling pxenv_tftp_read(), so
334  * the PXE stack is free to ignore whatever value the caller might
335  * place there and just assume that the buffer is large enough. That
336  * said, it may be worth the caller always filling in
337  * s_PXENV_TFTP_READ::BufferSize to guard against PXE stacks that
338  * mistake it for an input parameter.
339  *
340  * The length of the TFTP data packet will be returned via
341  * s_PXENV_TFTP_READ::BufferSize. If this length is less than the
342  * blksize negotiated via s_PXENV_TFTP_OPEN::PacketSize in the call to
343  * pxenv_tftp_open(), this indicates that the block is the last block
344  * in the file. Note that zero is a valid length for
345  * s_PXENV_TFTP_READ::BufferSize, and will occur when the length of
346  * the file is a multiple of the blksize.
347  *
348  * The PXE specification doesn't actually state that calls to
349  * pxenv_tftp_read() will return the data packets in strict sequential
350  * order, though most PXE stacks will probably do so. The sequence
351  * number of the packet will be returned in
352  * s_PXENV_TFTP_READ::PacketNumber. The first packet in the file has
353  * a sequence number of one, not zero.
354  *
355  * To guard against flawed PXE stacks, the caller should probably set
356  * s_PXENV_TFTP_READ::PacketNumber to one less than the expected
357  * returned value (i.e. set it to zero for the first call to
358  * pxenv_tftp_read() and then re-use the returned s_PXENV_TFTP_READ
359  * parameter block for subsequent calls without modifying
360  * s_PXENV_TFTP_READ::PacketNumber between calls). The caller should
361  * also guard against potential problems caused by flawed
362  * implementations returning the occasional duplicate packet, by
363  * checking that the value returned in s_PXENV_TFTP_READ::PacketNumber
364  * is as expected (i.e. one greater than that returned from the
365  * previous call to pxenv_tftp_read()).
366  *
367  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
368  * value before calling this function in protected mode. You cannot
369  * call this function with a 32-bit stack segment. (See the relevant
370  * @ref pxe_x86_pmode16 "implementation note" for more details.)
371  */
372 static PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read ) {
373  int rc;
374 
375  DBG ( "PXENV_TFTP_READ to %04x:%04x",
376  tftp_read->Buffer.segment, tftp_read->Buffer.offset );
377 
378  /* Read single block into buffer */
379  pxe_tftp.buffer = real_to_virt ( tftp_read->Buffer.segment,
380  tftp_read->Buffer.offset );
383  while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
384  ( pxe_tftp.offset == pxe_tftp.start ) )
385  step();
386  pxe_tftp.buffer = NULL;
387  tftp_read->BufferSize = ( pxe_tftp.offset - pxe_tftp.start );
388  tftp_read->PacketNumber = ++pxe_tftp.blkidx;
389 
390  /* EINPROGRESS is normal if we haven't reached EOF yet */
391  if ( rc == -EINPROGRESS )
392  rc = 0;
393 
394  tftp_read->Status = PXENV_STATUS ( rc );
396 }
397 
398 /**
399  * TFTP/MTFTP read file
400  *
401  * @v tftp_read_file Pointer to a struct s_PXENV_TFTP_READ_FILE
402  * @v s_PXENV_TFTP_READ_FILE::FileName File name
403  * @v s_PXENV_TFTP_READ_FILE::BufferSize Size of the receive buffer
404  * @v s_PXENV_TFTP_READ_FILE::Buffer Address of the receive buffer
405  * @v s_PXENV_TFTP_READ_FILE::ServerIPAddress TFTP server IP address
406  * @v s_PXENV_TFTP_READ_FILE::GatewayIPAddress Relay agent IP address
407  * @v s_PXENV_TFTP_READ_FILE::McastIPAddress File's multicast IP address
408  * @v s_PXENV_TFTP_READ_FILE::TFTPClntPort Client multicast UDP port
409  * @v s_PXENV_TFTP_READ_FILE::TFTPSrvPort Server multicast UDP port
410  * @v s_PXENV_TFTP_READ_FILE::TFTPOpenTimeOut Time to wait for first packet
411  * @v s_PXENV_TFTP_READ_FILE::TFTPReopenDelay MTFTP inactivity timeout
412  * @ret #PXENV_EXIT_SUCCESS File downloaded successfully
413  * @ret #PXENV_EXIT_FAILURE File not downloaded
414  * @ret s_PXENV_TFTP_READ_FILE::Status PXE status code
415  * @ret s_PXENV_TFTP_READ_FILE::BufferSize Length of downloaded file
416  *
417  * Downloads an entire file via either TFTP or MTFTP into the buffer
418  * pointed to by s_PXENV_TFTP_READ_FILE::Buffer.
419  *
420  * The PXE specification does not make it clear how the caller
421  * requests that MTFTP be used rather than TFTP (or vice versa). One
422  * reasonable guess is that setting
423  * s_PXENV_TFTP_READ_FILE::McastIPAddress to 0.0.0.0 would cause TFTP
424  * to be used instead of MTFTP, though it is conceivable that some PXE
425  * stacks would interpret that as "use the DHCP-provided multicast IP
426  * address" instead. Some PXE stacks will not implement MTFTP at all,
427  * and will always use TFTP.
428  *
429  * It is not specified whether or not
430  * s_PXENV_TFTP_READ_FILE::TFTPSrvPort will be used as the TFTP server
431  * port for TFTP (rather than MTFTP) downloads. Callers should assume
432  * that the only way to access a TFTP server on a non-standard port is
433  * to use pxenv_tftp_open() and pxenv_tftp_read().
434  *
435  * If s_PXENV_TFTP_READ_FILE::GatewayIPAddress is 0.0.0.0, normal IP
436  * routing will take place. See the relevant
437  * @ref pxe_routing "implementation note" for more details.
438  *
439  * It is interesting to note that s_PXENV_TFTP_READ_FILE::Buffer is an
440  * #ADDR32_t type, i.e. nominally a flat physical address. Some PXE
441  * NBPs (e.g. NTLDR) are known to call pxenv_tftp_read_file() in real
442  * mode with s_PXENV_TFTP_READ_FILE::Buffer set to an address above
443  * 1MB. This means that PXE stacks must be prepared to write to areas
444  * outside base memory. Exactly how this is to be achieved is not
445  * specified, though using INT 15,87 is as close to a standard method
446  * as any, and should probably be used. Switching to protected-mode
447  * in order to access high memory will fail if pxenv_tftp_read_file()
448  * is called in V86 mode; it is reasonably to expect that a V86
449  * monitor would intercept the relatively well-defined INT 15,87 if it
450  * wants the PXE stack to be able to write to high memory.
451  *
452  * Things get even more interesting if pxenv_tftp_read_file() is
453  * called in protected mode, because there is then absolutely no way
454  * for the PXE stack to write to an absolute physical address. You
455  * can't even get around the problem by creating a special "access
456  * everything" segment in the s_PXE data structure, because the
457  * #SEGDESC_t descriptors are limited to 64kB in size.
458  *
459  * Previous versions of the PXE specification (e.g. WfM 1.1a) provide
460  * a separate API call, %pxenv_tftp_read_file_pmode(), specifically to
461  * work around this problem. The s_PXENV_TFTP_READ_FILE_PMODE
462  * parameter block splits s_PXENV_TFTP_READ_FILE::Buffer into
463  * s_PXENV_TFTP_READ_FILE_PMODE::BufferSelector and
464  * s_PXENV_TFTP_READ_FILE_PMODE::BufferOffset, i.e. it provides a
465  * protected-mode segment:offset address for the data buffer. This
466  * API call is no longer present in version 2.1 of the PXE
467  * specification.
468  *
469  * Etherboot makes the assumption that s_PXENV_TFTP_READ_FILE::Buffer
470  * is an offset relative to the caller's data segment, when
471  * pxenv_tftp_read_file() is called in protected mode.
472  *
473  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
474  * value before calling this function in protected mode. You cannot
475  * call this function with a 32-bit stack segment. (See the relevant
476  * @ref pxe_x86_pmode16 "implementation note" for more details.)
477  */
479  *tftp_read_file ) {
480  int rc;
481 
482  DBG ( "PXENV_TFTP_READ_FILE to %08x+%x", tftp_read_file->Buffer,
483  tftp_read_file->BufferSize );
484 
485  /* Open TFTP file */
486  if ( ( rc = pxe_tftp_open ( tftp_read_file->ServerIPAddress, 0,
487  tftp_read_file->FileName, 0 ) ) != 0 ) {
488  tftp_read_file->Status = PXENV_STATUS ( rc );
489  return PXENV_EXIT_FAILURE;
490  }
491 
492  /* Read entire file */
493  pxe_tftp.buffer = phys_to_virt ( tftp_read_file->Buffer );
494  pxe_tftp.size = tftp_read_file->BufferSize;
495  while ( ( rc = pxe_tftp.rc ) == -EINPROGRESS )
496  step();
497  pxe_tftp.buffer = NULL;
498  tftp_read_file->BufferSize = pxe_tftp.max_offset;
499 
500  /* Close TFTP file */
501  pxe_tftp_close ( &pxe_tftp, rc );
502 
503  tftp_read_file->Status = PXENV_STATUS ( rc );
505 }
506 
507 /**
508  * TFTP GET FILE SIZE
509  *
510  * @v tftp_get_fsize Pointer to a struct s_PXENV_TFTP_GET_FSIZE
511  * @v s_PXENV_TFTP_GET_FSIZE::ServerIPAddress TFTP server IP address
512  * @v s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress Relay agent IP address
513  * @v s_PXENV_TFTP_GET_FSIZE::FileName File name
514  * @ret #PXENV_EXIT_SUCCESS File size was determined successfully
515  * @ret #PXENV_EXIT_FAILURE File size was not determined
516  * @ret s_PXENV_TFTP_GET_FSIZE::Status PXE status code
517  * @ret s_PXENV_TFTP_GET_FSIZE::FileSize File size
518  *
519  * Determine the size of a file on a TFTP server. This uses the
520  * "tsize" TFTP option, and so will not work with a TFTP server that
521  * does not support TFTP options, or that does not support the "tsize"
522  * option.
523  *
524  * The PXE specification states that this API call will @b not open a
525  * TFTP connection for subsequent use with pxenv_tftp_read(). (This
526  * is somewhat daft, since the only way to obtain the file size via
527  * the "tsize" option involves issuing a TFTP open request, but that's
528  * life.)
529  *
530  * You cannot call pxenv_tftp_get_fsize() while a TFTP or UDP
531  * connection is open.
532  *
533  * If s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress is 0.0.0.0, normal IP
534  * routing will take place. See the relevant
535  * @ref pxe_routing "implementation note" for more details.
536  *
537  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
538  * value before calling this function in protected mode. You cannot
539  * call this function with a 32-bit stack segment. (See the relevant
540  * @ref pxe_x86_pmode16 "implementation note" for more details.)
541  *
542  * @note There is no way to specify the TFTP server port with this API
543  * call. Though you can open a file using a non-standard TFTP server
544  * port (via s_PXENV_TFTP_OPEN::TFTPPort or, potentially,
545  * s_PXENV_TFTP_READ_FILE::TFTPSrvPort), you can only get the size of
546  * a file from a TFTP server listening on the standard TFTP port.
547  * "Consistency" is not a word in Intel's vocabulary.
548  */
550  *tftp_get_fsize ) {
551  int rc;
552 
553  DBG ( "PXENV_TFTP_GET_FSIZE" );
554 
555  /* Open TFTP file */
556  if ( ( rc = pxe_tftp_open ( tftp_get_fsize->ServerIPAddress, 0,
557  tftp_get_fsize->FileName, 0 ) ) != 0 ) {
558  tftp_get_fsize->Status = PXENV_STATUS ( rc );
559  return PXENV_EXIT_FAILURE;
560  }
561 
562  /* Wait for initial seek to arrive, and record size */
563  while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
564  ( pxe_tftp.max_offset == 0 ) ) {
565  step();
566  }
567  tftp_get_fsize->FileSize = pxe_tftp.max_offset;
568  DBG ( " fsize=%d", tftp_get_fsize->FileSize );
569 
570  /* EINPROGRESS is normal; we don't wait for the whole transfer */
571  if ( rc == -EINPROGRESS )
572  rc = 0;
573 
574  /* Close TFTP file */
575  pxe_tftp_close ( &pxe_tftp, rc );
576 
577  tftp_get_fsize->Status = PXENV_STATUS ( rc );
579 }
580 
581 /** PXE TFTP API */
582 struct pxe_api_call pxe_tftp_api[] __pxe_api_call = {
584  struct s_PXENV_TFTP_OPEN ),
586  struct s_PXENV_TFTP_CLOSE ),
588  struct s_PXENV_TFTP_READ ),
590  struct s_PXENV_TFTP_READ_FILE ),
592  struct s_PXENV_TFTP_GET_FSIZE ),
593 };
UINT16_t PacketNumber
TFTP packet number.
Definition: pxe_api.h:625
struct pxe_api_call pxe_tftp_api [] __pxe_api_call
PXE TFTP API.
Definition: pxe_tftp.c:582
An object interface operation.
Definition: interface.h:17
static int pxe_tftp_open(IP4_t ipaddress, UDP_PORT_t port, UINT8_t *filename, UINT16_t blksize)
Open PXE TFTP connection.
Definition: pxe_tftp.c:169
IP4_t ServerIPAddress
TFTP server IP address.
Definition: pxe_api.h:650
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
Data transfer metadata.
Definition: xfer.h:22
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
#define PXENV_EXIT_FAILURE
An error occurred.
Definition: pxe_types.h:46
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:47
Error codes.
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition: uri.c:808
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition: interface.h:217
Parameter block for pxenv_tftp_read()
Definition: pxe_api.h:623
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:67
#define PXENV_TFTP_READ
PXE API function code for pxenv_tftp_read()
Definition: pxe_api.h:620
IPv4 socket address.
Definition: in.h:84
PXENV_EXIT_t pxenv_tftp_read_file(struct s_PXENV_TFTP_READ_FILE *tftp_read_file)
TFTP/MTFTP read file.
Definition: pxe_tftp.c:478
#define ntohs(value)
Definition: byteswap.h:136
size_t size
Size of data buffer.
Definition: pxe_tftp.c:53
static size_t pxe_tftp_xfer_window(struct pxe_tftp_connection *pxe_tftp)
Check flow control window.
Definition: pxe_tftp.c:85
Uniform Resource Identifiers.
unsigned int blkidx
Block index.
Definition: pxe_tftp.c:63
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
PXENV_STATUS_t Status
PXE status code.
Definition: pxe_api.h:624
UINT32_t BufferSize
Size of data buffer.
Definition: pxe_api.h:648
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition: realmode.h:77
#define PXE_API_CALL(_opcode, _entry, _params_type)
Define a PXE API call.
Definition: pxe.h:106
Data transfer interfaces.
UINT16_t BufferSize
Size of data buffer.
Definition: pxe_api.h:626
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct interface_descriptor pxe_tftp_xfer_desc
PXE TFTP connection interface descriptor.
Definition: pxe_tftp.c:152
UINT16_t PXENV_EXIT_t
A PXE exit code.
Definition: pxe_types.h:44
u8 port
Port number.
Definition: CIB_PRM.h:31
IP4_t ServerIPAddress
TFTP server IP address.
Definition: pxe_api.h:690
UINT8_t FileName[128]
File name.
Definition: pxe_api.h:647
#define PXENV_TFTP_READ_FILE
PXE API function code for pxenv_tftp_read_file()
Definition: pxe_api.h:642
An object interface.
Definition: interface.h:124
struct interface xfer
Data transfer interface.
Definition: pxe_tftp.c:49
static int tftp_open(struct interface *xfer, struct uri *uri)
Initiate TFTP download.
Definition: tftp.c:1148
UINT16_t UDP_PORT_t
A UDP port.
Definition: pxe_types.h:67
ring len
Length.
Definition: dwmac.h:231
uint8_t UINT8_t
An 8-bit unsigned integer.
Definition: pxe_types.h:31
struct sockaddr sa
Definition: syslog.c:56
static void pxe_tftp_close(struct pxe_tftp_connection *pxe_tftp, int rc)
Close PXE TFTP connection.
Definition: pxe_tftp.c:74
size_t max_offset
Maximum file position.
Definition: pxe_tftp.c:59
static struct pxe_tftp_connection pxe_tftp
The PXE TFTP connection.
Definition: pxe_tftp.c:156
Parameter block for pxenv_tftp_get_fsize()
Definition: pxe_api.h:688
static void tftp_close(struct tftp_request *tftp, int rc)
Terminate download.
Definition: tftp.c:1060
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
Generalized socket address structure.
Definition: socket.h:96
void * buffer
Data buffer.
Definition: pxe_tftp.c:51
An object interface descriptor.
Definition: interface.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define PXENV_TFTP_OPEN
PXE API function code for pxenv_tftp_open()
Definition: pxe_api.h:571
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
TFTP protocol.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
UINT8_t FileName[128]
File name.
Definition: pxe_api.h:692
static int pxe_tftp_xfer_deliver(struct pxe_tftp_connection *pxe_tftp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
Definition: pxe_tftp.c:98
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
int rc
Overall return status code.
Definition: pxe_tftp.c:65
Processes.
Data transfer interface opening.
Parameter block for pxenv_tftp_close()
Definition: pxe_api.h:604
PXENV_STATUS_t Status
PXE status code.
Definition: pxe_api.h:646
#define PXENV_EXIT_SUCCESS
No error occurred.
Definition: pxe_types.h:45
#define PXENV_TFTP_CLOSE
PXE API function code for pxenv_tftp_close()
Definition: pxe_api.h:601
PXENV_STATUS_t Status
PXE status code.
Definition: pxe_api.h:689
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
Definition: socket.c:42
size_t start
Starting offset of data buffer.
Definition: pxe_tftp.c:55
A PXE API call.
Definition: pxe.h:81
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
uint16_t UINT16_t
A 16-bit unsigned integer.
Definition: pxe_types.h:34
void * data
Start of data.
Definition: iobuf.h:52
void step(void)
Single-step a single process.
Definition: process.c:98
Parameter block for pxenv_tftp_read_file()
Definition: pxe_api.h:645
UINT32_t FileSize
Size of the file.
Definition: pxe_api.h:693
Parameter block for pxenv_tftp_open()
Definition: pxe_api.h:574
#define TFTP_DEFAULT_BLKSIZE
Default TFTP data block size.
Definition: tftp.h:15
ADDR32_t Buffer
Address of data buffer.
Definition: pxe_api.h:649
#define PXENV_TFTP_GET_FSIZE
PXE API function code for pxenv_tftp_get_fsize()
Definition: pxe_api.h:685
SEGOFF16_t Buffer
Address of data buffer.
Definition: pxe_api.h:627
A Uniform Resource Identifier.
Definition: uri.h:64
uint32_t blksize
Cipher block size.
Definition: pccrr.h:14
static PXENV_EXIT_t pxenv_tftp_read(struct s_PXENV_TFTP_READ *tftp_read)
TFTP READ.
Definition: pxe_tftp.c:372
static PXENV_EXIT_t pxenv_tftp_close(struct s_PXENV_TFTP_CLOSE *tftp_close)
TFTP CLOSE.
Definition: pxe_tftp.c:303
UINT32_t IP4_t
An IPv4 address.
Definition: pxe_types.h:60
static PXENV_EXIT_t pxenv_tftp_open(struct s_PXENV_TFTP_OPEN *tftp_open)
TFTP OPEN.
Definition: pxe_tftp.c:252
struct sockaddr_in sin
Definition: syslog.c:58
uint8_t meta
Metadata flags.
Definition: ena.h:14
#define PXENV_STATUS_SUCCESS
Definition: pxe_error.h:19
static PXENV_EXIT_t pxenv_tftp_get_fsize(struct s_PXENV_TFTP_GET_FSIZE *tftp_get_fsize)
TFTP GET FILE SIZE.
Definition: pxe_tftp.c:549
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
A PXE TFTP connection.
Definition: pxe_tftp.c:47
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct interface_operation pxe_tftp_xfer_ops[]
PXE TFTP connection interface operations.
Definition: pxe_tftp.c:143
#define PXENV_STATUS(rc)
Derive PXENV_STATUS code from iPXE error number.
Definition: pxe_error.h:121
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
size_t blksize
Block size.
Definition: pxe_tftp.c:61
size_t offset
File position.
Definition: pxe_tftp.c:57
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:37