source: bootcd/isolinux/syslinux-6.03/gpxe/src/net/udp/tftp.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 32.6 KB
RevLine 
[e16e8f2]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
19FILE_LICENCE ( GPL2_OR_LATER );
20
21#include <stdint.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <strings.h>
26#include <byteswap.h>
27#include <errno.h>
28#include <assert.h>
29#include <gpxe/refcnt.h>
30#include <gpxe/xfer.h>
31#include <gpxe/open.h>
32#include <gpxe/uri.h>
33#include <gpxe/tcpip.h>
34#include <gpxe/retry.h>
35#include <gpxe/features.h>
36#include <gpxe/bitmap.h>
37#include <gpxe/settings.h>
38#include <gpxe/dhcp.h>
39#include <gpxe/uri.h>
40#include <gpxe/tftp.h>
41
42/** @file
43 *
44 * TFTP protocol
45 *
46 */
47
48FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
49
50/* TFTP-specific error codes */
51#define ETFTP_INVALID_BLKSIZE   EUNIQ_01
52#define ETFTP_INVALID_TSIZE     EUNIQ_02
53#define ETFTP_MC_NO_PORT        EUNIQ_03
54#define ETFTP_MC_NO_MC          EUNIQ_04
55#define ETFTP_MC_INVALID_MC     EUNIQ_05
56#define ETFTP_MC_INVALID_IP     EUNIQ_06
57#define ETFTP_MC_INVALID_PORT   EUNIQ_07
58
59/**
60 * A TFTP request
61 *
62 * This data structure holds the state for an ongoing TFTP transfer.
63 */
64struct tftp_request {
65        /** Reference count */
66        struct refcnt refcnt;
67        /** Data transfer interface */
68        struct xfer_interface xfer;
69
70        /** URI being fetched */
71        struct uri *uri;
72        /** Transport layer interface */
73        struct xfer_interface socket;
74        /** Multicast transport layer interface */
75        struct xfer_interface mc_socket;
76
77        /** Data block size
78         *
79         * This is the "blksize" option negotiated with the TFTP
80         * server.  (If the TFTP server does not support TFTP options,
81         * this will default to 512).
82         */
83        unsigned int blksize;
84        /** File size
85         *
86         * This is the value returned in the "tsize" option from the
87         * TFTP server.  If the TFTP server does not support the
88         * "tsize" option, this value will be zero.
89         */
90        unsigned long tsize;
91       
92        /** Server port
93         *
94         * This is the port to which RRQ packets are sent.
95         */
96        unsigned int port;
97        /** Peer address
98         *
99         * The peer address is determined by the first response
100         * received to the TFTP RRQ.
101         */
102        struct sockaddr_tcpip peer;
103        /** Request flags */
104        unsigned int flags;
105        /** MTFTP timeout count */
106        unsigned int mtftp_timeouts;
107
108        /** Block bitmap */
109        struct bitmap bitmap;
110        /** Maximum known length
111         *
112         * We don't always know the file length in advance.  In
113         * particular, if the TFTP server doesn't support the tsize
114         * option, or we are using MTFTP, then we don't know the file
115         * length until we see the end-of-file block (which, in the
116         * case of MTFTP, may not be the last block we see).
117         *
118         * This value is updated whenever we obtain information about
119         * the file length.
120         */
121        size_t filesize;
122        /** Retransmission timer */
123        struct retry_timer timer;
124};
125
126/** TFTP request flags */
127enum {
128        /** Send ACK packets */
129        TFTP_FL_SEND_ACK = 0x0001,
130        /** Request blksize and tsize options */
131        TFTP_FL_RRQ_SIZES = 0x0002,
132        /** Request multicast option */
133        TFTP_FL_RRQ_MULTICAST = 0x0004,
134        /** Perform MTFTP recovery on timeout */
135        TFTP_FL_MTFTP_RECOVERY = 0x0008,
136        /** Only get filesize and then abort the transfer */
137        TFTP_FL_SIZEONLY = 0x0010,
138};
139
140/** Maximum number of MTFTP open requests before falling back to TFTP */
141#define MTFTP_MAX_TIMEOUTS 3
142
143/**
144 * Free TFTP request
145 *
146 * @v refcnt            Reference counter
147 */
148static void tftp_free ( struct refcnt *refcnt ) {
149        struct tftp_request *tftp =
150                container_of ( refcnt, struct tftp_request, refcnt );
151
152        uri_put ( tftp->uri );
153        bitmap_free ( &tftp->bitmap );
154        free ( tftp );
155}
156
157/**
158 * Mark TFTP request as complete
159 *
160 * @v tftp              TFTP connection
161 * @v rc                Return status code
162 */
163static void tftp_done ( struct tftp_request *tftp, int rc ) {
164
165        DBGC ( tftp, "TFTP %p finished with status %d (%s)\n",
166               tftp, rc, strerror ( rc ) );
167
168        /* Stop the retry timer */
169        stop_timer ( &tftp->timer );
170
171        /* Close all data transfer interfaces */
172        xfer_nullify ( &tftp->socket );
173        xfer_close ( &tftp->socket, rc );
174        xfer_nullify ( &tftp->mc_socket );
175        xfer_close ( &tftp->mc_socket, rc );
176        xfer_nullify ( &tftp->xfer );
177        xfer_close ( &tftp->xfer, rc );
178}
179
180/**
181 * Reopen TFTP socket
182 *
183 * @v tftp              TFTP connection
184 * @ret rc              Return status code
185 */
186static int tftp_reopen ( struct tftp_request *tftp ) {
187        struct sockaddr_tcpip server;
188        int rc;
189
190        /* Close socket */
191        xfer_close ( &tftp->socket, 0 );
192
193        /* Disable ACK sending. */
194        tftp->flags &= ~TFTP_FL_SEND_ACK;
195
196        /* Reset peer address */
197        memset ( &tftp->peer, 0, sizeof ( tftp->peer ) );
198
199        /* Open socket */
200        memset ( &server, 0, sizeof ( server ) );
201        server.st_port = htons ( tftp->port );
202        if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM,
203                                             ( struct sockaddr * ) &server,
204                                             tftp->uri->host, NULL ) ) != 0 ) {
205                DBGC ( tftp, "TFTP %p could not open socket: %s\n",
206                       tftp, strerror ( rc ) );
207                return rc;
208        }
209
210        return 0;
211}
212
213/**
214 * Reopen TFTP multicast socket
215 *
216 * @v tftp              TFTP connection
217 * @v local             Local socket address
218 * @ret rc              Return status code
219 */
220static int tftp_reopen_mc ( struct tftp_request *tftp,
221                            struct sockaddr *local ) {
222        int rc;
223
224        /* Close multicast socket */
225        xfer_close ( &tftp->mc_socket, 0 );
226
227        /* Open multicast socket.  We never send via this socket, so
228         * use the local address as the peer address (since the peer
229         * address cannot be NULL).
230         */
231        if ( ( rc = xfer_open_socket ( &tftp->mc_socket, SOCK_DGRAM,
232                                       local, local ) ) != 0 ) {
233                DBGC ( tftp, "TFTP %p could not open multicast "
234                       "socket: %s\n", tftp, strerror ( rc ) );
235                return rc;
236        }
237
238        return 0;
239}
240
241/**
242 * Presize TFTP receive buffers and block bitmap
243 *
244 * @v tftp              TFTP connection
245 * @v filesize          Known minimum file size
246 * @ret rc              Return status code
247 */
248static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
249        unsigned int num_blocks;
250        int rc;
251
252        /* Do nothing if we are already large enough */
253        if ( filesize <= tftp->filesize )
254                return 0;
255
256        /* Record filesize */
257        tftp->filesize = filesize;
258
259        /* Notify recipient of file size */
260        xfer_seek ( &tftp->xfer, filesize, SEEK_SET );
261        xfer_seek ( &tftp->xfer, 0, SEEK_SET );
262
263        /* Calculate expected number of blocks.  Note that files whose
264         * length is an exact multiple of the blocksize will have a
265         * trailing zero-length block, which must be included.
266         */
267        num_blocks = ( ( filesize / tftp->blksize ) + 1 );
268        if ( ( rc = bitmap_resize ( &tftp->bitmap, num_blocks ) ) != 0 ) {
269                DBGC ( tftp, "TFTP %p could not resize bitmap to %d blocks: "
270                       "%s\n", tftp, num_blocks, strerror ( rc ) );
271                return rc;
272        }
273
274        return 0;
275}
276
277/**
278 * TFTP requested blocksize
279 *
280 * This is treated as a global configuration parameter.
281 */
282static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
283
284/**
285 * Set TFTP request blocksize
286 *
287 * @v blksize           Requested block size
288 */
289void tftp_set_request_blksize ( unsigned int blksize ) {
290        if ( blksize < TFTP_DEFAULT_BLKSIZE )
291                blksize = TFTP_DEFAULT_BLKSIZE;
292        tftp_request_blksize = blksize;
293}
294
295/**
296 * MTFTP multicast receive address
297 *
298 * This is treated as a global configuration parameter.
299 */
300static struct sockaddr_in tftp_mtftp_socket = {
301        .sin_family = AF_INET,
302        .sin_addr.s_addr = htonl ( 0xefff0101 ),
303        .sin_port = htons ( 3001 ),
304};
305
306/**
307 * Set MTFTP multicast address
308 *
309 * @v address           Multicast IPv4 address
310 */
311void tftp_set_mtftp_address ( struct in_addr address ) {
312        tftp_mtftp_socket.sin_addr = address;
313}
314
315/**
316 * Set MTFTP multicast port
317 *
318 * @v port              Multicast port
319 */
320void tftp_set_mtftp_port ( unsigned int port ) {
321        tftp_mtftp_socket.sin_port = htons ( port );
322}
323
324/**
325 * Transmit RRQ
326 *
327 * @v tftp              TFTP connection
328 * @ret rc              Return status code
329 */
330static int tftp_send_rrq ( struct tftp_request *tftp ) {
331        struct tftp_rrq *rrq;
332        const char *path;
333        size_t len;
334        struct io_buffer *iobuf;
335
336        /* Strip initial '/' if present.  If we were opened via the
337         * URI interface, then there will be an initial '/', since a
338         * full tftp:// URI provides no way to specify a non-absolute
339         * path.  However, many TFTP servers (particularly Windows
340         * TFTP servers) complain about having an initial '/', and it
341         * violates user expectations to have a '/' silently added to
342         * the DHCP-specified filename.
343         */
344        path = tftp->uri->path;
345        if ( *path == '/' )
346                path++;
347
348        DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
349
350        /* Allocate buffer */
351        len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */
352                + 5 + 1 /* "octet" + NUL */
353                + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */
354                + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */
355                + 9 + 1 + 1 /* "multicast" + NUL + NUL */ );
356        iobuf = xfer_alloc_iob ( &tftp->socket, len );
357        if ( ! iobuf )
358                return -ENOMEM;
359
360        /* Build request */
361        rrq = iob_put ( iobuf, sizeof ( *rrq ) );
362        rrq->opcode = htons ( TFTP_RRQ );
363        iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ),
364                                    "%s%coctet", path, 0 ) + 1 );
365        if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
366                iob_put ( iobuf, snprintf ( iobuf->tail,
367                                            iob_tailroom ( iobuf ),
368                                            "blksize%c%d%ctsize%c0", 0,
369                                            tftp_request_blksize, 0, 0 ) + 1 );
370        }
371        if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
372                iob_put ( iobuf, snprintf ( iobuf->tail,
373                                            iob_tailroom ( iobuf ),
374                                            "multicast%c", 0 ) + 1 );
375        }
376
377        /* RRQ always goes to the address specified in the initial
378         * xfer_open() call
379         */
380        return xfer_deliver_iob ( &tftp->socket, iobuf );
381}
382
383/**
384 * Transmit ACK
385 *
386 * @v tftp              TFTP connection
387 * @ret rc              Return status code
388 */
389static int tftp_send_ack ( struct tftp_request *tftp ) {
390        struct tftp_ack *ack;
391        struct io_buffer *iobuf;
392        struct xfer_metadata meta = {
393                .dest = ( struct sockaddr * ) &tftp->peer,
394        };
395        unsigned int block;
396
397        /* Determine next required block number */
398        block = bitmap_first_gap ( &tftp->bitmap );
399        DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block );
400
401        /* Allocate buffer */
402        iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
403        if ( ! iobuf )
404                return -ENOMEM;
405
406        /* Build ACK */
407        ack = iob_put ( iobuf, sizeof ( *ack ) );
408        ack->opcode = htons ( TFTP_ACK );
409        ack->block = htons ( block );
410
411        /* ACK always goes to the peer recorded from the RRQ response */
412        return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
413}
414
415/**
416 * Transmit ERROR (Abort)
417 *
418 * @v tftp              TFTP connection
419 * @v errcode           TFTP error code
420 * @v errmsg            Error message string
421 * @ret rc              Return status code
422 */
423static int tftp_send_error ( struct tftp_request *tftp, int errcode,
424                             const char *errmsg ) {
425        struct tftp_error *err;
426        struct io_buffer *iobuf;
427        struct xfer_metadata meta = {
428                .dest = ( struct sockaddr * ) &tftp->peer,
429        };
430        size_t msglen;
431
432        DBGC2 ( tftp, "TFTP %p sending ERROR %d: %s\n", tftp, errcode,
433                errmsg );
434
435        /* Allocate buffer */
436        msglen = sizeof ( *err ) + strlen ( errmsg ) + 1 /* NUL */;
437        iobuf = xfer_alloc_iob ( &tftp->socket, msglen );
438        if ( ! iobuf )
439                return -ENOMEM;
440
441        /* Build ERROR */
442        err = iob_put ( iobuf, msglen );
443        err->opcode = htons ( TFTP_ERROR );
444        err->errcode = htons ( errcode );
445        strcpy ( err->errmsg, errmsg );
446
447        /* ERR always goes to the peer recorded from the RRQ response */
448        return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
449}
450
451/**
452 * Transmit next relevant packet
453 *
454 * @v tftp              TFTP connection
455 * @ret rc              Return status code
456 */
457static int tftp_send_packet ( struct tftp_request *tftp ) {
458
459        /* Update retransmission timer.  While name resolution takes place the
460         * window is zero.  Avoid unnecessary delay after name resolution
461         * completes by retrying immediately.
462         */
463        stop_timer ( &tftp->timer );
464        if ( xfer_window ( &tftp->socket ) ) {
465                start_timer ( &tftp->timer );
466        } else {
467                start_timer_nodelay ( &tftp->timer );
468        }
469
470        /* Send RRQ or ACK as appropriate */
471        if ( ! tftp->peer.st_family ) {
472                return tftp_send_rrq ( tftp );
473        } else {
474                if ( tftp->flags & TFTP_FL_SEND_ACK ) {
475                        return tftp_send_ack ( tftp );
476                } else {
477                        return 0;
478                }
479        }
480}
481
482/**
483 * Handle TFTP retransmission timer expiry
484 *
485 * @v timer             Retry timer
486 * @v fail              Failure indicator
487 */
488static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
489        struct tftp_request *tftp =
490                container_of ( timer, struct tftp_request, timer );
491        int rc;
492
493        /* If we are doing MTFTP, attempt the various recovery strategies */
494        if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) {
495                if ( tftp->peer.st_family ) {
496                        /* If we have received any response from the server,
497                         * try resending the RRQ to restart the download.
498                         */
499                        DBGC ( tftp, "TFTP %p attempting reopen\n", tftp );
500                        if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
501                                goto err;
502                } else {
503                        /* Fall back to plain TFTP after several attempts */
504                        tftp->mtftp_timeouts++;
505                        DBGC ( tftp, "TFTP %p timeout %d waiting for MTFTP "
506                               "open\n", tftp, tftp->mtftp_timeouts );
507
508                        if ( tftp->mtftp_timeouts > MTFTP_MAX_TIMEOUTS ) {
509                                DBGC ( tftp, "TFTP %p falling back to plain "
510                                       "TFTP\n", tftp );
511                                tftp->flags = TFTP_FL_RRQ_SIZES;
512
513                                /* Close multicast socket */
514                                xfer_close ( &tftp->mc_socket, 0 );
515
516                                /* Reset retry timer */
517                                start_timer_nodelay ( &tftp->timer );
518
519                                /* The blocksize may change: discard
520                                 * the block bitmap
521                                 */
522                                bitmap_free ( &tftp->bitmap );
523                                memset ( &tftp->bitmap, 0,
524                                         sizeof ( tftp->bitmap ) );
525
526                                /* Reopen on standard TFTP port */
527                                tftp->port = TFTP_PORT;
528                                if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
529                                        goto err;
530                        }
531                }
532        } else {
533                /* Not doing MTFTP (or have fallen back to plain
534                 * TFTP); fail as per normal.
535                 */
536                if ( fail ) {
537                        rc = -ETIMEDOUT;
538                        goto err;
539                }
540        }
541        tftp_send_packet ( tftp );
542        return;
543
544 err:
545        tftp_done ( tftp, rc );
546}
547
548/**
549 * Process TFTP "blksize" option
550 *
551 * @v tftp              TFTP connection
552 * @v value             Option value
553 * @ret rc              Return status code
554 */
555static int tftp_process_blksize ( struct tftp_request *tftp,
556                                  const char *value ) {
557        char *end;
558
559        tftp->blksize = strtoul ( value, &end, 10 );
560        if ( *end ) {
561                DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
562                       tftp, value );
563                return -( EINVAL | ETFTP_INVALID_BLKSIZE );
564        }
565        DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
566
567        return 0;
568}
569
570/**
571 * Process TFTP "tsize" option
572 *
573 * @v tftp              TFTP connection
574 * @v value             Option value
575 * @ret rc              Return status code
576 */
577static int tftp_process_tsize ( struct tftp_request *tftp,
578                                const char *value ) {
579        char *end;
580
581        tftp->tsize = strtoul ( value, &end, 10 );
582        if ( *end ) {
583                DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
584                       tftp, value );
585                return -( EINVAL | ETFTP_INVALID_TSIZE );
586        }
587        DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
588
589        return 0;
590}
591
592/**
593 * Process TFTP "multicast" option
594 *
595 * @v tftp              TFTP connection
596 * @v value             Option value
597 * @ret rc              Return status code
598 */
599static int tftp_process_multicast ( struct tftp_request *tftp,
600                                    const char *value ) {
601        union {
602                struct sockaddr sa;
603                struct sockaddr_in sin;
604        } socket;
605        char buf[ strlen ( value ) + 1 ];
606        char *addr;
607        char *port;
608        char *port_end;
609        char *mc;
610        char *mc_end;
611        int rc;
612
613        /* Split value into "addr,port,mc" fields */
614        memcpy ( buf, value, sizeof ( buf ) );
615        addr = buf;
616        port = strchr ( addr, ',' );
617        if ( ! port ) {
618                DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp );
619                return -( EINVAL | ETFTP_MC_NO_PORT );
620        }
621        *(port++) = '\0';
622        mc = strchr ( port, ',' );
623        if ( ! mc ) {
624                DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp );
625                return -( EINVAL | ETFTP_MC_NO_MC );
626        }
627        *(mc++) = '\0';
628
629        /* Parse parameters */
630        if ( strtoul ( mc, &mc_end, 0 ) == 0 )
631                tftp->flags &= ~TFTP_FL_SEND_ACK;
632        if ( *mc_end ) {
633                DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc );
634                return -( EINVAL | ETFTP_MC_INVALID_MC );
635        }
636        DBGC ( tftp, "TFTP %p is%s the master client\n",
637               tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) );
638        if ( *addr && *port ) {
639                socket.sin.sin_family = AF_INET;
640                if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) {
641                        DBGC ( tftp, "TFTP %p multicast invalid IP address "
642                               "%s\n", tftp, addr );
643                        return -( EINVAL | ETFTP_MC_INVALID_IP );
644                }
645                DBGC ( tftp, "TFTP %p multicast IP address %s\n",
646                       tftp, inet_ntoa ( socket.sin.sin_addr ) );
647                socket.sin.sin_port = htons ( strtoul ( port, &port_end, 0 ) );
648                if ( *port_end ) {
649                        DBGC ( tftp, "TFTP %p multicast invalid port %s\n",
650                               tftp, port );
651                        return -( EINVAL | ETFTP_MC_INVALID_PORT );
652                }
653                DBGC ( tftp, "TFTP %p multicast port %d\n",
654                       tftp, ntohs ( socket.sin.sin_port ) );
655                if ( ( rc = tftp_reopen_mc ( tftp, &socket.sa ) ) != 0 )
656                        return rc;
657        }
658
659        return 0;
660}
661
662/** A TFTP option */
663struct tftp_option {
664        /** Option name */
665        const char *name;
666        /** Option processor
667         *
668         * @v tftp      TFTP connection
669         * @v value     Option value
670         * @ret rc      Return status code
671         */
672        int ( * process ) ( struct tftp_request *tftp, const char *value );
673};
674
675/** Recognised TFTP options */
676static struct tftp_option tftp_options[] = {
677        { "blksize", tftp_process_blksize },
678        { "tsize", tftp_process_tsize },
679        { "multicast", tftp_process_multicast },
680        { NULL, NULL }
681};
682
683/**
684 * Process TFTP option
685 *
686 * @v tftp              TFTP connection
687 * @v name              Option name
688 * @v value             Option value
689 * @ret rc              Return status code
690 */
691static int tftp_process_option ( struct tftp_request *tftp,
692                                 const char *name, const char *value ) {
693        struct tftp_option *option;
694
695        for ( option = tftp_options ; option->name ; option++ ) {
696                if ( strcasecmp ( name, option->name ) == 0 )
697                        return option->process ( tftp, value );
698        }
699
700        DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
701               tftp, name, value );
702
703        /* Unknown options should be silently ignored */
704        return 0;
705}
706
707/**
708 * Receive OACK
709 *
710 * @v tftp              TFTP connection
711 * @v buf               Temporary data buffer
712 * @v len               Length of temporary data buffer
713 * @ret rc              Return status code
714 */
715static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
716        struct tftp_oack *oack = buf;
717        char *end = buf + len;
718        char *name;
719        char *value;
720        char *next;
721        int rc = 0;
722
723        /* Sanity check */
724        if ( len < sizeof ( *oack ) ) {
725                DBGC ( tftp, "TFTP %p received underlength OACK packet "
726                       "length %zd\n", tftp, len );
727                rc = -EINVAL;
728                goto done;
729        }
730
731        /* Process each option in turn */
732        for ( name = oack->data ; name < end ; name = next ) {
733
734                /* Parse option name and value
735                 *
736                 * We treat parsing errors as non-fatal, because there
737                 * exists at least one TFTP server (IBM Tivoli PXE
738                 * Server 5.1.0.3) that has been observed to send
739                 * malformed OACKs containing trailing garbage bytes.
740                 */
741                value = ( name + strnlen ( name, ( end - name ) ) + 1 );
742                if ( value > end ) {
743                        DBGC ( tftp, "TFTP %p received OACK with malformed "
744                               "option name:\n", tftp );
745                        DBGC_HD ( tftp, oack, len );
746                        break;
747                }
748                if ( value == end ) {
749                        DBGC ( tftp, "TFTP %p received OACK missing value "
750                               "for option \"%s\"\n", tftp, name );
751                        DBGC_HD ( tftp, oack, len );
752                        break;
753                }
754                next = ( value + strnlen ( value, ( end - value ) ) + 1 );
755                if ( next > end ) {
756                        DBGC ( tftp, "TFTP %p received OACK with malformed "
757                               "value for option \"%s\":\n", tftp, name );
758                        DBGC_HD ( tftp, oack, len );
759                        break;
760                }
761
762                /* Process option */
763                if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
764                        goto done;
765        }
766
767        /* Process tsize information, if available */
768        if ( tftp->tsize ) {
769                if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 )
770                        goto done;
771        }
772
773        /* Abort request if only trying to determine file size */
774        if ( tftp->flags & TFTP_FL_SIZEONLY ) {
775                rc = 0;
776                tftp_send_error ( tftp, 0, "TFTP Aborted" );
777                tftp_done ( tftp, rc );
778                return rc;
779        }
780
781        /* Request next data block */
782        tftp_send_packet ( tftp );
783
784 done:
785        if ( rc )
786                tftp_done ( tftp, rc );
787        return rc;
788}
789
790/**
791 * Receive DATA
792 *
793 * @v tftp              TFTP connection
794 * @v iobuf             I/O buffer
795 * @ret rc              Return status code
796 *
797 * Takes ownership of I/O buffer.
798 */
799static int tftp_rx_data ( struct tftp_request *tftp,
800                          struct io_buffer *iobuf ) {
801        struct tftp_data *data = iobuf->data;
802        struct xfer_metadata meta;
803        unsigned int block;
804        off_t offset;
805        size_t data_len;
806        int rc;
807
808        if ( tftp->flags & TFTP_FL_SIZEONLY ) {
809                /* If we get here then server doesn't support SIZE option */
810                rc = -ENOTSUP;
811                tftp_send_error ( tftp, 0, "TFTP Aborted" );
812                goto done;
813        }
814
815        /* Sanity check */
816        if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
817                DBGC ( tftp, "TFTP %p received underlength DATA packet "
818                       "length %zd\n", tftp, iob_len ( iobuf ) );
819                rc = -EINVAL;
820                goto done;
821        }
822
823        /* Calculate block number */
824        block = ( ( bitmap_first_gap ( &tftp->bitmap ) + 1 ) & ~0xffff );
825        if ( data->block == 0 && block == 0 ) {
826                DBGC ( tftp, "TFTP %p received data block 0\n", tftp );
827                rc = -EINVAL;
828                goto done;
829        }
830        block += ( ntohs ( data->block ) - 1 );
831
832        /* Extract data */
833        offset = ( block * tftp->blksize );
834        iob_pull ( iobuf, sizeof ( *data ) );
835        data_len = iob_len ( iobuf );
836        if ( data_len > tftp->blksize ) {
837                DBGC ( tftp, "TFTP %p received overlength DATA packet "
838                       "length %zd\n", tftp, data_len );
839                rc = -EINVAL;
840                goto done;
841        }
842
843        /* Deliver data */
844        memset ( &meta, 0, sizeof ( meta ) );
845        meta.whence = SEEK_SET;
846        meta.offset = offset;
847        if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ),
848                                            &meta ) ) != 0 ) {
849                DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
850                       tftp, strerror ( rc ) );
851                goto done;
852        }
853
854        /* Ensure block bitmap is ready */
855        if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 )
856                goto done;
857
858        /* Mark block as received */
859        bitmap_set ( &tftp->bitmap, block );
860
861        /* Acknowledge block */
862        tftp_send_packet ( tftp );
863
864        /* If all blocks have been received, finish. */
865        if ( bitmap_full ( &tftp->bitmap ) )
866                tftp_done ( tftp, 0 );
867
868 done:
869        free_iob ( iobuf );
870        if ( rc )
871                tftp_done ( tftp, rc );
872        return rc;
873}
874
875/** Translation between TFTP errors and internal error numbers */
876static const int tftp_errors[] = {
877        [TFTP_ERR_FILE_NOT_FOUND]       = ENOENT,
878        [TFTP_ERR_ACCESS_DENIED]        = EACCES,
879        [TFTP_ERR_ILLEGAL_OP]           = ENOTSUP,
880};
881
882/**
883 * Receive ERROR
884 *
885 * @v tftp              TFTP connection
886 * @v buf               Temporary data buffer
887 * @v len               Length of temporary data buffer
888 * @ret rc              Return status code
889 */
890static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) {
891        struct tftp_error *error = buf;
892        unsigned int err;
893        int rc = 0;
894
895        /* Sanity check */
896        if ( len < sizeof ( *error ) ) {
897                DBGC ( tftp, "TFTP %p received underlength ERROR packet "
898                       "length %zd\n", tftp, len );
899                return -EINVAL;
900        }
901
902        DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
903               "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
904       
905        /* Determine final operation result */
906        err = ntohs ( error->errcode );
907        if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) )
908                rc = -tftp_errors[err];
909        if ( ! rc )
910                rc = -ENOTSUP;
911
912        /* Close TFTP request */
913        tftp_done ( tftp, rc );
914
915        return 0;
916}
917
918/**
919 * Receive new data
920 *
921 * @v tftp              TFTP connection
922 * @v iobuf             I/O buffer
923 * @v meta              Transfer metadata
924 * @ret rc              Return status code
925 */
926static int tftp_rx ( struct tftp_request *tftp,
927                     struct io_buffer *iobuf,
928                     struct xfer_metadata *meta ) {
929        struct sockaddr_tcpip *st_src;
930        struct tftp_common *common = iobuf->data;
931        size_t len = iob_len ( iobuf );
932        int rc = -EINVAL;
933       
934        /* Sanity checks */
935        if ( len < sizeof ( *common ) ) {
936                DBGC ( tftp, "TFTP %p received underlength packet length "
937                       "%zd\n", tftp, len );
938                goto done;
939        }
940        if ( ! meta->src ) {
941                DBGC ( tftp, "TFTP %p received packet without source port\n",
942                       tftp );
943                goto done;
944        }
945
946        /* Filter by TID.  Set TID on first response received */
947        st_src = ( struct sockaddr_tcpip * ) meta->src;
948        if ( ! tftp->peer.st_family ) {
949                memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) );
950                DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
951                       ntohs ( tftp->peer.st_port ) );
952        } else if ( memcmp ( &tftp->peer, st_src,
953                             sizeof ( tftp->peer ) ) != 0 ) {
954                DBGC ( tftp, "TFTP %p received packet from wrong source (got "
955                       "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ),
956                       ntohs ( tftp->peer.st_port ) );
957                goto done;
958        }
959
960        switch ( common->opcode ) {
961        case htons ( TFTP_OACK ):
962                rc = tftp_rx_oack ( tftp, iobuf->data, len );
963                break;
964        case htons ( TFTP_DATA ):
965                rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
966                break;
967        case htons ( TFTP_ERROR ):
968                rc = tftp_rx_error ( tftp, iobuf->data, len );
969                break;
970        default:
971                DBGC ( tftp, "TFTP %p received strange packet type %d\n",
972                       tftp, ntohs ( common->opcode ) );
973                break;
974        };
975
976 done:
977        free_iob ( iobuf );
978        return rc;
979}
980
981/**
982 * Receive new data via socket
983 *
984 * @v socket            Transport layer interface
985 * @v iobuf             I/O buffer
986 * @v meta              Transfer metadata
987 * @ret rc              Return status code
988 */
989static int tftp_socket_deliver_iob ( struct xfer_interface *socket,
990                                     struct io_buffer *iobuf,
991                                     struct xfer_metadata *meta ) {
992        struct tftp_request *tftp =
993                container_of ( socket, struct tftp_request, socket );
994
995        /* Enable sending ACKs when we receive a unicast packet.  This
996         * covers three cases:
997         *
998         * 1. Standard TFTP; we should always send ACKs, and will
999         *    always receive a unicast packet before we need to send the
1000         *    first ACK.
1001         *
1002         * 2. RFC2090 multicast TFTP; the only unicast packets we will
1003         *    receive are the OACKs; enable sending ACKs here (before
1004         *    processing the OACK) and disable it when processing the
1005         *    multicast option if we are not the master client.
1006         *
1007         * 3. MTFTP; receiving a unicast datagram indicates that we
1008         *    are the "master client" and should send ACKs.
1009         */
1010        tftp->flags |= TFTP_FL_SEND_ACK;
1011
1012        return tftp_rx ( tftp, iobuf, meta );
1013}
1014
1015/** TFTP socket operations */
1016static struct xfer_interface_operations tftp_socket_operations = {
1017        .close          = ignore_xfer_close,
1018        .vredirect      = xfer_vreopen,
1019        .window         = unlimited_xfer_window,
1020        .alloc_iob      = default_xfer_alloc_iob,
1021        .deliver_iob    = tftp_socket_deliver_iob,
1022        .deliver_raw    = xfer_deliver_as_iob,
1023};
1024
1025/**
1026 * Receive new data via multicast socket
1027 *
1028 * @v mc_socket         Multicast transport layer interface
1029 * @v iobuf             I/O buffer
1030 * @v meta              Transfer metadata
1031 * @ret rc              Return status code
1032 */
1033static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket,
1034                                        struct io_buffer *iobuf,
1035                                        struct xfer_metadata *meta ) {
1036        struct tftp_request *tftp =
1037                container_of ( mc_socket, struct tftp_request, mc_socket );
1038
1039        return tftp_rx ( tftp, iobuf, meta );
1040}
1041
1042/** TFTP multicast socket operations */
1043static struct xfer_interface_operations tftp_mc_socket_operations = {
1044        .close          = ignore_xfer_close,
1045        .vredirect      = xfer_vreopen,
1046        .window         = unlimited_xfer_window,
1047        .alloc_iob      = default_xfer_alloc_iob,
1048        .deliver_iob    = tftp_mc_socket_deliver_iob,
1049        .deliver_raw    = xfer_deliver_as_iob,
1050};
1051
1052/**
1053 * Close TFTP data transfer interface
1054 *
1055 * @v xfer              Data transfer interface
1056 * @v rc                Reason for close
1057 */
1058static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) {
1059        struct tftp_request *tftp =
1060                container_of ( xfer, struct tftp_request, xfer );
1061
1062        DBGC ( tftp, "TFTP %p interface closed: %s\n",
1063               tftp, strerror ( rc ) );
1064
1065        tftp_done ( tftp, rc );
1066}
1067
1068/**
1069 * Check flow control window
1070 *
1071 * @v xfer              Data transfer interface
1072 * @ret len             Length of window
1073 */
1074static size_t tftp_xfer_window ( struct xfer_interface *xfer ) {
1075        struct tftp_request *tftp =
1076                container_of ( xfer, struct tftp_request, xfer );
1077
1078        /* We abuse this data-xfer method to convey the blocksize to
1079         * the caller.  This really should be done using some kind of
1080         * stat() method, but we don't yet have the facility to do
1081         * that.
1082         */
1083        return tftp->blksize;
1084}
1085
1086/** TFTP data transfer interface operations */
1087static struct xfer_interface_operations tftp_xfer_operations = {
1088        .close          = tftp_xfer_close,
1089        .vredirect      = ignore_xfer_vredirect,
1090        .window         = tftp_xfer_window,
1091        .alloc_iob      = default_xfer_alloc_iob,
1092        .deliver_iob    = xfer_deliver_as_raw,
1093        .deliver_raw    = ignore_xfer_deliver_raw,
1094};
1095
1096/**
1097 * Initiate TFTP/TFTM/MTFTP download
1098 *
1099 * @v xfer              Data transfer interface
1100 * @v uri               Uniform Resource Identifier
1101 * @ret rc              Return status code
1102 */
1103static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri,
1104                            unsigned int default_port,
1105                            struct sockaddr *multicast,
1106                            unsigned int flags ) {
1107        struct tftp_request *tftp;
1108        int rc;
1109
1110        /* Sanity checks */
1111        if ( ! uri->host )
1112                return -EINVAL;
1113        if ( ! uri->path )
1114                return -EINVAL;
1115
1116        /* Allocate and populate TFTP structure */
1117        tftp = zalloc ( sizeof ( *tftp ) );
1118        if ( ! tftp )
1119                return -ENOMEM;
1120        tftp->refcnt.free = tftp_free;
1121        xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt );
1122        tftp->uri = uri_get ( uri );
1123        xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt );
1124        xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations,
1125                    &tftp->refcnt );
1126        tftp->blksize = TFTP_DEFAULT_BLKSIZE;
1127        tftp->flags = flags;
1128        tftp->timer.expired = tftp_timer_expired;
1129
1130        /* Open socket */
1131        tftp->port = uri_port ( tftp->uri, default_port );
1132        if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
1133                goto err;
1134
1135        /* Open multicast socket */
1136        if ( multicast ) {
1137                if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
1138                        goto err;
1139        }
1140
1141        /* Start timer to initiate RRQ */
1142        start_timer_nodelay ( &tftp->timer );
1143
1144        /* Attach to parent interface, mortalise self, and return */
1145        xfer_plug_plug ( &tftp->xfer, xfer );
1146        ref_put ( &tftp->refcnt );
1147        return 0;
1148
1149 err:
1150        DBGC ( tftp, "TFTP %p could not create request: %s\n",
1151               tftp, strerror ( rc ) );
1152        tftp_done ( tftp, rc );
1153        ref_put ( &tftp->refcnt );
1154        return rc;
1155}
1156
1157/**
1158 * Initiate TFTP download
1159 *
1160 * @v xfer              Data transfer interface
1161 * @v uri               Uniform Resource Identifier
1162 * @ret rc              Return status code
1163 */
1164static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
1165        return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1166                                TFTP_FL_RRQ_SIZES );
1167
1168}
1169
1170/** TFTP URI opener */
1171struct uri_opener tftp_uri_opener __uri_opener = {
1172        .scheme = "tftp",
1173        .open   = tftp_open,
1174};
1175
1176/**
1177 * Initiate TFTP-size request
1178 *
1179 * @v xfer              Data transfer interface
1180 * @v uri               Uniform Resource Identifier
1181 * @ret rc              Return status code
1182 */
1183static int tftpsize_open ( struct xfer_interface *xfer, struct uri *uri ) {
1184        return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1185                                ( TFTP_FL_RRQ_SIZES |
1186                                  TFTP_FL_SIZEONLY ) );
1187
1188}
1189
1190/** TFTP URI opener */
1191struct uri_opener tftpsize_uri_opener __uri_opener = {
1192        .scheme = "tftpsize",
1193        .open   = tftpsize_open,
1194};
1195
1196/**
1197 * Initiate TFTM download
1198 *
1199 * @v xfer              Data transfer interface
1200 * @v uri               Uniform Resource Identifier
1201 * @ret rc              Return status code
1202 */
1203static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) {
1204        return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1205                                ( TFTP_FL_RRQ_SIZES |
1206                                  TFTP_FL_RRQ_MULTICAST ) );
1207
1208}
1209
1210/** TFTM URI opener */
1211struct uri_opener tftm_uri_opener __uri_opener = {
1212        .scheme = "tftm",
1213        .open   = tftm_open,
1214};
1215
1216/**
1217 * Initiate MTFTP download
1218 *
1219 * @v xfer              Data transfer interface
1220 * @v uri               Uniform Resource Identifier
1221 * @ret rc              Return status code
1222 */
1223static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
1224        return tftp_core_open ( xfer, uri, MTFTP_PORT,
1225                                ( struct sockaddr * ) &tftp_mtftp_socket,
1226                                TFTP_FL_MTFTP_RECOVERY );
1227}
1228
1229/** MTFTP URI opener */
1230struct uri_opener mtftp_uri_opener __uri_opener = {
1231        .scheme = "mtftp",
1232        .open   = mtftp_open,
1233};
1234
1235/******************************************************************************
1236 *
1237 * Settings
1238 *
1239 ******************************************************************************
1240 */
1241
1242/** TFTP server setting */
1243struct setting next_server_setting __setting = {
1244        .name = "next-server",
1245        .description = "TFTP server",
1246        .tag = DHCP_EB_SIADDR,
1247        .type = &setting_type_ipv4,
1248};
1249
1250/**
1251 * Apply TFTP configuration settings
1252 *
1253 * @ret rc              Return status code
1254 */
1255static int tftp_apply_settings ( void ) {
1256        static struct in_addr tftp_server = { 0 };
1257        struct in_addr last_tftp_server;
1258        char uri_string[32];
1259        struct uri *uri;
1260
1261        /* Retrieve TFTP server setting */
1262        last_tftp_server = tftp_server;
1263        fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
1264
1265        /* If TFTP server setting has changed, set the current working
1266         * URI to match.  Do it only when the TFTP server has changed
1267         * to try to minimise surprises to the user, who probably
1268         * won't expect the CWURI to change just because they updated
1269         * an unrelated setting and triggered all the settings
1270         * applicators.
1271         */
1272        if ( tftp_server.s_addr != last_tftp_server.s_addr ) {
1273                snprintf ( uri_string, sizeof ( uri_string ),
1274                           "tftp://%s/", inet_ntoa ( tftp_server ) );
1275                uri = parse_uri ( uri_string );
1276                if ( ! uri )
1277                        return -ENOMEM;
1278                churi ( uri );
1279                uri_put ( uri );
1280        }
1281
1282        return 0;
1283}
1284
1285/** TFTP settings applicator */
1286struct settings_applicator tftp_settings_applicator __settings_applicator = {
1287        .apply = tftp_apply_settings,
1288};
Note: See TracBrowser for help on using the repository browser.