Now have enough functions to implement a standard TFTP client in around 50
[people/xl0/gpxe.git] / src / proto / tftpcore.c
1 #include "tftp.h"
2 #include "tcp.h" /* for struct tcphdr */
3 #include "errno.h"
4 #include "etherboot.h"
5 #include "tftpcore.h"
6
7 /** @file
8  *
9  * TFTP core functions
10  *
11  * This file provides functions that are common to the TFTP (rfc1350),
12  * TFTM (rfc2090) and MTFTP (PXE) protocols.
13  *
14  */
15
16 /**
17  * Wait for a TFTP packet
18  *
19  * @v ptr                       Pointer to a struct tftp_state
20  * @v tftp_state::server::sin_addr TFTP server IP address
21  * @v tftp_state::client::sin_addr Client multicast IP address, or 0.0.0.0
22  * @v tftp_state::client::sin_port Client UDP port
23  * @v ip                        IP header
24  * @v udp                       UDP header
25  * @ret True                    This is our TFTP packet
26  * @ret False                   This is not one of our TFTP packets
27  *
28  * Wait for a TFTP packet that is part of the current connection
29  * (i.e. comes from the TFTP server, has the correct destination port,
30  * and is addressed either to our IP address or to our multicast
31  * listening address).
32  *
33  * Invoke await_tftp() using code such as
34  *
35  * @code
36  *
37  * if ( await_reply ( await_tftp, 0, &tftp_state, timeout ) ) {
38  *      ...
39  * }
40  *
41  * @endcode
42  */
43 int await_tftp ( int ival __unused, void *ptr, unsigned short ptype __unused,
44                  struct iphdr *ip, struct udphdr *udp,
45                  struct tcphdr *tcp __unused ) {
46         struct tftp_state *state = ptr;
47
48         /* Must have valid UDP (and, therefore, also IP) headers */
49         if ( ! udp ) {
50                 return 0;
51         }
52         /* Packet must come from the TFTP server */
53         if ( ip->src.s_addr != state->server.sin_addr.s_addr )
54                 return 0;
55         /* Packet must be addressed to the correct UDP port */
56         if ( ntohs ( udp->dest ) != state->client.sin_port )
57                 return 0;
58         /* Packet must be addressed to us, or to our multicast
59          * listening address (if we have one).
60          */
61         if ( ! ( ( ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr ) ||
62                  ( ( state->client.sin_addr.s_addr ) && 
63                    ( ip->dest.s_addr == state->client.sin_addr.s_addr ) ) ) )
64                 return 0;
65         return 1;
66 }
67
68
69 /**
70  * Issue a TFTP open request (RRQ)
71  *
72  * @v state                             TFTP transfer state
73  * @v tftp_state::server::sin_addr      TFTP server IP address
74  * @v tftp_state::server::sin_port      TFTP server UDP port, or 0
75  * @v tftp_state::client::sin_addr      Client multicast IP address, or 0.0.0.0
76  * @v tftp_state::client::sin_port      Client UDP port, or 0
77  * @v tftp_state::blksize               Requested blksize, or 0
78  * @v filename                          File name
79  * @ret True                            Received a non-error response
80  * @ret False                           Received error response / no response
81  * @ret tftp_state::server::sin_port    TFTP server UDP port
82  * @ret tftp_state::client::sin_port    Client UDP port
83  * @ret tftp_state::blksize             Always #TFTP_DEFAULT_BLKSIZE
84  * @ret *reply                          The server's response, if any
85  * @err #PXENV_STATUS_TFTP_OPEN_TIMEOUT TFTP open timed out
86  * @err other                           As returned by udp_transmit()
87  * @err other                           As set by tftp_set_errno()
88  *
89  * Send a TFTP/TFTM/MTFTP RRQ (read request) to a TFTP server, and
90  * return the server's reply (which may be an OACK, DATA or ERROR
91  * packet).  The server's reply will not be acknowledged, or processed
92  * in any way.
93  *
94  * If tftp_state::server::sin_port is 0, the standard TFTP server port
95  * (#TFTP_PORT) will be used.
96  *
97  * If tftp_state::client::sin_addr is not 0.0.0.0, it will be used as
98  * a multicast listening address for replies from the TFTP server.
99  *
100  * If tftp_state::client::sin_port is 0, the standard mechanism of
101  * using a new, unique port number for each TFTP request will be used.
102  * 
103  * For the various different types of TFTP server, you should treat
104  * tftp_state::client as follows:
105  *
106  *   - Standard TFTP server: set tftp_state::client::sin_addr to
107  *     0.0.0.0 and tftp_state::client::sin_port to 0.  tftp_open()
108  *     will set tftp_state::client::sin_port to the assigned local UDP
109  *     port.
110  *
111  *   - TFTM server: set tftp_state::client::sin_addr to 0.0.0.0 and
112  *     tftp_state::client::sin_port to 0.  tftp_open() will set
113  *     tftp_state::client::sin_port to the assigned local UDP port.
114  *     (Your call to tftp_process_opts() will then overwrite both
115  *     tftp_state::client::sin_addr and tftp_state::client::sin_port
116  *     with the values return in the OACK packet.)
117  *
118  *   - MTFTP server: set tftp_state::client::sin_addr to the client
119  *     multicast address and tftp_state::client::sin_port to the
120  *     client multicast port (both of which must be previously known,
121  *     e.g. provided by a DHCP server).  tftp_open() will not alter
122  *     these values.
123  *
124  * If tftp_state::blksize is 0, the maximum blocksize
125  * (#TFTP_MAX_BLKSIZE) will be requested.
126  *
127  * On exit, tftp_state::blksize will always contain
128  * #TFTP_DEFAULT_BLKSIZE, since this is the blocksize value that must
129  * be assumed until the OACK packet is processed (by a subsequent call
130  * to tftp_process_opts()).
131  *
132  * tftp_state::server::sin_port will be set to the UDP port from which
133  * the server's response originated.  This may or may not be the port
134  * to which the open request was sent.
135  *
136  * The options "blksize", "tsize" and "multicast" will always be
137  * appended to a TFTP open request.  Servers that do not understand
138  * any of these options should simply ignore them.
139  *
140  * tftp_open() will not automatically join or leave multicast groups;
141  * the caller is responsible for calling join_group() and
142  * leave_group() at appropriate times.
143  *
144  * If the response from the server is a TFTP ERROR packet, tftp_open()
145  * will return False and #errno will be set accordingly.
146  */
147 int tftp_open ( struct tftp_state *state, const char *filename,
148                 union tftp_any **reply ) {
149         static unsigned short lport = 2000; /* local port */
150         int fixed_lport;
151         struct tftp_rrq rrq;
152         unsigned int rrqlen;
153         int retry;
154
155         /* Flush receive queue */
156         rx_qdrain();
157
158         /* Default to blksize of TFTP_MAX_BLKSIZE if none specified */
159         if ( ! state->blksize )
160                 state->blksize = TFTP_MAX_BLKSIZE;
161
162         /* Use default TFTP server port if none specified */
163         if ( ! state->server.sin_port )
164                 state->server.sin_port = TFTP_PORT;
165
166         /* Determine whether or not to use lport */
167         fixed_lport = state->server.sin_port;
168
169         /* Set up RRQ */
170         rrq.opcode = htons ( TFTP_RRQ );
171         rrqlen = ( offsetof ( typeof ( rrq ), data ) +
172                     sprintf ( rrq.data,
173                               "%s%coctet%cblksize%c%d%ctsize%c0%cmulticast%c",
174                               filename, 0, 0, 0, state->blksize, 0, 0, 0, 0 )
175                     + 1 );
176
177         /* Set negotiated blksize to default value */
178         state->blksize = TFTP_DEFAULT_BLKSIZE;
179         
180         /* Nullify received packet pointer */
181         *reply = NULL;
182
183         /* Transmit RRQ until we get a response */
184         for ( retry = 0 ; retry < MAX_TFTP_RETRIES ; retry++ ) {
185                 long timeout = rfc2131_sleep_interval ( TIMEOUT, retry );
186
187                 /* Set client UDP port, if not already fixed */
188                 if ( ! fixed_lport )
189                         state->client.sin_port = ++lport;
190                 
191                 /* Send the RRQ */
192                 DBG ( "TFTPCORE: requesting %@:%d/%s from port %d\n",
193                       state->server.sin_addr.s_addr, state->server.sin_port,
194                       rrq.data, state->client.sin_port );
195                 if ( ! udp_transmit ( state->server.sin_addr.s_addr,
196                                       state->client.sin_port,
197                                       state->server.sin_port,
198                                       rrqlen, &rrq ) )
199                         return 0;
200                 
201                 /* Wait for response */
202                 if ( await_reply ( await_tftp, 0, state, timeout ) ) {
203                         *reply = ( union tftp_any * ) &nic.packet[ETH_HLEN];
204                         state->server.sin_port =
205                                 ntohs ( (*reply)->common.udp.dest );
206                         if ( ntohs ( (*reply)->common.opcode ) == TFTP_ERROR ){
207                                 tftp_set_errno ( &(*reply)->error );
208                                 return 0;
209                         }
210                         return 1;
211                 }
212         }
213
214         errno = PXENV_STATUS_TFTP_OPEN_TIMEOUT;
215         return 0;
216 }
217
218 /**
219  * Process a TFTP OACK packet
220  *
221  * @v state                             TFTP transfer state
222  * @v oack                              The TFTP OACK packet
223  * @ret True                            Options were processed successfully
224  * @ret False                           Options were not processed successfully
225  * @ret tftp_state::blksize             Negotiated blksize
226  * @ret tftp_state::tsize               File size (if known), or 0
227  * @ret tftp_state::client::sin_addr    Client multicast IP address, or 0.0.0.0
228  * @ret tftp_state::client::sin_port    Client UDP port
229  * @ret tftp_state::master              Client is master
230  * @err EINVAL                          An invalid option value was encountered
231  *
232  * Process the options returned by the TFTP server in an rfc2347 OACK
233  * packet.  The options "blksize" (rfc2348), "tsize" (rfc2349) and
234  * "multicast" (rfc2090) are recognised and processed; any other
235  * options are silently ignored.
236  *
237  * Where an option is not present in the OACK packet, the
238  * corresponding field(s) in #state will be left unaltered.
239  *
240  * Calling tftp_process_opts() does not send an acknowledgement for
241  * the OACK packet; this is the responsibility of the caller.
242  *
243  * @note If the "blksize" option is not present, tftp_state::blksize
244  * will @b not be implicitly set to #TFTP_DEFAULT_BLKSIZE.  However,
245  * since tftp_open() always sets tftp_state::blksize to
246  * #TFTP_DEFAULT_BLKSIZE before returning, you probably don't need to
247  * worry about this.
248  */
249 int tftp_process_opts ( struct tftp_state *state, struct tftp_oack *oack ) {
250         const char *p;
251         const char *end;
252
253         /* End of options */
254         end = ( ( char * ) &oack->udp ) + ntohs ( oack->udp.len );
255
256         /* Only possible error */
257         errno = EINVAL;
258
259         for ( p = oack->data ; p < end ; ) {
260                 if ( strcasecmp ( "blksize", p ) == 0 ) {
261                         p += 8;
262                         state->blksize = strtoul ( p, &p, 10 );
263                         if ( *p ) {
264                                 DBG ( "TFTPCORE: garbage \"%s\" "
265                                       "after blksize\n", p );
266                                 return 0;
267                         }
268                         p++;
269                 } else if ( strcasecmp ( "tsize", p ) == 0 ) {
270                         p += 6;
271                         state->tsize = strtoul ( p, &p, 10 );
272                         if ( *p ) {
273                                 DBG ( "TFTPCORE: garbage \"%s\" "
274                                       "after tsize\n", p );
275                                 return 0;
276                         }
277                         p++;
278                 } else if ( strcasecmp ( "multicast", p ) == 0 ) {
279                         char *e = strchr ( p, ',' );
280                         if ( ( ! e ) || ( e >= end ) ) {
281                                 DBG ( "TFTPCORE: malformed multicast field "
282                                       "\"%s\"\n", p );
283                                 return 0;
284                         }
285                         /* IP address may be missing, in which case we
286                          * should leave state->client.sin_addr
287                          * unaltered.
288                          */
289                         if ( e != p ) {
290                                 int rc;
291                                 *e = '\0';
292                                 rc = inet_aton ( p, &state->client.sin_addr );
293                                 *e = ',';
294                                 if ( ! rc ) {
295                                         DBG ( "TFTPCORE: malformed multicast "
296                                               "IP address \"%s\"\n", p );
297                                         return 0;
298                                 }
299                         }
300                         p = e + 1;
301                         /* UDP port may also be missing */
302                         if ( *p != ',' ) {
303                                 state->client.sin_port = strtoul ( p, &p, 10 );
304                                 if ( *p != ',' ) {
305                                         DBG ( "TFTPCORE: garbage \"%s\" "
306                                               "after multicast port\n", p );
307                                         return 0;
308                                 }
309                         } else {
310                                 p++;
311                         }
312                         /* "Master Client" must always be present */
313                         state->master = strtoul ( p, &p, 10 );
314                         if ( *p ) {
315                                 DBG ( "TFTPCORE: garbage \"%s\" "
316                                       "after multicast mc\n", p );
317                                 return 0;
318                         }
319                         p++;
320                 } else {
321                         p += strlen ( p ) + 1; /* skip option name */
322                         p += strlen ( p ) + 1; /* skip option value */
323                 }
324         }
325
326         if ( p > end ) {
327                 DBG ( "TFTPCORE: overran options in OACK\n" );
328                 return 0;
329         }
330
331         return 1;
332 }
333
334 /**
335  * Acknowledge a TFTP packet
336  *
337  * @v state                             TFTP transfer state
338  * @v tftp_state::server::sin_addr      TFTP server IP address
339  * @v tftp_state::server::sin_port      TFTP server UDP port
340  * @v tftp_state::client::sin_port      Client UDP port
341  * @v tftp_state::block                 Most recently received block number
342  * @ret True                            Acknowledgement packet was sent
343  * @ret False                           Acknowledgement packet was not sent
344  * @err other                           As returned by udp_transmit()
345  * 
346  * Send a TFTP ACK packet for the most recently received block.
347  *
348  * This sends only a single ACK packet; it does not wait for the
349  * server's response.
350  */
351 int tftp_ack_nowait ( struct tftp_state *state ) {
352         struct tftp_ack ack;
353
354         ack.opcode = htons ( TFTP_ACK );
355         ack.block = htons ( state->block );
356         return udp_transmit ( state->server.sin_addr.s_addr,
357                               state->client.sin_port, state->server.sin_port,
358                               sizeof ( ack ), &ack );
359 }
360
361 /**
362  * Acknowledge a TFTP packet and wait for a response
363  *
364  * @v state                             TFTP transfer state
365  * @v tftp_state::server::sin_addr      TFTP server IP address
366  * @v tftp_state::server::sin_port      TFTP server UDP port
367  * @v tftp_state::client::sin_port      Client UDP port
368  * @v tftp_state::block                 Most recently received block number
369  * @ret True                            Received a non-error response
370  * @ret False                           Received error response / no response
371  * @ret *reply                          The server's response, if any
372  * @err #PXENV_STATUS_TFTP_READ_TIMEOUT Timed out waiting for a response
373  * @err other                           As returned by tftp_ack_nowait()
374  * @err other                           As set by tftp_set_errno()
375  *
376  * Send a TFTP ACK packet for the most recently received data block,
377  * and keep transmitting this ACK until we get a response from the
378  * server (e.g. a new data block).
379  *
380  * If the response is a TFTP DATA packet, no processing is done.
381  * Specifically, the block number is not checked to ensure that this
382  * is indeed the next data block in the sequence, nor is
383  * tftp_state::block updated with the new block number.
384  *
385  * If the response from the server is a TFTP ERROR packet, tftp_open()
386  * will return False and #errno will be set accordingly.
387  */
388 int tftp_ack ( struct tftp_state *state, union tftp_any **reply ) {
389         int retry;
390
391         *reply = NULL;
392         for ( retry = 0 ; retry < MAX_TFTP_RETRIES ; retry++ ) {
393                 long timeout = rfc2131_sleep_interval ( TFTP_REXMT, retry );
394                 /* ACK the last data block */
395                 if ( ! tftp_ack_nowait ( state ) ) {
396                         DBG ( "TFTP: could not send ACK: %m\n" );
397                         return 0;
398                 }       
399                 if ( await_reply ( await_tftp, 0, &state, timeout ) ) {
400                         /* We received a reply */
401                         *reply = ( union tftp_any * ) &nic.packet[ETH_HLEN];
402                         if ( ntohs ( (*reply)->common.opcode ) == TFTP_ERROR ){
403                                 tftp_set_errno ( &(*reply)->error );
404                                 return 0;
405                         }
406                         return 1;
407                 }
408         }
409         DBG ( "TFTP: ACK retries exceeded\n" );
410         errno = PXENV_STATUS_TFTP_READ_TIMEOUT;
411         return 0;
412 }
413
414 /**
415  * Send a TFTP error
416  *
417  * @v state                             TFTP transfer state
418  * @v tftp_state::server::sin_addr      TFTP server IP address
419  * @v tftp_state::server::sin_port      TFTP server UDP port
420  * @v tftp_state::client::sin_port      Client UDP port
421  * @v errcode                           TFTP error code
422  * @v errmsg                            Descriptive error string
423  * @ret True                            Error packet was sent
424  * @ret False                           Error packet was not sent
425  *
426  * Send a TFTP ERROR packet back to the server to terminate the
427  * transfer.
428  */
429 int tftp_error ( struct tftp_state *state, int errcode, const char *errmsg ) {
430         struct tftp_error error;
431
432         DBG ( "TFTPCORE: aborting with error %d (%s)\n", errcode, errmsg );
433         error.opcode = htons ( TFTP_ERROR );
434         error.errcode = htons ( errcode );
435         strncpy ( error.errmsg, errmsg, sizeof ( error.errmsg ) );
436         return udp_transmit ( state->server.sin_addr.s_addr,
437                               state->client.sin_port, state->server.sin_port,
438                               sizeof ( error ), &error );
439 }
440
441 /**
442  * Interpret a TFTP error
443  *
444  * @v error                             Pointer to a struct tftp_error
445  *
446  * Sets #errno based on the error code in a TFTP ERROR packet.
447  */
448 void tftp_set_errno ( struct tftp_error *error ) {
449         static int errmap[] = {
450                 [TFTP_ERR_FILE_NOT_FOUND] = PXENV_STATUS_TFTP_FILE_NOT_FOUND,
451                 [TFTP_ERR_ACCESS_DENIED] = PXENV_STATUS_TFTP_ACCESS_VIOLATION,
452                 [TFTP_ERR_ILLEGAL_OP] = PXENV_STATUS_TFTP_UNKNOWN_OPCODE,
453         };
454         unsigned int errcode = ntohs ( error->errcode );
455         
456         errno = 0;
457         if ( errcode < ( sizeof(errmap) / sizeof(errmap[0]) ) )
458                 errno = errmap[errcode];
459         if ( ! errno )
460                 errno = PXENV_STATUS_TFTP_ERROR_OPCODE;
461 }