2 #include "tcp.h" /* for struct tcphdr */
11 * This file provides functions that are common to the TFTP (rfc1350),
12 * TFTM (rfc2090) and MTFTP (PXE) protocols.
17 * Wait for a TFTP packet
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
25 * @ret True This is our TFTP packet
26 * @ret False This is not one of our TFTP packets
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
33 * Invoke await_tftp() using code such as
37 * if ( await_reply ( await_tftp, 0, &tftp_state, timeout ) ) {
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;
48 /* Must have valid UDP (and, therefore, also IP) headers */
50 DBG2 ( "TFTPCORE: not UDP\n" );
53 /* Packet must come from the TFTP server */
54 if ( ip->src.s_addr != state->server.sin_addr.s_addr ) {
55 DBG2 ( "TFTPCORE: from %@, not from TFTP server %@\n",
56 ip->src.s_addr, state->server.sin_addr.s_addr );
59 /* Packet must be addressed to the correct UDP port */
60 if ( ntohs ( udp->dest ) != state->client.sin_port ) {
61 DBG2 ( "TFTPCORE: to UDP port %d, not to TFTP port %d\n",
62 ntohs ( udp->dest ), state->client.sin_port );
65 /* Packet must be addressed to us, or to our multicast
66 * listening address (if we have one).
68 if ( ! ( ( ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr ) ||
69 ( ( state->client.sin_addr.s_addr ) &&
70 ( ip->dest.s_addr == state->client.sin_addr.s_addr ) ) ) ) {
71 DBG2 ( "TFTPCORE: to %@, not to %@ (or %@)\n",
72 ip->dest.s_addr, arptable[ARP_CLIENT].ipaddr.s_addr,
73 state->client.sin_addr.s_addr );
81 * Issue a TFTP open request (RRQ)
83 * @v state TFTP transfer state
84 * @v tftp_state::server::sin_addr TFTP server IP address
85 * @v tftp_state::server::sin_port TFTP server UDP port, or 0
86 * @v tftp_state::client::sin_addr Client multicast IP address, or 0.0.0.0
87 * @v tftp_state::client::sin_port Client UDP port, or 0
88 * @v tftp_state::blksize Requested blksize, or 0
89 * @v filename File name
90 * @ret True Received a non-error response
91 * @ret False Received error response / no response
92 * @ret tftp_state::server::sin_port TFTP server UDP port
93 * @ret tftp_state::client::sin_port Client UDP port
94 * @ret tftp_state::blksize Always #TFTP_DEFAULT_BLKSIZE
95 * @ret *reply The server's response, if any
96 * @err #PXENV_STATUS_TFTP_OPEN_TIMEOUT TFTP open timed out
97 * @err other As returned by udp_transmit()
98 * @err other As set by tftp_set_errno()
100 * Send a TFTP/TFTM/MTFTP RRQ (read request) to a TFTP server, and
101 * return the server's reply (which may be an OACK, DATA or ERROR
102 * packet). The server's reply will not be acknowledged, or processed
105 * If tftp_state::server::sin_port is 0, the standard TFTP server port
106 * (#TFTP_PORT) will be used.
108 * If tftp_state::client::sin_addr is not 0.0.0.0, it will be used as
109 * a multicast listening address for replies from the TFTP server.
111 * If tftp_state::client::sin_port is 0, the standard mechanism of
112 * using a new, unique port number for each TFTP request will be used.
114 * For the various different types of TFTP server, you should treat
115 * tftp_state::client as follows:
117 * - Standard TFTP server: set tftp_state::client::sin_addr to
118 * 0.0.0.0 and tftp_state::client::sin_port to 0. tftp_open()
119 * will set tftp_state::client::sin_port to the assigned local UDP
122 * - TFTM server: set tftp_state::client::sin_addr to 0.0.0.0 and
123 * tftp_state::client::sin_port to 0. tftp_open() will set
124 * tftp_state::client::sin_port to the assigned local UDP port.
125 * (Your call to tftp_process_opts() will then overwrite both
126 * tftp_state::client::sin_addr and tftp_state::client::sin_port
127 * with the values return in the OACK packet.)
129 * - MTFTP server: set tftp_state::client::sin_addr to the client
130 * multicast address and tftp_state::client::sin_port to the
131 * client multicast port (both of which must be previously known,
132 * e.g. provided by a DHCP server). tftp_open() will not alter
135 * If tftp_state::blksize is 0, the maximum blocksize
136 * (#TFTP_MAX_BLKSIZE) will be requested.
138 * On exit, tftp_state::blksize will always contain
139 * #TFTP_DEFAULT_BLKSIZE, since this is the blocksize value that must
140 * be assumed until the OACK packet is processed (by a subsequent call
141 * to tftp_process_opts()).
143 * tftp_state::server::sin_port will be set to the UDP port from which
144 * the server's response originated. This may or may not be the port
145 * to which the open request was sent.
147 * The options "blksize", "tsize" and "multicast" will always be
148 * appended to a TFTP open request. Servers that do not understand
149 * any of these options should simply ignore them.
151 * tftp_open() will not automatically join or leave multicast groups;
152 * the caller is responsible for calling join_group() and
153 * leave_group() at appropriate times.
155 * If the response from the server is a TFTP ERROR packet, tftp_open()
156 * will return False and #errno will be set accordingly.
158 int tftp_open ( struct tftp_state *state, const char *filename,
159 union tftp_any **reply ) {
160 static unsigned short lport = 2000; /* local port */
166 /* Flush receive queue */
169 /* Default to blksize of TFTP_MAX_BLKSIZE if none specified */
170 if ( ! state->blksize )
171 state->blksize = TFTP_MAX_BLKSIZE;
173 /* Use default TFTP server port if none specified */
174 if ( ! state->server.sin_port )
175 state->server.sin_port = TFTP_PORT;
177 /* Determine whether or not to use lport */
178 fixed_lport = state->client.sin_port;
181 rrq.opcode = htons ( TFTP_RRQ );
182 rrqlen = ( offsetof ( typeof ( rrq ), data ) +
184 "%s%coctet%cblksize%c%d%ctsize%c0%cmulticast%c",
185 filename, 0, 0, 0, state->blksize, 0, 0, 0, 0 )
188 /* Set negotiated blksize to default value */
189 state->blksize = TFTP_DEFAULT_BLKSIZE;
191 /* Nullify received packet pointer */
194 /* Transmit RRQ until we get a response */
195 for ( retry = 0 ; retry < MAX_TFTP_RETRIES ; retry++ ) {
196 long timeout = rfc2131_sleep_interval ( TIMEOUT, retry );
198 /* Set client UDP port, if not already fixed */
200 state->client.sin_port = ++lport;
203 DBG ( "TFTPCORE: requesting %@:%d/%s from port %d\n",
204 state->server.sin_addr.s_addr, state->server.sin_port,
205 rrq.data, state->client.sin_port );
206 if ( ! udp_transmit ( state->server.sin_addr.s_addr,
207 state->client.sin_port,
208 state->server.sin_port,
212 /* Wait for response */
213 if ( await_reply ( await_tftp, 0, state, timeout ) ) {
214 *reply = ( union tftp_any * ) &nic.packet[ETH_HLEN];
215 state->server.sin_port =
216 ntohs ( (*reply)->common.udp.src );
217 DBG ( "TFTPCORE: got reply from %@:%d (type %d)\n",
218 state->server.sin_addr.s_addr,
219 state->server.sin_port,
220 ntohs ( (*reply)->common.opcode ) );
221 if ( ntohs ( (*reply)->common.opcode ) == TFTP_ERROR ){
222 tftp_set_errno ( &(*reply)->error );
229 DBG ( "TFTPCORE: open request timed out\n" );
230 errno = PXENV_STATUS_TFTP_OPEN_TIMEOUT;
235 * Process a TFTP OACK packet
237 * @v state TFTP transfer state
238 * @v oack The TFTP OACK packet
239 * @ret True Options were processed successfully
240 * @ret False Options were not processed successfully
241 * @ret tftp_state::blksize Negotiated blksize
242 * @ret tftp_state::tsize File size (if known), or 0
243 * @ret tftp_state::client::sin_addr Client multicast IP address, or 0.0.0.0
244 * @ret tftp_state::client::sin_port Client UDP port
245 * @ret tftp_state::master Client is master
246 * @err EINVAL An invalid option value was encountered
248 * Process the options returned by the TFTP server in an rfc2347 OACK
249 * packet. The options "blksize" (rfc2348), "tsize" (rfc2349) and
250 * "multicast" (rfc2090) are recognised and processed; any other
251 * options are silently ignored.
253 * Where an option is not present in the OACK packet, the
254 * corresponding field(s) in #state will be left unaltered.
256 * Calling tftp_process_opts() does not send an acknowledgement for
257 * the OACK packet; this is the responsibility of the caller.
259 * @note If the "blksize" option is not present, tftp_state::blksize
260 * will @b not be implicitly set to #TFTP_DEFAULT_BLKSIZE. However,
261 * since tftp_open() always sets tftp_state::blksize to
262 * #TFTP_DEFAULT_BLKSIZE before returning, you probably don't need to
265 int tftp_process_opts ( struct tftp_state *state, struct tftp_oack *oack ) {
269 DBG ( "TFTPCORE: processing OACK\n" );
272 end = ( ( char * ) &oack->udp ) + ntohs ( oack->udp.len );
274 /* Only possible error */
277 for ( p = oack->data ; p < end ; ) {
278 if ( strcasecmp ( "blksize", p ) == 0 ) {
280 state->blksize = strtoul ( p, &p, 10 );
282 DBG ( "TFTPCORE: garbage \"%s\" "
283 "after blksize\n", p );
287 DBG ( "TFTPCORE: got blksize %d\n", state->blksize );
288 } else if ( strcasecmp ( "tsize", p ) == 0 ) {
290 state->tsize = strtoul ( p, &p, 10 );
292 DBG ( "TFTPCORE: garbage \"%s\" "
293 "after tsize\n", p );
297 DBG ( "TFTPCORE: got tsize %d\n", state->tsize );
298 } else if ( strcasecmp ( "multicast", p ) == 0 ) {
299 char *e = strchr ( p, ',' );
300 if ( ( ! e ) || ( e >= end ) ) {
301 DBG ( "TFTPCORE: malformed multicast field "
305 /* IP address may be missing, in which case we
306 * should leave state->client.sin_addr
312 rc = inet_aton ( p, &state->client.sin_addr );
315 DBG ( "TFTPCORE: malformed multicast "
316 "IP address \"%s\"\n", p );
321 /* UDP port may also be missing */
323 state->client.sin_port = strtoul ( p, &p, 10 );
325 DBG ( "TFTPCORE: garbage \"%s\" "
326 "after multicast port\n", p );
332 /* "Master Client" must always be present */
333 state->master = strtoul ( p, &p, 10 );
335 DBG ( "TFTPCORE: garbage \"%s\" "
336 "after multicast mc\n", p );
340 DBG ( "TFTPCORE: got multicast %@:%d (%s)\n",
341 state->client.sin_addr.s_addr,
342 state->client.sin_port,
343 ( state->master ? "master" : "not master" ) );
345 DBG ( "TFTPCORE: unknown option \"%s\"\n", p );
346 p += strlen ( p ) + 1; /* skip option name */
347 p += strlen ( p ) + 1; /* skip option value */
352 DBG ( "TFTPCORE: overran options in OACK\n" );
360 * Acknowledge a TFTP packet
362 * @v state TFTP transfer state
363 * @v tftp_state::server::sin_addr TFTP server IP address
364 * @v tftp_state::server::sin_port TFTP server UDP port
365 * @v tftp_state::client::sin_port Client UDP port
366 * @v tftp_state::block Most recently received block number
367 * @ret True Acknowledgement packet was sent
368 * @ret False Acknowledgement packet was not sent
369 * @err other As returned by udp_transmit()
371 * Send a TFTP ACK packet for the most recently received block.
373 * This sends only a single ACK packet; it does not wait for the
376 int tftp_ack_nowait ( struct tftp_state *state ) {
379 DBG ( "TFTPCORE: acknowledging data block %d\n", state->block );
380 ack.opcode = htons ( TFTP_ACK );
381 ack.block = htons ( state->block );
382 return udp_transmit ( state->server.sin_addr.s_addr,
383 state->client.sin_port, state->server.sin_port,
384 sizeof ( ack ), &ack );
388 * Acknowledge a TFTP packet and wait for a response
390 * @v state TFTP transfer state
391 * @v tftp_state::server::sin_addr TFTP server IP address
392 * @v tftp_state::server::sin_port TFTP server UDP port
393 * @v tftp_state::client::sin_port Client UDP port
394 * @v tftp_state::block Most recently received block number
395 * @ret True Received a non-error response
396 * @ret False Received error response / no response
397 * @ret *reply The server's response, if any
398 * @err #PXENV_STATUS_TFTP_READ_TIMEOUT Timed out waiting for a response
399 * @err other As returned by tftp_ack_nowait()
400 * @err other As set by tftp_set_errno()
402 * Send a TFTP ACK packet for the most recently received data block,
403 * and keep transmitting this ACK until we get a response from the
404 * server (e.g. a new data block).
406 * If the response is a TFTP DATA packet, no processing is done.
407 * Specifically, the block number is not checked to ensure that this
408 * is indeed the next data block in the sequence, nor is
409 * tftp_state::block updated with the new block number.
411 * If the response from the server is a TFTP ERROR packet, tftp_open()
412 * will return False and #errno will be set accordingly.
414 int tftp_ack ( struct tftp_state *state, union tftp_any **reply ) {
418 for ( retry = 0 ; retry < MAX_TFTP_RETRIES ; retry++ ) {
419 long timeout = rfc2131_sleep_interval ( TFTP_REXMT, retry );
420 /* ACK the last data block */
421 if ( ! tftp_ack_nowait ( state ) ) {
422 DBG ( "TFTP: could not send ACK: %m\n" );
425 if ( await_reply ( await_tftp, 0, state, timeout ) ) {
426 /* We received a reply */
427 *reply = ( union tftp_any * ) &nic.packet[ETH_HLEN];
428 DBG ( "TFTPCORE: got reply (type %d)\n",
429 ntohs ( (*reply)->common.opcode ) );
430 if ( ntohs ( (*reply)->common.opcode ) == TFTP_ERROR ){
431 tftp_set_errno ( &(*reply)->error );
437 DBG ( "TFTP: timed out during read\n" );
438 errno = PXENV_STATUS_TFTP_READ_TIMEOUT;
445 * @v state TFTP transfer state
446 * @v tftp_state::server::sin_addr TFTP server IP address
447 * @v tftp_state::server::sin_port TFTP server UDP port
448 * @v tftp_state::client::sin_port Client UDP port
449 * @v errcode TFTP error code
450 * @v errmsg Descriptive error string
451 * @ret True Error packet was sent
452 * @ret False Error packet was not sent
454 * Send a TFTP ERROR packet back to the server to terminate the
457 int tftp_error ( struct tftp_state *state, int errcode, const char *errmsg ) {
458 struct tftp_error error;
460 DBG ( "TFTPCORE: aborting with error %d (%s)\n", errcode, errmsg );
461 error.opcode = htons ( TFTP_ERROR );
462 error.errcode = htons ( errcode );
463 strncpy ( error.errmsg, errmsg, sizeof ( error.errmsg ) );
464 return udp_transmit ( state->server.sin_addr.s_addr,
465 state->client.sin_port, state->server.sin_port,
466 sizeof ( error ), &error );
470 * Interpret a TFTP error
472 * @v error Pointer to a struct tftp_error
474 * Sets #errno based on the error code in a TFTP ERROR packet.
476 void tftp_set_errno ( struct tftp_error *error ) {
477 static int errmap[] = {
478 [TFTP_ERR_FILE_NOT_FOUND] = PXENV_STATUS_TFTP_FILE_NOT_FOUND,
479 [TFTP_ERR_ACCESS_DENIED] = PXENV_STATUS_TFTP_ACCESS_VIOLATION,
480 [TFTP_ERR_ILLEGAL_OP] = PXENV_STATUS_TFTP_UNKNOWN_OPCODE,
482 unsigned int errcode = ntohs ( error->errcode );
485 if ( errcode < ( sizeof(errmap) / sizeof(errmap[0]) ) )
486 errno = errmap[errcode];
488 errno = PXENV_STATUS_TFTP_ERROR_OPCODE;