Documented remainder of PXE TFTP API calls.
[people/xl0/gpxe.git] / src / interface / pxe / pxe_tftp.c
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., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "pxe.h"
26
27 static int pxe_tftp_read_block ( unsigned char *data, unsigned int block,
28                                  unsigned int len, int eof );
29
30 /**
31  * TFTP OPEN
32  *
33  * @v tftp_open                         Pointer to a struct s_PXENV_TFTP_OPEN
34  * @v s_PXENV_TFTP_OPEN::ServerIPAddress TFTP server IP address
35  * @v s_PXENV_TFTP_OPEN::GatewayIPAddress Relay agent IP address, or 0.0.0.0
36  * @v s_PXENV_TFTP_OPEN::FileName       Name of file to open
37  * @v s_PXENV_TFTP_OPEN::TFTPPort       TFTP server UDP port
38  * @v s_PXENV_TFTP_OPEN::PacketSize     TFTP blksize option to request
39  * @ret #PXENV_EXIT_SUCCESS             File was opened
40  * @ret #PXENV_EXIT_FAILURE             File was not opened
41  * @ret s_PXENV_TFTP_OPEN::Status       PXE status code
42  * @ret s_PXENV_TFTP_OPEN::PacketSize   Negotiated blksize
43  * @err #PXENV_STATUS_TFTP_INVALID_PACKET_SIZE Requested blksize too small
44  *
45  * Opens a TFTP connection for downloading a file a block at a time
46  * using pxenv_tftp_read().
47  *
48  * If s_PXENV_TFTP_OPEN::GatewayIPAddress is 0.0.0.0, normal IP
49  * routing will take place.  See the relevant
50  * @ref pxe_routing "implementation note" for more details.
51  *
52  * The blksize negotiated with the TFTP server will be returned in
53  * s_PXENV_TFTP_OPEN::PacketSize, and will be the size of data blocks
54  * returned by subsequent calls to pxenv_tftp_read().  The TFTP server
55  * may negotiate a smaller blksize than the caller requested.
56  *
57  * Some TFTP servers do not support TFTP options, and will therefore
58  * not be able to use anything other than a fixed 512-byte blksize.
59  * The PXE specification version 2.1 requires that the caller must
60  * pass in s_PXENV_TFTP_OPEN::PacketSize with a value of 512 or
61  * greater.
62  *
63  * You can only have one TFTP connection open at a time, because the
64  * PXE API requires the PXE stack to keep state (e.g. local and remote
65  * port numbers, data block index) about the open TFTP connection,
66  * rather than letting the caller do so.
67  *
68  * It is unclear precisely what constitutes a "TFTP open" operation.
69  * Clearly, we must send the TFTP open request to the server.  Since
70  * we must know whether or not the open succeeded, we must wait for
71  * the first reply packet from the TFTP server.  If the TFTP server
72  * supports options, the first reply packet will be an OACK; otherwise
73  * it will be a DATA packet.  In other words, we may only get to
74  * discover whether or not the open succeeded when we receive the
75  * first block of data.  However, the pxenv_tftp_open() API provides
76  * no way for us to return this block of data at this time.  See the
77  * relevant @ref pxe_note_tftp "implementation note" for Etherboot's
78  * solution to this problem.
79  *
80  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
81  * value before calling this function in protected mode.  You cannot
82  * call this function with a 32-bit stack segment.  (See the relevant
83  * @ref pxe_x86_pmode16 "implementation note" for more details.)
84  * 
85  * @note If you pass in a value less than 512 for
86  * s_PXENV_TFTP_OPEN::PacketSize, Etherboot will attempt to negotiate
87  * this blksize with the TFTP server, even though such a value is not
88  * permitted according to the PXE specification.  If the TFTP server
89  * ends up dictating a blksize larger than the value requested by the
90  * caller (which is very probable in the case of a requested blksize
91  * less than 512), then Etherboot will return the error
92  * #PXENV_STATUS_TFTP_INVALID_PACKET_SIZE.
93  *
94  * @note According to the PXE specification version 2.1, this call
95  * "opens a file for reading/writing", though how writing is to be
96  * achieved without the existence of an API call %pxenv_tftp_write()
97  * is not made clear.
98  *
99  * @note Despite the existence of the numerous statements within the
100  * PXE specification of the form "...if a TFTP/MTFTP or UDP connection
101  * is active...", you cannot use pxenv_tftp_open() and
102  * pxenv_tftp_read() to read a file via MTFTP; only via plain old
103  * TFTP.  If you want to use MTFTP, use pxenv_tftp_read_file()
104  * instead.  Astute readers will note that, since
105  * pxenv_tftp_read_file() is an atomic operation from the point of
106  * view of the PXE API, it is conceptually impossible to issue any
107  * other PXE API call "if an MTFTP connection is active".
108  */
109 PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) {
110         struct sockaddr_in tftp_server;
111         struct tftpreq_info_t request;
112         struct tftpblk_info_t block;
113
114         DBG ( "PXENV_TFTP_OPEN" );
115         ENSURE_READY ( tftp_open );
116
117         /* Set server address and port */
118         tftp_server.sin_addr.s_addr = tftp_open->ServerIPAddress
119                 ? tftp_open->ServerIPAddress
120                 : arptable[ARP_SERVER].ipaddr.s_addr;
121         tftp_server.sin_port = ntohs ( tftp_open->TFTPPort );
122 #ifdef WORK_AROUND_BPBATCH_BUG        
123         /* Force use of port 69; BpBatch tries to use port 4 for some         
124         * bizarre reason.         */        
125         tftp_server.sin_port = TFTP_PORT;
126 #endif
127         /* Ignore gateway address; we can route properly */
128         /* Fill in request structure */
129         request.server = &tftp_server;
130         request.name = tftp_open->FileName;
131         request.blksize = tftp_open->PacketSize;
132         DBG ( " %@:%d/%s (%d)", tftp_open->ServerIPAddress,
133               tftp_open->TFTPPort, request.name, request.blksize );
134         if ( !request.blksize ) request.blksize = TFTP_DEFAULTSIZE_PACKET;
135         /* Make request and get first packet */
136         if ( !tftp_block ( &request, &block ) ) {
137                 tftp_open->Status = PXENV_STATUS_TFTP_FILE_NOT_FOUND;
138                 return PXENV_EXIT_FAILURE;
139         }
140         /* Fill in PacketSize */
141         tftp_open->PacketSize = request.blksize;
142         /* Store first block for later retrieval by TFTP_READ */
143         pxe_stack->tftpdata.magic_cookie = PXE_TFTP_MAGIC_COOKIE;
144         pxe_stack->tftpdata.len = block.len;
145         pxe_stack->tftpdata.eof = block.eof;
146         memcpy ( pxe_stack->tftpdata.data, block.data, block.len );
147
148         tftp_open->Status = PXENV_STATUS_SUCCESS;
149         return PXENV_EXIT_SUCCESS;
150 }
151
152 /**
153  * TFTP CLOSE
154  *
155  * @v tftp_close                        Pointer to a struct s_PXENV_TFTP_CLOSE
156  * @ret #PXENV_EXIT_SUCCESS             File was closed successfully
157  * @ret #PXENV_EXIT_FAILURE             File was not closed
158  * @ret s_PXENV_TFTP_CLOSE::Status      PXE status code
159  * @err None                            -
160  *
161  * Close a connection previously opened with pxenv_tftp_open().  You
162  * must have previously opened a connection with pxenv_tftp_open().
163  *
164  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
165  * value before calling this function in protected mode.  You cannot
166  * call this function with a 32-bit stack segment.  (See the relevant
167  * @ref pxe_x86_pmode16 "implementation note" for more details.)
168  *
169  * @note Since TFTP runs over UDP, which is a connectionless protocol,
170  * the concept of closing a file is somewhat meaningless.  This call
171  * is a no-op for Etherboot.
172  */
173 PXENV_EXIT_t pxenv_tftp_close ( struct s_PXENV_TFTP_CLOSE *tftp_close ) {
174         DBG ( "PXENV_TFTP_CLOSE" );
175         ENSURE_READY ( tftp_close );
176         tftp_close->Status = PXENV_STATUS_SUCCESS;
177         return PXENV_EXIT_SUCCESS;
178 }
179
180 /**
181  * TFTP READ
182  *
183  * @v tftp_read                         Pointer to a struct s_PXENV_TFTP_READ
184  * @v s_PXENV_TFTP_READ::Buffer         Address of data buffer
185  * @ret #PXENV_EXIT_SUCCESS             Data was read successfully
186  * @ret #PXENV_EXIT_FAILURE             Data was not read
187  * @ret s_PXENV_TFTP_READ::Status       PXE status code
188  * @ret s_PXENV_TFTP_READ::PacketNumber TFTP packet number
189  * @ret s_PXENV_TFTP_READ::BufferSize   Length of data written into buffer
190  *
191  * Reads a single packet from a connection previously opened with
192  * pxenv_tftp_open() into the data buffer pointed to by
193  * s_PXENV_TFTP_READ::Buffer.  You must have previously opened a
194  * connection with pxenv_tftp_open().  The data written into
195  * s_PXENV_TFTP_READ::Buffer is just the file data; the various
196  * network headers have already been removed.
197  *
198  * The buffer must be large enough to contain a packet of the size
199  * negotiated via the s_PXENV_TFTP_OPEN::PacketSize field in the
200  * pxenv_tftp_open() call.  It is worth noting that the PXE
201  * specification does @b not require the caller to fill in
202  * s_PXENV_TFTP_READ::BufferSize before calling pxenv_tftp_read(), so
203  * the PXE stack is free to ignore whatever value the caller might
204  * place there and just assume that the buffer is large enough.  That
205  * said, it may be worth the caller always filling in
206  * s_PXENV_TFTP_READ::BufferSize to guard against PXE stacks that
207  * mistake it for an input parameter.
208  *
209  * The length of the TFTP data packet will be returned via
210  * s_PXENV_TFTP_READ::BufferSize.  If this length is less than the
211  * blksize negotiated via s_PXENV_TFTP_OPEN::PacketSize in the call to
212  * pxenv_tftp_open(), this indicates that the block is the last block
213  * in the file.  Note that zero is a valid length for
214  * s_PXENV_TFTP_READ::BufferSize, and will occur when the length of
215  * the file is a multiple of the blksize.
216  *
217  * The PXE specification doesn't actually state that calls to
218  * pxenv_tftp_read() will return the data packets in strict sequential
219  * order, though most PXE stacks will probably do so.  The sequence
220  * number of the packet will be returned in
221  * s_PXENV_TFTP_READ::PacketNumber.  The first packet in the file has
222  * a sequence number of one, not zero.
223  *
224  * To guard against flawed PXE stacks, the caller should probably set
225  * s_PXENV_TFTP_READ::PacketNumber to one less than the expected
226  * returned value (i.e. set it to zero for the first call to
227  * pxenv_tftp_read() and then re-use the returned s_PXENV_TFTP_READ
228  * parameter block for subsequent calls without modifying
229  * s_PXENV_TFTP_READ::PacketNumber between calls).  The caller should
230  * also guard against potential problems caused by flawed
231  * implementations returning the occasional duplicate packet, by
232  * checking that the value returned in s_PXENV_TFTP_READ::PacketNumber
233  * is as expected (i.e. one greater than that returned from the
234  * previous call to pxenv_tftp_read()).
235  *
236  * Nothing in the PXE specification indicates when the TFTP
237  * acknowledgement packets will be sent back to the server.  See the
238  * relevant @ref pxe_note_tftp "implementation note" for details on
239  * when Etherboot chooses to send these packets.
240  *
241  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
242  * value before calling this function in protected mode.  You cannot
243  * call this function with a 32-bit stack segment.  (See the relevant
244  * @ref pxe_x86_pmode16 "implementation note" for more details.)
245  */
246 PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read ) {
247         struct tftpblk_info_t block;
248
249         DBG ( "PXENV_TFTP_READ" );
250         ENSURE_READY ( tftp_read );
251
252         /* Do we have a block pending */
253         if ( pxe_stack->tftpdata.magic_cookie == PXE_TFTP_MAGIC_COOKIE ) {
254                 block.data = pxe_stack->tftpdata.data;
255                 block.len = pxe_stack->tftpdata.len;
256                 block.eof = pxe_stack->tftpdata.eof;
257                 block.block = 1; /* Will be the first block */
258                 pxe_stack->tftpdata.magic_cookie = 0;
259         } else {
260                 if ( !tftp_block ( NULL, &block ) ) {
261                         tftp_read->Status = PXENV_STATUS_TFTP_FILE_NOT_FOUND;
262                         return PXENV_EXIT_FAILURE;
263                 }
264         }
265
266         /* Return data */
267         tftp_read->PacketNumber = block.block;
268         tftp_read->BufferSize = block.len;
269         memcpy ( SEGOFF16_TO_PTR(tftp_read->Buffer), block.data, block.len );
270         DBG ( " %d to %hx:%hx", block.len, tftp_read->Buffer.segment,
271               tftp_read->Buffer.offset );
272  
273         tftp_read->Status = PXENV_STATUS_SUCCESS;
274         return PXENV_EXIT_SUCCESS;
275 }
276
277 /**
278  * TFTP/MTFTP read file
279  *
280  * @v tftp_read_file                 Pointer to a struct s_PXENV_TFTP_READ_FILE
281  * @v s_PXENV_TFTP_READ_FILE::FileName          File name
282  * @v s_PXENV_TFTP_READ_FILE::BufferSize        Size of the receive buffer
283  * @v s_PXENV_TFTP_READ_FILE::Buffer            Address of the receive buffer
284  * @v s_PXENV_TFTP_READ_FILE::ServerIPAddress   TFTP server IP address
285  * @v s_PXENV_TFTP_READ_FILE::GatewayIPAddress  Relay agent IP address
286  * @v s_PXENV_TFTP_READ_FILE::McastIPAddress    File's multicast IP address
287  * @v s_PXENV_TFTP_READ_FILE::TFTPClntPort      Client multicast UDP port
288  * @v s_PXENV_TFTP_READ_FILE::TFTPSrvPort       Server multicast UDP port
289  * @v s_PXENV_TFTP_READ_FILE::TFTPOpenTimeOut   Time to wait for first packet
290  * @v s_PXENV_TFTP_READ_FILE::TFTPReopenDelay   MTFTP inactivity timeout
291  * @ret #PXENV_EXIT_SUCCESS                     File downloaded successfully
292  * @ret #PXENV_EXIT_FAILURE                     File not downloaded
293  * @ret s_PXENV_TFTP_READ_FILE::Status          PXE status code
294  * @ret s_PXENV_TFTP_READ_FILE::BufferSize      Length of downloaded file
295  *
296  * Downloads an entire file via either TFTP or MTFTP into the buffer
297  * pointed to by s_PXENV_TFTP_READ_FILE::Buffer.
298  *
299  * The PXE specification does not make it clear how the caller
300  * requests that MTFTP be used rather than TFTP (or vice versa).  One
301  * reasonable guess is that setting
302  * s_PXENV_TFTP_READ_FILE::McastIPAddress to 0.0.0.0 would cause TFTP
303  * to be used instead of MTFTP, though it is conceivable that some PXE
304  * stacks would interpret that as "use the DHCP-provided multicast IP
305  * address" instead.  Some PXE stacks will not implement MTFTP at all,
306  * and will always use TFTP.
307  *
308  * It is not specified whether or not
309  * s_PXENV_TFTP_READ_FILE::TFTPSrvPort will be used as the TFTP server
310  * port for TFTP (rather than MTFTP) downloads.  Callers should assume
311  * that the only way to access a TFTP server on a non-standard port is
312  * to use pxenv_tftp_open() and pxenv_tftp_read().
313  *
314  * If s_PXENV_TFTP_READ_FILE::GatewayIPAddress is 0.0.0.0, normal IP
315  * routing will take place.  See the relevant
316  * @ref pxe_routing "implementation note" for more details.
317  *
318  * It is interesting to note that s_PXENV_TFTP_READ_FILE::Buffer is an
319  * #ADDR32_t type, i.e. nominally a flat physical address.  Some PXE
320  * NBPs (e.g. NTLDR) are known to call pxenv_tftp_read_file() in real
321  * mode with s_PXENV_TFTP_READ_FILE::Buffer set to an address above
322  * 1MB.  This means that PXE stacks must be prepared to write to areas
323  * outside base memory.  Exactly how this is to be achieved is not
324  * specified, though using INT 15,87 is as close to a standard method
325  * as any, and should probably be used.  Switching to protected-mode
326  * in order to access high memory will fail if pxenv_tftp_read_file()
327  * is called in V86 mode; it is reasonably to expect that a V86
328  * monitor would intercept the relatively well-defined INT 15,87 if it
329  * wants the PXE stack to be able to write to high memory.
330  *
331  * Things get even more interesting if pxenv_tftp_read_file() is
332  * called in protected mode, because there is then absolutely no way
333  * for the PXE stack to write to an absolute physical address.  You
334  * can't even get around the problem by creating a special "access
335  * everything" segment in the s_PXE data structure, because the
336  * #SEGDESC_t descriptors are limited to 64kB in size.
337  *
338  * Previous versions of the PXE specification (e.g. WfM 1.1a) provide
339  * a separate API call, %pxenv_tftp_read_file_pmode(), specifically to
340  * work around this problem.  The s_PXENV_TFTP_READ_FILE_PMODE
341  * parameter block splits s_PXENV_TFTP_READ_FILE::Buffer into
342  * s_PXENV_TFTP_READ_FILE_PMODE::BufferSelector and
343  * s_PXENV_TFTP_READ_FILE_PMODE::BufferOffset, i.e. it provides a
344  * protected-mode segment:offset address for the data buffer.  This
345  * API call is no longer present in version 2.1 of the PXE
346  * specification.
347  *
348  * Etherboot makes the assumption that s_PXENV_TFTP_READ_FILE::Buffer
349  * is an offset relative to the caller's data segment, when
350  * pxenv_tftp_read_file() is called in protected mode.
351  *
352  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
353  * value before calling this function in protected mode.  You cannot
354  * call this function with a 32-bit stack segment.  (See the relevant
355  * @ref pxe_x86_pmode16 "implementation note" for more details.)
356  *
357  * @note Microsoft's NTLDR assumes that the filename passed in via
358  * s_PXENV_TFTP_READ_FILE::FileName will be stored in the "file" field
359  * of the stored DHCPACK packet, whence it will be returned via any
360  * subsequent calls to pxenv_get_cached_info().  Though this is
361  * essentially a bug in the Intel PXE implementation (not, for once,
362  * in the specification!), it is a bug that Microsoft relies upon, and
363  * so we implement this bug-for-bug compatibility by overwriting the
364  * filename stored DHCPACK packet with the filename passed in
365  * s_PXENV_TFTP_READ_FILE::FileName.
366  *
367  */
368 PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE
369                                     *tftp_read_file ) {
370         struct sockaddr_in tftp_server;
371         int rc;
372
373         DBG ( "PXENV_TFTP_READ_FILE %s to [%x,%x)", tftp_read_file->FileName,
374               tftp_read_file->Buffer,
375               tftp_read_file->Buffer + tftp_read_file->BufferSize );
376         ENSURE_READY ( tftp_read_file );
377
378         /* inserted by Klaus Wittemeier */
379         /* KERNEL_BUF stores the name of the last required file */
380         /* This is a fix to make Microsoft Remote Install Services work (RIS) */
381         memcpy(KERNEL_BUF, tftp_read_file->FileName, sizeof(KERNEL_BUF));
382         /* end of insertion */
383
384         /* Set server address and port */
385         tftp_server.sin_addr.s_addr = tftp_read_file->ServerIPAddress
386                 ? tftp_read_file->ServerIPAddress
387                 : arptable[ARP_SERVER].ipaddr.s_addr;
388         tftp_server.sin_port = ntohs ( tftp_read_file->TFTPSrvPort );
389
390         pxe_stack->readfile.buffer = phys_to_virt ( tftp_read_file->Buffer );
391         pxe_stack->readfile.bufferlen = tftp_read_file->BufferSize;
392         pxe_stack->readfile.offset = 0;
393
394         rc = tftp ( NULL, &tftp_server, tftp_read_file->FileName,
395                     pxe_tftp_read_block );
396         if ( rc ) {
397                 tftp_read_file->Status = PXENV_STATUS_FAILURE;
398                 return PXENV_EXIT_FAILURE;
399         }
400         tftp_read_file->Status = PXENV_STATUS_SUCCESS;
401         return PXENV_EXIT_SUCCESS;
402 }
403
404 static int pxe_tftp_read_block ( unsigned char *data,
405                                  unsigned int block __unused,
406                                  unsigned int len, int eof ) {
407         if ( pxe_stack->readfile.buffer ) {
408                 if ( pxe_stack->readfile.offset + len >=
409                      pxe_stack->readfile.bufferlen ) return -1;
410                 memcpy ( pxe_stack->readfile.buffer +
411                          pxe_stack->readfile.offset, data, len );
412         }
413         pxe_stack->readfile.offset += len;
414         return eof ? 0 : 1;
415 }
416
417 /**
418  * TFTP GET FILE SIZE
419  *
420  * @v tftp_get_fsize                 Pointer to a struct s_PXENV_TFTP_GET_FSIZE
421  * @v s_PXENV_TFTP_GET_FSIZE::ServerIPAddress   TFTP server IP address
422  * @v s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress  Relay agent IP address
423  * @v s_PXENV_TFTP_GET_FSIZE::FileName  File name
424  * @ret #PXENV_EXIT_SUCCESS             File size was determined successfully
425  * @ret #PXENV_EXIT_FAILURE             File size was not determined
426  * @ret s_PXENV_TFTP_GET_FSIZE::Status  PXE status code
427  * @ret s_PXENV_TFTP_GET_FSIZE::FileSize        File size
428  *
429  * Determine the size of a file on a TFTP server.  This uses the
430  * "tsize" TFTP option, and so will not work with a TFTP server that
431  * does not support TFTP options, or that does not support the "tsize"
432  * option.
433  *
434  * The PXE specification states that this API call will @b not open a
435  * TFTP connection for subsequent use with pxenv_tftp_read().  (This
436  * is somewhat daft, since the only way to obtain the file size via
437  * the "tsize" option involves issuing a TFTP open request, but that's
438  * life.)
439  *
440  * You cannot call pxenv_tftp_get_fsize() while a TFTP or UDP
441  * connection is open.
442  *
443  * If s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress is 0.0.0.0, normal IP
444  * routing will take place.  See the relevant
445  * @ref pxe_routing "implementation note" for more details.
446  *
447  * On x86, you must set the s_PXE::StatusCallout field to a nonzero
448  * value before calling this function in protected mode.  You cannot
449  * call this function with a 32-bit stack segment.  (See the relevant
450  * @ref pxe_x86_pmode16 "implementation note" for more details.)
451  * 
452  * @note There is no way to specify the TFTP server port with this API
453  * call.  Though you can open a file using a non-standard TFTP server
454  * port (via s_PXENV_TFTP_OPEN::TFTPPort or, potentially,
455  * s_PXENV_TFTP_READ_FILE::TFTPSrvPort), you can only get the size of
456  * a file from a TFTP server listening on the standard TFTP port.
457  * "Consistency" is not a word in Intel's vocabulary.
458  */
459 PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE
460                                     *tftp_get_fsize ) {
461         int rc;
462
463         DBG ( "PXENV_TFTP_GET_FSIZE" );
464         ENSURE_READY ( tftp_get_fsize );
465
466         pxe_stack->readfile.buffer = NULL;
467         pxe_stack->readfile.bufferlen = 0;
468         pxe_stack->readfile.offset = 0;
469
470 #warning "Rewrite pxenv_tftp_get_fsize, please"
471         if ( rc ) {
472                 tftp_get_fsize->FileSize = 0;
473                 tftp_get_fsize->Status = PXENV_STATUS_FAILURE;
474                 return PXENV_EXIT_FAILURE;
475         }
476         tftp_get_fsize->FileSize = pxe_stack->readfile.offset;
477         tftp_get_fsize->Status = PXENV_STATUS_SUCCESS;
478         return PXENV_EXIT_SUCCESS;
479 }
480
481 /** @page pxe_notes Etherboot PXE implementation notes
482
483 @section pxe_note_tftp Welding together the TFTP protocol and the PXE TFTP API
484
485 The PXE TFTP API is fundamentally poorly designed; the TFTP protocol
486 simply does not map well into "open file", "read file block", "close
487 file" operations.  The problem is the unreliable nature of UDP
488 transmissions and the lock-step mechanism employed by TFTP to
489 guarantee file transfer.  The lock-step mechanism requires that if we
490 time out waiting for a packet to arrive, we must trigger its
491 retransmission by retransmitting our own previously transmitted
492 packet.
493
494 For example, suppose that pxenv_tftp_read() is called to read the
495 first data block of a file from a server that does not support TFTP
496 options, and that no data block is received within the timeout period.
497 In order to trigger the retransmission of this data block,
498 pxenv_tftp_read() must retransmit the TFTP open request.  However, the
499 information used to build the TFTP open request is not available at
500 this time; it was provided only to the pxenv_tftp_open() call.  Even
501 if we were able to retransmit a TFTP open request, we would have to
502 allocate a new local port number (and be prepared for data to arrive
503 from a new remote port number) in order to avoid violating the TFTP
504 protocol specification.
505
506 The question of when to transmit the ACK packets is also awkward.  At
507 a first glance, it would seem to be fairly simple: acknowledge a
508 packet immediately after receiving it.  However, since the ACK packet
509 may itself be lost, the next call to pxenv_tftp_read() must be
510 prepared to retransmit the acknowledgement.
511
512 Another problem to consider is that the pxenv_tftp_open() API call
513 must return an indication of whether or not the TFTP open request
514 succeeded.  In the case of a TFTP server that doesn't support TFTP
515 options, the only indication of a successful open is the reception of
516 the first data block.  However, the pxenv_tftp_open() API provides no
517 way to return this data block at this time.
518
519 At least some PXE stacks (e.g. NILO) solve this problem by violating
520 the TFTP protocol and never bothering with retransmissions, relying on
521 the TFTP server to retransmit when it times out waiting for an ACK.
522 This approach is dubious at best; if, for example, the initial TFTP
523 open request is lost then NILO will believe that it has opened the
524 file and will eventually time out and give up while waiting for the
525 first packet to arrive.
526
527 The only viable solution seems to be to allocate a buffer for the
528 storage of the first data packet returned by the TFTP server, since we
529 may receive this packet during the pxenv_tftp_open() call but have to
530 return it from the subsequent pxenv_tftp_read() call.  This buffer
531 must be statically allocated and must be dedicated to providing a
532 temporary home for TFTP packets.  There is nothing in the PXE
533 specification that prevents a caller from calling
534 e.g. pxenv_undi_transmit() between calls to the TFTP API, so we cannot
535 use the normal transmit/receive buffer for this purpose.
536
537 Having paid the storage penalty for this buffer, we can then gain some
538 simplicity by exploiting it in full.  There is at least one
539 circumstance (pxenv_tftp_open() called to open a file on a server that
540 does not support TFTP options) in which we will have to enter
541 pxenv_tftp_read() knowing that our previous transmission (the open
542 request, in this situation) has already been acknowledged.
543 Implementation of pxenv_tftp_read() can be made simpler by making this
544 condition an invariant.  Specifically, on each call to
545 pxenv_tftp_read(), we shall ensure that the following are true:
546
547   - Our previous transmission has already been acknowledged.  We
548     therefore do not need to keep state about our previous
549     transmission.
550
551   - The next packet to read is already in a buffer in memory.
552
553 In order to maintain these two conditions, pxenv_tftp_read() must do
554 the following:
555
556   - Copy the data packet from our buffer to the caller's buffer.
557
558   - Acknowledge the data packet that we have just copied.  This will
559     trigger transmission of the next packet from the server.
560
561   - Retransmit this acknowledgement packet until the next packet
562     arrives.
563
564   - Copy the packet into our internal buffer, ready for the next call
565     to pxenv_tftp_read().
566
567 It can be verified that this preserves the invariant condition, and it
568 is clear that the resulting implementation of pxenv_tftp_read() can be
569 relatively simple.  (For the special case of the last data packet,
570 pxenv_tftp_read() should return immediately after sending a single
571 acknowledgement packet.)
572
573 In order to set up this invariant condition for the first call to
574 pxenv_tftp_read(), pxenv_tftp_open() must do the following:
575
576   - Construct and transmit the TFTP open request.
577
578   - Retransmit the TFTP open request (using a new local port number as
579     necessary) until a response (DATA, OACK, or ERROR) is received.
580
581   - If the response is an OACK, acknowledge the OACK and retransmit
582     the acknowledgement until the first DATA packet arrives.
583
584   - If we have a DATA packet, store it in a buffer ready for the first
585     call to pxenv_tftp_read().
586
587 This approach has the advantage of being fully compliant with both
588 RFC1350 (TFTP) and RFC2347 (TFTP options).  It avoids unnecessary
589 retransmissions.  The cost is approximately 1500 bytes of
590 uninitialised storage.  Since there is demonstrably no way to avoid
591 paying this cost without either violating the protocol specifications
592 or introducing unnecessary retransmissions, we deem this to be a cost
593 worth paying.
594
595 A small performance gain may be obtained by adding a single extra
596 "send ACK" in both pxenv_tftp_open() and pxenv_tftp_read() immediately
597 after receiving the DATA packet and copying it into the internal
598 buffer.   The sequence of events for pxenv_tftp_read() then becomes:
599
600   - Copy the data packet from our buffer to the caller's buffer.
601
602   - If this was the last data packet, return immediately.
603
604   - Check to see if a TFTP data packet is waiting.  If not, send an
605     ACK for the data packet that we have just copied, and retransmit
606     this ACK until the next data packet arrives.
607
608   - Copy the packet into our internal buffer, ready for the next call
609     to pxenv_tftp_read().
610
611   - Send a single ACK for this data packet.
612
613 Sending the ACK at this point allows the server to transmit the next
614 data block while our caller is processing the current packet.  If this
615 ACK is lost, or the DATA packet it triggers is lost or is consumed by
616 something other than pxenv_tftp_read() (e.g. by calls to
617 pxenv_undi_isr()), then the next call to pxenv_tftp_read() will not
618 find a TFTP data packet waiting and will retransmit the ACK anyway.
619
620 Note to future API designers at Intel: try to understand the
621 underlying network protocol first!
622
623 */