Quick hack to be able to accept transfers from servers that don't
[people/mcb30/gpxe.git] / src / net / udp / tftp.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <strings.h>
24 #include <byteswap.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <gpxe/refcnt.h>
28 #include <gpxe/xfer.h>
29 #include <gpxe/open.h>
30 #include <gpxe/uri.h>
31 #include <gpxe/tcpip.h>
32 #include <gpxe/retry.h>
33 #include <gpxe/features.h>
34 #include <gpxe/tftp.h>
35
36 /** @file
37  *
38  * TFTP protocol
39  *
40  */
41
42 FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
43
44 /**
45  * A TFTP request
46  *
47  * This data structure holds the state for an ongoing TFTP transfer.
48  */
49 struct tftp_request {
50         /** Reference count */
51         struct refcnt refcnt;
52         /** Data transfer interface */
53         struct xfer_interface xfer;
54
55         /** URI being fetched */
56         struct uri *uri;
57         /** Transport layer interface */
58         struct xfer_interface socket;
59
60         /** Data block size
61          *
62          * This is the "blksize" option negotiated with the TFTP
63          * server.  (If the TFTP server does not support TFTP options,
64          * this will default to 512).
65          */
66         unsigned int blksize;
67         /** File size
68          *
69          * This is the value returned in the "tsize" option from the
70          * TFTP server.  If the TFTP server does not support the
71          * "tsize" option, this value will be zero.
72          */
73         unsigned long tsize;
74
75         /** Request state
76          *
77          * This is the block number to be used in the next ACK sent
78          * back to the server, i.e. the number of the last received
79          * data block.  The value zero indicates that the last
80          * received block was an OACK (i.e. that the next ACK will
81          * contain a block number of zero), and any value less than
82          * zero indicates that the connection has not yet been opened
83          * (i.e. that no blocks have yet been received).
84          */
85         int state;
86         /** Peer address
87          *
88          * The peer address is determined by the first response
89          * received to the TFTP RRQ.
90          */
91         struct sockaddr_tcpip peer;
92         /** Retransmission timer */
93         struct retry_timer timer;
94 };
95
96 /**
97  * Free TFTP request
98  *
99  * @v refcnt            Reference counter
100  */
101 static void tftp_free ( struct refcnt *refcnt ) {
102         struct tftp_request *tftp =
103                 container_of ( refcnt, struct tftp_request, refcnt );
104
105         uri_put ( tftp->uri );
106         free ( tftp );
107 }
108
109 /**
110  * Mark TFTP request as complete
111  *
112  * @v tftp              TFTP connection
113  * @v rc                Return status code
114  */
115 static void tftp_done ( struct tftp_request *tftp, int rc ) {
116
117         DBGC ( tftp, "TFTP %p finished with status %d (%s)\n",
118                tftp, rc, strerror ( rc ) );
119
120         /* Stop the retry timer */
121         stop_timer ( &tftp->timer );
122
123         /* Close all data transfer interfaces */
124         xfer_nullify ( &tftp->socket );
125         xfer_close ( &tftp->socket, rc );
126         xfer_nullify ( &tftp->xfer );
127         xfer_close ( &tftp->xfer, rc );
128 }
129
130 /**
131  * TFTP requested blocksize
132  *
133  * This is treated as a global configuration parameter.
134  */
135 static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
136
137 /**
138  * Set TFTP request blocksize
139  *
140  * @v blksize           Requested block size
141  */
142 void tftp_set_request_blksize ( unsigned int blksize ) {
143         if ( blksize < TFTP_DEFAULT_BLKSIZE )
144                 blksize = TFTP_DEFAULT_BLKSIZE;
145         tftp_request_blksize = blksize;
146 }
147
148 /**
149  * Transmit RRQ
150  *
151  * @v tftp              TFTP connection
152  * @ret rc              Return status code
153  */
154 static int tftp_send_rrq ( struct tftp_request *tftp ) {
155         struct tftp_rrq *rrq;
156         const char *path = tftp->uri->path;
157         size_t len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */
158                        + 5 + 1 /* "octet" + NUL */
159                        + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */
160                        + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */ );
161         struct io_buffer *iobuf;
162
163         DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
164
165         /* Allocate buffer */
166         iobuf = xfer_alloc_iob ( &tftp->socket, len );
167         if ( ! iobuf )
168                 return -ENOMEM;
169
170         /* Build request */
171         rrq = iob_put ( iobuf, sizeof ( *rrq ) );
172         rrq->opcode = htons ( TFTP_RRQ );
173         iob_put ( iobuf,
174                   snprintf ( rrq->data, iob_tailroom ( iobuf ),
175                              "%s%coctet%cblksize%c%d%ctsize%c0", path, 0,
176                              0, 0, tftp_request_blksize, 0, 0 ) + 1 );
177
178         /* RRQ always goes to the address specified in the initial
179          * xfer_open() call
180          */
181         return xfer_deliver_iob ( &tftp->socket, iobuf );
182 }
183
184 /**
185  * Transmit ACK
186  *
187  * @v tftp              TFTP connection
188  * @ret rc              Return status code
189  */
190 static int tftp_send_ack ( struct tftp_request *tftp ) {
191         struct tftp_ack *ack;
192         struct io_buffer *iobuf;
193         struct xfer_metadata meta = {
194                 .dest = ( struct sockaddr * ) &tftp->peer,
195         };
196
197         DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n",
198                 tftp, tftp->state );
199
200         /* Allocate buffer */
201         iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
202         if ( ! iobuf )
203                 return -ENOMEM;
204
205         /* Build ACK */
206         ack = iob_put ( iobuf, sizeof ( *ack ) );
207         ack->opcode = htons ( TFTP_ACK );
208         ack->block = htons ( tftp->state );
209
210         /* ACK always goes to the peer recorded from the RRQ response */
211         return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
212 }
213
214 /**
215  * Transmit data
216  *
217  * @v tftp              TFTP connection
218  * @ret rc              Return status code
219  */
220 static int tftp_send_packet ( struct tftp_request *tftp ) {
221
222         /* Start retransmission timer */
223         start_timer ( &tftp->timer );
224
225         /* Send RRQ or ACK as appropriate */
226         if ( tftp->state < 0 ) {
227                 return tftp_send_rrq ( tftp );
228         } else {
229                 return tftp_send_ack ( tftp );
230         }
231 }
232
233 /**
234  * Handle TFTP retransmission timer expiry
235  *
236  * @v timer             Retry timer
237  * @v fail              Failure indicator
238  */
239 static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
240         struct tftp_request *tftp =
241                 container_of ( timer, struct tftp_request, timer );
242
243         if ( fail ) {
244                 tftp_done ( tftp, -ETIMEDOUT );
245         } else {
246                 tftp_send_packet ( tftp );
247         }
248 }
249
250 /**
251  * Mark TFTP block as received
252  *
253  * @v tftp              TFTP connection
254  * @v block             Block number
255  */
256 static void tftp_received ( struct tftp_request *tftp, unsigned int block ) {
257
258         /* Stop the retry timer */
259         stop_timer ( &tftp->timer );
260
261         /* Update state to indicate which block we're now waiting for */
262         tftp->state = block;
263
264         /* Send next packet */
265         tftp_send_packet ( tftp );
266 }
267
268 /**
269  * Process TFTP "blksize" option
270  *
271  * @v tftp              TFTP connection
272  * @v value             Option value
273  * @ret rc              Return status code
274  */
275 static int tftp_process_blksize ( struct tftp_request *tftp,
276                                   const char *value ) {
277         char *end;
278
279         tftp->blksize = strtoul ( value, &end, 10 );
280         if ( *end ) {
281                 DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
282                        tftp, value );
283                 return -EINVAL;
284         }
285         DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
286
287         return 0;
288 }
289
290 /**
291  * Process TFTP "tsize" option
292  *
293  * @v tftp              TFTP connection
294  * @v value             Option value
295  * @ret rc              Return status code
296  */
297 static int tftp_process_tsize ( struct tftp_request *tftp,
298                                 const char *value ) {
299         char *end;
300
301         tftp->tsize = strtoul ( value, &end, 10 );
302         if ( *end ) {
303                 DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
304                        tftp, value );
305                 return -EINVAL;
306         }
307         DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
308
309         /* Notify recipient of file size */
310         xfer_seek ( &tftp->xfer, tftp->tsize, SEEK_SET );
311         xfer_seek ( &tftp->xfer, 0, SEEK_SET );
312
313         return 0;
314 }
315
316 /** A TFTP option */
317 struct tftp_option {
318         /** Option name */
319         const char *name;
320         /** Option processor
321          *
322          * @v tftp      TFTP connection
323          * @v value     Option value
324          * @ret rc      Return status code
325          */
326         int ( * process ) ( struct tftp_request *tftp, const char *value );
327 };
328
329 /** Recognised TFTP options */
330 static struct tftp_option tftp_options[] = {
331         { "blksize", tftp_process_blksize },
332         { "tsize", tftp_process_tsize },
333         { NULL, NULL }
334 };
335
336 /**
337  * Process TFTP option
338  *
339  * @v tftp              TFTP connection
340  * @v name              Option name
341  * @v value             Option value
342  * @ret rc              Return status code
343  */
344 static int tftp_process_option ( struct tftp_request *tftp,
345                                  const char *name, const char *value ) {
346         struct tftp_option *option;
347
348         for ( option = tftp_options ; option->name ; option++ ) {
349                 if ( strcasecmp ( name, option->name ) == 0 )
350                         return option->process ( tftp, value );
351         }
352
353         DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
354                tftp, name, value );
355
356         return -EINVAL;
357 }
358
359 /**
360  * Receive OACK
361  *
362  * @v tftp              TFTP connection
363  * @v buf               Temporary data buffer
364  * @v len               Length of temporary data buffer
365  * @ret rc              Return status code
366  */
367 static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
368         struct tftp_oack *oack = buf;
369         char *end = buf + len;
370         char *name;
371         char *value;
372         int rc;
373
374         /* Sanity check */
375         if ( len < sizeof ( *oack ) ) {
376                 DBGC ( tftp, "TFTP %p received underlength OACK packet "
377                        "length %d\n", tftp, len );
378                 return -EINVAL;
379         }
380         if ( end[-1] != '\0' ) {
381                 DBGC ( tftp, "TFTP %p received OACK missing final NUL\n",
382                        tftp );
383                 return -EINVAL;
384         }
385
386         /* Process each option in turn */
387         name = oack->data;
388         while ( name < end ) {
389                 value = ( name + strlen ( name ) + 1 );
390                 if ( value == end ) {
391                         DBGC ( tftp, "TFTP %p received OACK missing value "
392                                "for option \"%s\"\n", tftp, name );
393                         return -EINVAL;
394                 }
395                 if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
396                         return rc;
397                 name = ( value + strlen ( value ) + 1 );
398         }
399
400         /* Mark as received block 0 (the OACK) */
401         tftp_received ( tftp, 0 );
402
403         return 0;
404 }
405
406 /**
407  * Receive DATA
408  *
409  * @v tftp              TFTP connection
410  * @v iobuf             I/O buffer
411  * @ret rc              Return status code
412  *
413  * Takes ownership of I/O buffer.
414  */
415 static int tftp_rx_data ( struct tftp_request *tftp,
416                           struct io_buffer *iobuf ) {
417         struct tftp_data *data = iobuf->data;
418         int block;
419         size_t data_len;
420         int rc;
421
422         /* Sanity check */
423         if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
424                 DBGC ( tftp, "TFTP %p received underlength DATA packet "
425                        "length %d\n", tftp, iob_len ( iobuf ) );
426                 free_iob ( iobuf );
427                 return -EINVAL;
428         }
429
430         /* Extract data */
431         block = ntohs ( data->block );
432         iob_pull ( iobuf, sizeof ( *data ) );
433         data_len = iob_len ( iobuf );
434
435         /* Check for correct block */
436         if ( ( tftp->state == -1 ) && ( block == 1 ) )
437                 tftp->state = 0;
438         if ( block != ( tftp->state + 1 ) ) {
439                 DBGC ( tftp, "TFTP %p received out-of-order block %d "
440                        "(expecting %d)\n", tftp, block, ( tftp->state + 1 ) );
441                 free_iob ( iobuf );
442                 return 0;
443         }
444
445         /* Deliver data */
446         if ( ( rc = xfer_deliver_iob ( &tftp->xfer, iobuf ) ) != 0 ) {
447                 DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
448                        tftp, strerror ( rc ) );
449                 tftp_done ( tftp, rc );
450                 return rc;
451         }
452
453         /* Mark block as received */
454         tftp_received ( tftp, block );
455
456         /* Finish when final block received */
457         if ( data_len < tftp->blksize )
458                 tftp_done ( tftp, 0 );
459
460         return 0;
461 }
462
463 /** Translation between TFTP errors and internal error numbers */
464 static const uint8_t tftp_errors[] = {
465         [TFTP_ERR_FILE_NOT_FOUND]       = PXENV_STATUS_TFTP_FILE_NOT_FOUND,
466         [TFTP_ERR_ACCESS_DENIED]        = PXENV_STATUS_TFTP_ACCESS_VIOLATION,
467         [TFTP_ERR_ILLEGAL_OP]           = PXENV_STATUS_TFTP_UNKNOWN_OPCODE,
468 };
469
470 /**
471  * Receive ERROR
472  *
473  * @v tftp              TFTP connection
474  * @v buf               Temporary data buffer
475  * @v len               Length of temporary data buffer
476  * @ret rc              Return status code
477  */
478 static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) {
479         struct tftp_error *error = buf;
480         unsigned int err;
481         int rc = 0;
482
483         /* Sanity check */
484         if ( len < sizeof ( *error ) ) {
485                 DBGC ( tftp, "TFTP %p received underlength ERROR packet "
486                        "length %d\n", tftp, len );
487                 return -EINVAL;
488         }
489
490         DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
491                "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
492         
493         /* Determine final operation result */
494         err = ntohs ( error->errcode );
495         if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) )
496                 rc = -tftp_errors[err];
497         if ( ! rc )
498                 rc = -PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION;
499
500         /* Close TFTP request */
501         tftp_done ( tftp, rc );
502
503         return 0;
504 }
505
506 /**
507  * Receive new data
508  *
509  * @v udp               UDP connection
510  * @v data              Received data
511  * @v len               Length of received data
512  * @v st_src            Partially-filled source address
513  * @v st_dest           Partially-filled destination address
514  */
515 static int tftp_socket_deliver_iob ( struct xfer_interface *socket,
516                                      struct io_buffer *iobuf,
517                                      struct xfer_metadata *meta ) {
518         struct tftp_request *tftp =
519                 container_of ( socket, struct tftp_request, socket );
520         struct sockaddr_tcpip *st_src;
521         struct tftp_common *common = iobuf->data;
522         size_t len = iob_len ( iobuf );
523         int rc = -EINVAL;
524         
525         /* Sanity checks */
526         if ( len < sizeof ( *common ) ) {
527                 DBGC ( tftp, "TFTP %p received underlength packet length %d\n",
528                        tftp, len );
529                 goto done;
530         }
531         if ( ! meta ) {
532                 DBGC ( tftp, "TFTP %p received packet without metadata\n",
533                        tftp );
534                 goto done;
535         }
536         if ( ! meta->src ) {
537                 DBGC ( tftp, "TFTP %p received packet without source port\n",
538                        tftp );
539                 goto done;
540         }
541
542         /* Filter by TID.  Set TID on first response received */
543         st_src = ( struct sockaddr_tcpip * ) meta->src;
544         if ( tftp->state < 0 ) {
545                 memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) );
546                 DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
547                        ntohs ( tftp->peer.st_port ) );
548         } else if ( memcmp ( &tftp->peer, st_src,
549                              sizeof ( tftp->peer ) ) != 0 ) {
550                 DBGC ( tftp, "TFTP %p received packet from wrong source (got "
551                        "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ),
552                        ntohs ( tftp->peer.st_port ) );
553                 goto done;
554         }
555
556         switch ( common->opcode ) {
557         case htons ( TFTP_OACK ):
558                 rc = tftp_rx_oack ( tftp, iobuf->data, len );
559                 break;
560         case htons ( TFTP_DATA ):
561                 rc = tftp_rx_data ( tftp, iobuf );
562                 iobuf = NULL;
563                 break;
564         case htons ( TFTP_ERROR ):
565                 rc = tftp_rx_error ( tftp, iobuf->data, len );
566                 break;
567         default:
568                 DBGC ( tftp, "TFTP %p received strange packet type %d\n",
569                        tftp, ntohs ( common->opcode ) );
570                 break;
571         };
572
573  done:
574         free_iob ( iobuf );
575         return rc;
576 }
577
578 /**
579  * TFTP connection closed by network stack
580  *
581  * @v socket            Transport layer interface
582  * @v rc                Reason for close
583  */
584 static void tftp_socket_close ( struct xfer_interface *socket, int rc ) {
585         struct tftp_request *tftp =
586                 container_of ( socket, struct tftp_request, socket );
587
588         DBGC ( tftp, "TFTP %p socket closed: %s\n",
589                tftp, strerror ( rc ) );
590
591         tftp_done ( tftp, rc );
592 }
593
594 /** TFTP socket operations */
595 static struct xfer_interface_operations tftp_socket_operations = {
596         .close          = tftp_socket_close,
597         .vredirect      = xfer_vopen,
598         .seek           = ignore_xfer_seek,
599         .window         = unlimited_xfer_window,
600         .alloc_iob      = default_xfer_alloc_iob,
601         .deliver_iob    = tftp_socket_deliver_iob,
602         .deliver_raw    = xfer_deliver_as_iob,
603 };
604  
605 /**
606  * Close TFTP data transfer interface
607  *
608  * @v xfer              Data transfer interface
609  * @v rc                Reason for close
610  */
611 static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) {
612         struct tftp_request *tftp =
613                 container_of ( xfer, struct tftp_request, xfer );
614
615         DBGC ( tftp, "TFTP %p interface closed: %s\n",
616                tftp, strerror ( rc ) );
617
618         tftp_done ( tftp, rc );
619 }
620
621 /** TFTP data transfer interface operations */
622 static struct xfer_interface_operations tftp_xfer_operations = {
623         .close          = tftp_xfer_close,
624         .vredirect      = ignore_xfer_vredirect,
625         .seek           = ignore_xfer_seek,
626         .window         = unlimited_xfer_window,
627         .alloc_iob      = default_xfer_alloc_iob,
628         .deliver_iob    = xfer_deliver_as_raw,
629         .deliver_raw    = ignore_xfer_deliver_raw,
630 };
631
632 /**
633  * Initiate TFTP download
634  *
635  * @v xfer              Data transfer interface
636  * @v uri               Uniform Resource Identifier
637  * @ret rc              Return status code
638  */
639 int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
640         struct tftp_request *tftp;
641         struct sockaddr_tcpip server;
642         int rc;
643
644         /* Sanity checks */
645         if ( ! uri->host )
646                 return -EINVAL;
647         if ( ! uri->path )
648                 return -EINVAL;
649
650         /* Allocate and populate TFTP structure */
651         tftp = zalloc ( sizeof ( *tftp ) );
652         if ( ! tftp )
653                 return -ENOMEM;
654         tftp->refcnt.free = tftp_free;
655         xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt );
656         tftp->uri = uri_get ( uri );
657         xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt );
658         tftp->blksize = TFTP_DEFAULT_BLKSIZE;
659         tftp->state = -1;
660         tftp->timer.expired = tftp_timer_expired;
661
662         /* Open socket */
663         memset ( &server, 0, sizeof ( server ) );
664         server.st_port = htons ( uri_port ( tftp->uri, TFTP_PORT ) );
665         if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM,
666                                              ( struct sockaddr * ) &server,
667                                              uri->host, NULL ) ) != 0 )
668                 goto err;
669
670         /* Start timer to initiate RRQ */
671         start_timer_nodelay ( &tftp->timer );
672
673         /* Attach to parent interface, mortalise self, and return */
674         xfer_plug_plug ( &tftp->xfer, xfer );
675         ref_put ( &tftp->refcnt );
676         return 0;
677
678  err:
679         DBGC ( tftp, "TFTP %p could not create request: %s\n",
680                tftp, strerror ( rc ) );
681         tftp_done ( tftp, rc );
682         ref_put ( &tftp->refcnt );
683         return rc;
684 }
685
686 /** TFTP URI opener */
687 struct uri_opener tftp_uri_opener __uri_opener = {
688         .scheme = "tftp",
689         .open   = tftp_open,
690 };