tftp.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <strings.h>
00026 #include <byteswap.h>
00027 #include <errno.h>
00028 #include <assert.h>
00029 #include <gpxe/refcnt.h>
00030 #include <gpxe/xfer.h>
00031 #include <gpxe/open.h>
00032 #include <gpxe/uri.h>
00033 #include <gpxe/tcpip.h>
00034 #include <gpxe/retry.h>
00035 #include <gpxe/features.h>
00036 #include <gpxe/bitmap.h>
00037 #include <gpxe/settings.h>
00038 #include <gpxe/dhcp.h>
00039 #include <gpxe/uri.h>
00040 #include <gpxe/tftp.h>
00041 
00042 /** @file
00043  *
00044  * TFTP protocol
00045  *
00046  */
00047 
00048 FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
00049 
00050 /* TFTP-specific error codes */
00051 #define ETFTP_INVALID_BLKSIZE   EUNIQ_01
00052 #define ETFTP_INVALID_TSIZE     EUNIQ_02
00053 #define ETFTP_MC_NO_PORT        EUNIQ_03
00054 #define ETFTP_MC_NO_MC          EUNIQ_04
00055 #define ETFTP_MC_INVALID_MC     EUNIQ_05
00056 #define ETFTP_MC_INVALID_IP     EUNIQ_06
00057 #define ETFTP_MC_INVALID_PORT   EUNIQ_07
00058 
00059 /**
00060  * A TFTP request
00061  *
00062  * This data structure holds the state for an ongoing TFTP transfer.
00063  */
00064 struct tftp_request {
00065         /** Reference count */
00066         struct refcnt refcnt;
00067         /** Data transfer interface */
00068         struct xfer_interface xfer;
00069 
00070         /** URI being fetched */
00071         struct uri *uri;
00072         /** Transport layer interface */
00073         struct xfer_interface socket;
00074         /** Multicast transport layer interface */
00075         struct xfer_interface mc_socket;
00076 
00077         /** Data block size
00078          *
00079          * This is the "blksize" option negotiated with the TFTP
00080          * server.  (If the TFTP server does not support TFTP options,
00081          * this will default to 512).
00082          */
00083         unsigned int blksize;
00084         /** File size
00085          *
00086          * This is the value returned in the "tsize" option from the
00087          * TFTP server.  If the TFTP server does not support the
00088          * "tsize" option, this value will be zero.
00089          */
00090         unsigned long tsize;
00091         
00092         /** Server port
00093          *
00094          * This is the port to which RRQ packets are sent.
00095          */
00096         unsigned int port;
00097         /** Peer address
00098          *
00099          * The peer address is determined by the first response
00100          * received to the TFTP RRQ.
00101          */
00102         struct sockaddr_tcpip peer;
00103         /** Request flags */
00104         unsigned int flags;
00105         /** MTFTP timeout count */
00106         unsigned int mtftp_timeouts;
00107 
00108         /** Block bitmap */
00109         struct bitmap bitmap;
00110         /** Maximum known length
00111          *
00112          * We don't always know the file length in advance.  In
00113          * particular, if the TFTP server doesn't support the tsize
00114          * option, or we are using MTFTP, then we don't know the file
00115          * length until we see the end-of-file block (which, in the
00116          * case of MTFTP, may not be the last block we see).
00117          *
00118          * This value is updated whenever we obtain information about
00119          * the file length.
00120          */
00121         size_t filesize;
00122         /** Retransmission timer */
00123         struct retry_timer timer;
00124 };
00125 
00126 /** TFTP request flags */
00127 enum {
00128         /** Send ACK packets */
00129         TFTP_FL_SEND_ACK = 0x0001,
00130         /** Request blksize and tsize options */
00131         TFTP_FL_RRQ_SIZES = 0x0002,
00132         /** Request multicast option */
00133         TFTP_FL_RRQ_MULTICAST = 0x0004,
00134         /** Perform MTFTP recovery on timeout */
00135         TFTP_FL_MTFTP_RECOVERY = 0x0008,
00136         /** Only get filesize and then abort the transfer */
00137         TFTP_FL_SIZEONLY = 0x0010,
00138 };
00139 
00140 /** Maximum number of MTFTP open requests before falling back to TFTP */
00141 #define MTFTP_MAX_TIMEOUTS 3
00142 
00143 /**
00144  * Free TFTP request
00145  *
00146  * @v refcnt            Reference counter
00147  */
00148 static void tftp_free ( struct refcnt *refcnt ) {
00149         struct tftp_request *tftp =
00150                 container_of ( refcnt, struct tftp_request, refcnt );
00151 
00152         uri_put ( tftp->uri );
00153         bitmap_free ( &tftp->bitmap );
00154         free ( tftp );
00155 }
00156 
00157 /**
00158  * Mark TFTP request as complete
00159  *
00160  * @v tftp              TFTP connection
00161  * @v rc                Return status code
00162  */
00163 static void tftp_done ( struct tftp_request *tftp, int rc ) {
00164 
00165         DBGC ( tftp, "TFTP %p finished with status %d (%s)\n",
00166                tftp, rc, strerror ( rc ) );
00167 
00168         /* Stop the retry timer */
00169         stop_timer ( &tftp->timer );
00170 
00171         /* Close all data transfer interfaces */
00172         xfer_nullify ( &tftp->socket );
00173         xfer_close ( &tftp->socket, rc );
00174         xfer_nullify ( &tftp->mc_socket );
00175         xfer_close ( &tftp->mc_socket, rc );
00176         xfer_nullify ( &tftp->xfer );
00177         xfer_close ( &tftp->xfer, rc );
00178 }
00179 
00180 /**
00181  * Reopen TFTP socket
00182  *
00183  * @v tftp              TFTP connection
00184  * @ret rc              Return status code
00185  */
00186 static int tftp_reopen ( struct tftp_request *tftp ) {
00187         struct sockaddr_tcpip server;
00188         int rc;
00189 
00190         /* Close socket */
00191         xfer_close ( &tftp->socket, 0 );
00192 
00193         /* Disable ACK sending. */
00194         tftp->flags &= ~TFTP_FL_SEND_ACK;
00195 
00196         /* Reset peer address */
00197         memset ( &tftp->peer, 0, sizeof ( tftp->peer ) );
00198 
00199         /* Open socket */
00200         memset ( &server, 0, sizeof ( server ) );
00201         server.st_port = htons ( tftp->port );
00202         if ( ( rc = xfer_open_named_socket ( &tftp->socket, SOCK_DGRAM,
00203                                              ( struct sockaddr * ) &server,
00204                                              tftp->uri->host, NULL ) ) != 0 ) {
00205                 DBGC ( tftp, "TFTP %p could not open socket: %s\n",
00206                        tftp, strerror ( rc ) );
00207                 return rc;
00208         }
00209 
00210         return 0;
00211 }
00212 
00213 /**
00214  * Reopen TFTP multicast socket
00215  *
00216  * @v tftp              TFTP connection
00217  * @v local             Local socket address
00218  * @ret rc              Return status code
00219  */
00220 static int tftp_reopen_mc ( struct tftp_request *tftp,
00221                             struct sockaddr *local ) {
00222         int rc;
00223 
00224         /* Close multicast socket */
00225         xfer_close ( &tftp->mc_socket, 0 );
00226 
00227         /* Open multicast socket.  We never send via this socket, so
00228          * use the local address as the peer address (since the peer
00229          * address cannot be NULL).
00230          */
00231         if ( ( rc = xfer_open_socket ( &tftp->mc_socket, SOCK_DGRAM,
00232                                        local, local ) ) != 0 ) {
00233                 DBGC ( tftp, "TFTP %p could not open multicast "
00234                        "socket: %s\n", tftp, strerror ( rc ) );
00235                 return rc;
00236         }
00237 
00238         return 0;
00239 }
00240 
00241 /**
00242  * Presize TFTP receive buffers and block bitmap
00243  *
00244  * @v tftp              TFTP connection
00245  * @v filesize          Known minimum file size
00246  * @ret rc              Return status code
00247  */
00248 static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
00249         unsigned int num_blocks;
00250         int rc;
00251 
00252         /* Do nothing if we are already large enough */
00253         if ( filesize <= tftp->filesize )
00254                 return 0;
00255 
00256         /* Record filesize */
00257         tftp->filesize = filesize;
00258 
00259         /* Notify recipient of file size */
00260         xfer_seek ( &tftp->xfer, filesize, SEEK_SET );
00261         xfer_seek ( &tftp->xfer, 0, SEEK_SET );
00262 
00263         /* Calculate expected number of blocks.  Note that files whose
00264          * length is an exact multiple of the blocksize will have a
00265          * trailing zero-length block, which must be included.
00266          */
00267         num_blocks = ( ( filesize / tftp->blksize ) + 1 );
00268         if ( ( rc = bitmap_resize ( &tftp->bitmap, num_blocks ) ) != 0 ) {
00269                 DBGC ( tftp, "TFTP %p could not resize bitmap to %d blocks: "
00270                        "%s\n", tftp, num_blocks, strerror ( rc ) );
00271                 return rc;
00272         }
00273 
00274         return 0;
00275 }
00276 
00277 /**
00278  * TFTP requested blocksize
00279  *
00280  * This is treated as a global configuration parameter.
00281  */
00282 static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
00283 
00284 /**
00285  * Set TFTP request blocksize
00286  *
00287  * @v blksize           Requested block size
00288  */
00289 void tftp_set_request_blksize ( unsigned int blksize ) {
00290         if ( blksize < TFTP_DEFAULT_BLKSIZE )
00291                 blksize = TFTP_DEFAULT_BLKSIZE;
00292         tftp_request_blksize = blksize;
00293 }
00294 
00295 /**
00296  * MTFTP multicast receive address
00297  *
00298  * This is treated as a global configuration parameter.
00299  */
00300 static struct sockaddr_in tftp_mtftp_socket = {
00301         .sin_family = AF_INET,
00302         .sin_addr.s_addr = htonl ( 0xefff0101 ),
00303         .sin_port = htons ( 3001 ),
00304 };
00305 
00306 /**
00307  * Set MTFTP multicast address
00308  *
00309  * @v address           Multicast IPv4 address
00310  */
00311 void tftp_set_mtftp_address ( struct in_addr address ) {
00312         tftp_mtftp_socket.sin_addr = address;
00313 }
00314 
00315 /**
00316  * Set MTFTP multicast port
00317  *
00318  * @v port              Multicast port
00319  */
00320 void tftp_set_mtftp_port ( unsigned int port ) {
00321         tftp_mtftp_socket.sin_port = htons ( port );
00322 }
00323 
00324 /**
00325  * Transmit RRQ
00326  *
00327  * @v tftp              TFTP connection
00328  * @ret rc              Return status code
00329  */
00330 static int tftp_send_rrq ( struct tftp_request *tftp ) {
00331         struct tftp_rrq *rrq;
00332         const char *path;
00333         size_t len;
00334         struct io_buffer *iobuf;
00335 
00336         /* Strip initial '/' if present.  If we were opened via the
00337          * URI interface, then there will be an initial '/', since a
00338          * full tftp:// URI provides no way to specify a non-absolute
00339          * path.  However, many TFTP servers (particularly Windows
00340          * TFTP servers) complain about having an initial '/', and it
00341          * violates user expectations to have a '/' silently added to
00342          * the DHCP-specified filename.
00343          */
00344         path = tftp->uri->path;
00345         if ( *path == '/' )
00346                 path++;
00347 
00348         DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
00349 
00350         /* Allocate buffer */
00351         len = ( sizeof ( *rrq ) + strlen ( path ) + 1 /* NUL */
00352                 + 5 + 1 /* "octet" + NUL */
00353                 + 7 + 1 + 5 + 1 /* "blksize" + NUL + ddddd + NUL */
00354                 + 5 + 1 + 1 + 1 /* "tsize" + NUL + "0" + NUL */ 
00355                 + 9 + 1 + 1 /* "multicast" + NUL + NUL */ );
00356         iobuf = xfer_alloc_iob ( &tftp->socket, len );
00357         if ( ! iobuf )
00358                 return -ENOMEM;
00359 
00360         /* Build request */
00361         rrq = iob_put ( iobuf, sizeof ( *rrq ) );
00362         rrq->opcode = htons ( TFTP_RRQ );
00363         iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ),
00364                                     "%s%coctet", path, 0 ) + 1 );
00365         if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
00366                 iob_put ( iobuf, snprintf ( iobuf->tail,
00367                                             iob_tailroom ( iobuf ),
00368                                             "blksize%c%d%ctsize%c0", 0,
00369                                             tftp_request_blksize, 0, 0 ) + 1 );
00370         }
00371         if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
00372                 iob_put ( iobuf, snprintf ( iobuf->tail,
00373                                             iob_tailroom ( iobuf ),
00374                                             "multicast%c", 0 ) + 1 );
00375         }
00376 
00377         /* RRQ always goes to the address specified in the initial
00378          * xfer_open() call
00379          */
00380         return xfer_deliver_iob ( &tftp->socket, iobuf );
00381 }
00382 
00383 /**
00384  * Transmit ACK
00385  *
00386  * @v tftp              TFTP connection
00387  * @ret rc              Return status code
00388  */
00389 static int tftp_send_ack ( struct tftp_request *tftp ) {
00390         struct tftp_ack *ack;
00391         struct io_buffer *iobuf;
00392         struct xfer_metadata meta = {
00393                 .dest = ( struct sockaddr * ) &tftp->peer,
00394         };
00395         unsigned int block;
00396 
00397         /* Determine next required block number */
00398         block = bitmap_first_gap ( &tftp->bitmap );
00399         DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block );
00400 
00401         /* Allocate buffer */
00402         iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
00403         if ( ! iobuf )
00404                 return -ENOMEM;
00405 
00406         /* Build ACK */
00407         ack = iob_put ( iobuf, sizeof ( *ack ) );
00408         ack->opcode = htons ( TFTP_ACK );
00409         ack->block = htons ( block );
00410 
00411         /* ACK always goes to the peer recorded from the RRQ response */
00412         return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
00413 }
00414 
00415 /**
00416  * Transmit ERROR (Abort)
00417  *
00418  * @v tftp              TFTP connection
00419  * @v errcode           TFTP error code
00420  * @v errmsg            Error message string
00421  * @ret rc              Return status code
00422  */
00423 static int tftp_send_error ( struct tftp_request *tftp, int errcode,
00424                              const char *errmsg ) {
00425         struct tftp_error *err;
00426         struct io_buffer *iobuf;
00427         struct xfer_metadata meta = {
00428                 .dest = ( struct sockaddr * ) &tftp->peer,
00429         };
00430         size_t msglen;
00431 
00432         DBGC2 ( tftp, "TFTP %p sending ERROR %d: %s\n", tftp, errcode,
00433                 errmsg );
00434 
00435         /* Allocate buffer */
00436         msglen = sizeof ( *err ) + strlen ( errmsg ) + 1 /* NUL */;
00437         iobuf = xfer_alloc_iob ( &tftp->socket, msglen );
00438         if ( ! iobuf )
00439                 return -ENOMEM;
00440 
00441         /* Build ERROR */
00442         err = iob_put ( iobuf, msglen );
00443         err->opcode = htons ( TFTP_ERROR );
00444         err->errcode = htons ( errcode );
00445         strcpy ( err->errmsg, errmsg );
00446 
00447         /* ERR always goes to the peer recorded from the RRQ response */
00448         return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
00449 }
00450 
00451 /**
00452  * Transmit next relevant packet
00453  *
00454  * @v tftp              TFTP connection
00455  * @ret rc              Return status code
00456  */
00457 static int tftp_send_packet ( struct tftp_request *tftp ) {
00458 
00459         /* Update retransmission timer.  While name resolution takes place the
00460          * window is zero.  Avoid unnecessary delay after name resolution
00461          * completes by retrying immediately.
00462          */
00463         stop_timer ( &tftp->timer );
00464         if ( xfer_window ( &tftp->socket ) ) {
00465                 start_timer ( &tftp->timer );
00466         } else {
00467                 start_timer_nodelay ( &tftp->timer );
00468         }
00469 
00470         /* Send RRQ or ACK as appropriate */
00471         if ( ! tftp->peer.st_family ) {
00472                 return tftp_send_rrq ( tftp );
00473         } else {
00474                 if ( tftp->flags & TFTP_FL_SEND_ACK ) {
00475                         return tftp_send_ack ( tftp );
00476                 } else {
00477                         return 0;
00478                 }
00479         }
00480 }
00481 
00482 /**
00483  * Handle TFTP retransmission timer expiry
00484  *
00485  * @v timer             Retry timer
00486  * @v fail              Failure indicator
00487  */
00488 static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
00489         struct tftp_request *tftp =
00490                 container_of ( timer, struct tftp_request, timer );
00491         int rc;
00492 
00493         /* If we are doing MTFTP, attempt the various recovery strategies */
00494         if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) {
00495                 if ( tftp->peer.st_family ) {
00496                         /* If we have received any response from the server,
00497                          * try resending the RRQ to restart the download.
00498                          */
00499                         DBGC ( tftp, "TFTP %p attempting reopen\n", tftp );
00500                         if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
00501                                 goto err;
00502                 } else {
00503                         /* Fall back to plain TFTP after several attempts */
00504                         tftp->mtftp_timeouts++;
00505                         DBGC ( tftp, "TFTP %p timeout %d waiting for MTFTP "
00506                                "open\n", tftp, tftp->mtftp_timeouts );
00507 
00508                         if ( tftp->mtftp_timeouts > MTFTP_MAX_TIMEOUTS ) {
00509                                 DBGC ( tftp, "TFTP %p falling back to plain "
00510                                        "TFTP\n", tftp );
00511                                 tftp->flags = TFTP_FL_RRQ_SIZES;
00512 
00513                                 /* Close multicast socket */
00514                                 xfer_close ( &tftp->mc_socket, 0 );
00515 
00516                                 /* Reset retry timer */
00517                                 start_timer_nodelay ( &tftp->timer );
00518 
00519                                 /* The blocksize may change: discard
00520                                  * the block bitmap
00521                                  */
00522                                 bitmap_free ( &tftp->bitmap );
00523                                 memset ( &tftp->bitmap, 0,
00524                                          sizeof ( tftp->bitmap ) );
00525 
00526                                 /* Reopen on standard TFTP port */
00527                                 tftp->port = TFTP_PORT;
00528                                 if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
00529                                         goto err;
00530                         }
00531                 }
00532         } else {
00533                 /* Not doing MTFTP (or have fallen back to plain
00534                  * TFTP); fail as per normal.
00535                  */
00536                 if ( fail ) {
00537                         rc = -ETIMEDOUT;
00538                         goto err;
00539                 }
00540         }
00541         tftp_send_packet ( tftp );
00542         return;
00543 
00544  err:
00545         tftp_done ( tftp, rc );
00546 }
00547 
00548 /**
00549  * Process TFTP "blksize" option
00550  *
00551  * @v tftp              TFTP connection
00552  * @v value             Option value
00553  * @ret rc              Return status code
00554  */
00555 static int tftp_process_blksize ( struct tftp_request *tftp,
00556                                   const char *value ) {
00557         char *end;
00558 
00559         tftp->blksize = strtoul ( value, &end, 10 );
00560         if ( *end ) {
00561                 DBGC ( tftp, "TFTP %p got invalid blksize \"%s\"\n",
00562                        tftp, value );
00563                 return -( EINVAL | ETFTP_INVALID_BLKSIZE );
00564         }
00565         DBGC ( tftp, "TFTP %p blksize=%d\n", tftp, tftp->blksize );
00566 
00567         return 0;
00568 }
00569 
00570 /**
00571  * Process TFTP "tsize" option
00572  *
00573  * @v tftp              TFTP connection
00574  * @v value             Option value
00575  * @ret rc              Return status code
00576  */
00577 static int tftp_process_tsize ( struct tftp_request *tftp,
00578                                 const char *value ) {
00579         char *end;
00580 
00581         tftp->tsize = strtoul ( value, &end, 10 );
00582         if ( *end ) {
00583                 DBGC ( tftp, "TFTP %p got invalid tsize \"%s\"\n",
00584                        tftp, value );
00585                 return -( EINVAL | ETFTP_INVALID_TSIZE );
00586         }
00587         DBGC ( tftp, "TFTP %p tsize=%ld\n", tftp, tftp->tsize );
00588 
00589         return 0;
00590 }
00591 
00592 /**
00593  * Process TFTP "multicast" option
00594  *
00595  * @v tftp              TFTP connection
00596  * @v value             Option value
00597  * @ret rc              Return status code
00598  */
00599 static int tftp_process_multicast ( struct tftp_request *tftp,
00600                                     const char *value ) {
00601         union {
00602                 struct sockaddr sa;
00603                 struct sockaddr_in sin;
00604         } socket;
00605         char buf[ strlen ( value ) + 1 ];
00606         char *addr;
00607         char *port;
00608         char *port_end;
00609         char *mc;
00610         char *mc_end;
00611         int rc;
00612 
00613         /* Split value into "addr,port,mc" fields */
00614         memcpy ( buf, value, sizeof ( buf ) );
00615         addr = buf;
00616         port = strchr ( addr, ',' );
00617         if ( ! port ) {
00618                 DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp );
00619                 return -( EINVAL | ETFTP_MC_NO_PORT );
00620         }
00621         *(port++) = '\0';
00622         mc = strchr ( port, ',' );
00623         if ( ! mc ) {
00624                 DBGC ( tftp, "TFTP %p multicast missing mc\n", tftp );
00625                 return -( EINVAL | ETFTP_MC_NO_MC );
00626         }
00627         *(mc++) = '\0';
00628 
00629         /* Parse parameters */
00630         if ( strtoul ( mc, &mc_end, 0 ) == 0 )
00631                 tftp->flags &= ~TFTP_FL_SEND_ACK;
00632         if ( *mc_end ) {
00633                 DBGC ( tftp, "TFTP %p multicast invalid mc %s\n", tftp, mc );
00634                 return -( EINVAL | ETFTP_MC_INVALID_MC );
00635         }
00636         DBGC ( tftp, "TFTP %p is%s the master client\n",
00637                tftp, ( ( tftp->flags & TFTP_FL_SEND_ACK ) ? "" : " not" ) );
00638         if ( *addr && *port ) {
00639                 socket.sin.sin_family = AF_INET;
00640                 if ( inet_aton ( addr, &socket.sin.sin_addr ) == 0 ) {
00641                         DBGC ( tftp, "TFTP %p multicast invalid IP address "
00642                                "%s\n", tftp, addr );
00643                         return -( EINVAL | ETFTP_MC_INVALID_IP );
00644                 }
00645                 DBGC ( tftp, "TFTP %p multicast IP address %s\n",
00646                        tftp, inet_ntoa ( socket.sin.sin_addr ) );
00647                 socket.sin.sin_port = htons ( strtoul ( port, &port_end, 0 ) );
00648                 if ( *port_end ) {
00649                         DBGC ( tftp, "TFTP %p multicast invalid port %s\n",
00650                                tftp, port );
00651                         return -( EINVAL | ETFTP_MC_INVALID_PORT );
00652                 }
00653                 DBGC ( tftp, "TFTP %p multicast port %d\n",
00654                        tftp, ntohs ( socket.sin.sin_port ) );
00655                 if ( ( rc = tftp_reopen_mc ( tftp, &socket.sa ) ) != 0 )
00656                         return rc;
00657         }
00658 
00659         return 0;
00660 }
00661 
00662 /** A TFTP option */
00663 struct tftp_option {
00664         /** Option name */
00665         const char *name;
00666         /** Option processor
00667          *
00668          * @v tftp      TFTP connection
00669          * @v value     Option value
00670          * @ret rc      Return status code
00671          */
00672         int ( * process ) ( struct tftp_request *tftp, const char *value );
00673 };
00674 
00675 /** Recognised TFTP options */
00676 static struct tftp_option tftp_options[] = {
00677         { "blksize", tftp_process_blksize },
00678         { "tsize", tftp_process_tsize },
00679         { "multicast", tftp_process_multicast },
00680         { NULL, NULL }
00681 };
00682 
00683 /**
00684  * Process TFTP option
00685  *
00686  * @v tftp              TFTP connection
00687  * @v name              Option name
00688  * @v value             Option value
00689  * @ret rc              Return status code
00690  */
00691 static int tftp_process_option ( struct tftp_request *tftp,
00692                                  const char *name, const char *value ) {
00693         struct tftp_option *option;
00694 
00695         for ( option = tftp_options ; option->name ; option++ ) {
00696                 if ( strcasecmp ( name, option->name ) == 0 )
00697                         return option->process ( tftp, value );
00698         }
00699 
00700         DBGC ( tftp, "TFTP %p received unknown option \"%s\" = \"%s\"\n",
00701                tftp, name, value );
00702 
00703         /* Unknown options should be silently ignored */
00704         return 0;
00705 }
00706 
00707 /**
00708  * Receive OACK
00709  *
00710  * @v tftp              TFTP connection
00711  * @v buf               Temporary data buffer
00712  * @v len               Length of temporary data buffer
00713  * @ret rc              Return status code
00714  */
00715 static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
00716         struct tftp_oack *oack = buf;
00717         char *end = buf + len;
00718         char *name;
00719         char *value;
00720         char *next;
00721         int rc = 0;
00722 
00723         /* Sanity check */
00724         if ( len < sizeof ( *oack ) ) {
00725                 DBGC ( tftp, "TFTP %p received underlength OACK packet "
00726                        "length %zd\n", tftp, len );
00727                 rc = -EINVAL;
00728                 goto done;
00729         }
00730 
00731         /* Process each option in turn */
00732         for ( name = oack->data ; name < end ; name = next ) {
00733 
00734                 /* Parse option name and value
00735                  *
00736                  * We treat parsing errors as non-fatal, because there
00737                  * exists at least one TFTP server (IBM Tivoli PXE
00738                  * Server 5.1.0.3) that has been observed to send
00739                  * malformed OACKs containing trailing garbage bytes.
00740                  */
00741                 value = ( name + strnlen ( name, ( end - name ) ) + 1 );
00742                 if ( value > end ) {
00743                         DBGC ( tftp, "TFTP %p received OACK with malformed "
00744                                "option name:\n", tftp );
00745                         DBGC_HD ( tftp, oack, len );
00746                         break;
00747                 }
00748                 if ( value == end ) {
00749                         DBGC ( tftp, "TFTP %p received OACK missing value "
00750                                "for option \"%s\"\n", tftp, name );
00751                         DBGC_HD ( tftp, oack, len );
00752                         break;
00753                 }
00754                 next = ( value + strnlen ( value, ( end - value ) ) + 1 );
00755                 if ( next > end ) {
00756                         DBGC ( tftp, "TFTP %p received OACK with malformed "
00757                                "value for option \"%s\":\n", tftp, name );
00758                         DBGC_HD ( tftp, oack, len );
00759                         break;
00760                 }
00761 
00762                 /* Process option */
00763                 if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
00764                         goto done;
00765         }
00766 
00767         /* Process tsize information, if available */
00768         if ( tftp->tsize ) {
00769                 if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 )
00770                         goto done;
00771         }
00772 
00773         /* Abort request if only trying to determine file size */
00774         if ( tftp->flags & TFTP_FL_SIZEONLY ) {
00775                 rc = 0;
00776                 tftp_send_error ( tftp, 0, "TFTP Aborted" );
00777                 tftp_done ( tftp, rc );
00778                 return rc;
00779         }
00780 
00781         /* Request next data block */
00782         tftp_send_packet ( tftp );
00783 
00784  done:
00785         if ( rc )
00786                 tftp_done ( tftp, rc );
00787         return rc;
00788 }
00789 
00790 /**
00791  * Receive DATA
00792  *
00793  * @v tftp              TFTP connection
00794  * @v iobuf             I/O buffer
00795  * @ret rc              Return status code
00796  *
00797  * Takes ownership of I/O buffer.
00798  */
00799 static int tftp_rx_data ( struct tftp_request *tftp,
00800                           struct io_buffer *iobuf ) {
00801         struct tftp_data *data = iobuf->data;
00802         struct xfer_metadata meta;
00803         unsigned int block;
00804         off_t offset;
00805         size_t data_len;
00806         int rc;
00807 
00808         if ( tftp->flags & TFTP_FL_SIZEONLY ) {
00809                 /* If we get here then server doesn't support SIZE option */
00810                 rc = -ENOTSUP;
00811                 tftp_send_error ( tftp, 0, "TFTP Aborted" );
00812                 goto done;
00813         }
00814 
00815         /* Sanity check */
00816         if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
00817                 DBGC ( tftp, "TFTP %p received underlength DATA packet "
00818                        "length %zd\n", tftp, iob_len ( iobuf ) );
00819                 rc = -EINVAL;
00820                 goto done;
00821         }
00822 
00823         /* Calculate block number */
00824         block = ( ( bitmap_first_gap ( &tftp->bitmap ) + 1 ) & ~0xffff );
00825         if ( data->block == 0 && block == 0 ) {
00826                 DBGC ( tftp, "TFTP %p received data block 0\n", tftp );
00827                 rc = -EINVAL;
00828                 goto done;
00829         }
00830         block += ( ntohs ( data->block ) - 1 );
00831 
00832         /* Extract data */
00833         offset = ( block * tftp->blksize );
00834         iob_pull ( iobuf, sizeof ( *data ) );
00835         data_len = iob_len ( iobuf );
00836         if ( data_len > tftp->blksize ) {
00837                 DBGC ( tftp, "TFTP %p received overlength DATA packet "
00838                        "length %zd\n", tftp, data_len );
00839                 rc = -EINVAL;
00840                 goto done;
00841         }
00842 
00843         /* Deliver data */
00844         memset ( &meta, 0, sizeof ( meta ) );
00845         meta.whence = SEEK_SET;
00846         meta.offset = offset;
00847         if ( ( rc = xfer_deliver_iob_meta ( &tftp->xfer, iob_disown ( iobuf ),
00848                                             &meta ) ) != 0 ) {
00849                 DBGC ( tftp, "TFTP %p could not deliver data: %s\n",
00850                        tftp, strerror ( rc ) );
00851                 goto done;
00852         }
00853 
00854         /* Ensure block bitmap is ready */
00855         if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 )
00856                 goto done;
00857 
00858         /* Mark block as received */
00859         bitmap_set ( &tftp->bitmap, block );
00860 
00861         /* Acknowledge block */
00862         tftp_send_packet ( tftp );
00863 
00864         /* If all blocks have been received, finish. */
00865         if ( bitmap_full ( &tftp->bitmap ) )
00866                 tftp_done ( tftp, 0 );
00867 
00868  done:
00869         free_iob ( iobuf );
00870         if ( rc )
00871                 tftp_done ( tftp, rc );
00872         return rc;
00873 }
00874 
00875 /** Translation between TFTP errors and internal error numbers */
00876 static const int tftp_errors[] = {
00877         [TFTP_ERR_FILE_NOT_FOUND]       = ENOENT,
00878         [TFTP_ERR_ACCESS_DENIED]        = EACCES,
00879         [TFTP_ERR_ILLEGAL_OP]           = ENOTSUP,
00880 };
00881 
00882 /**
00883  * Receive ERROR
00884  *
00885  * @v tftp              TFTP connection
00886  * @v buf               Temporary data buffer
00887  * @v len               Length of temporary data buffer
00888  * @ret rc              Return status code
00889  */
00890 static int tftp_rx_error ( struct tftp_request *tftp, void *buf, size_t len ) {
00891         struct tftp_error *error = buf;
00892         unsigned int err;
00893         int rc = 0;
00894 
00895         /* Sanity check */
00896         if ( len < sizeof ( *error ) ) {
00897                 DBGC ( tftp, "TFTP %p received underlength ERROR packet "
00898                        "length %zd\n", tftp, len );
00899                 return -EINVAL;
00900         }
00901 
00902         DBGC ( tftp, "TFTP %p received ERROR packet with code %d, message "
00903                "\"%s\"\n", tftp, ntohs ( error->errcode ), error->errmsg );
00904         
00905         /* Determine final operation result */
00906         err = ntohs ( error->errcode );
00907         if ( err < ( sizeof ( tftp_errors ) / sizeof ( tftp_errors[0] ) ) )
00908                 rc = -tftp_errors[err];
00909         if ( ! rc )
00910                 rc = -ENOTSUP;
00911 
00912         /* Close TFTP request */
00913         tftp_done ( tftp, rc );
00914 
00915         return 0;
00916 }
00917 
00918 /**
00919  * Receive new data
00920  *
00921  * @v tftp              TFTP connection
00922  * @v iobuf             I/O buffer
00923  * @v meta              Transfer metadata
00924  * @ret rc              Return status code
00925  */
00926 static int tftp_rx ( struct tftp_request *tftp,
00927                      struct io_buffer *iobuf,
00928                      struct xfer_metadata *meta ) {
00929         struct sockaddr_tcpip *st_src;
00930         struct tftp_common *common = iobuf->data;
00931         size_t len = iob_len ( iobuf );
00932         int rc = -EINVAL;
00933         
00934         /* Sanity checks */
00935         if ( len < sizeof ( *common ) ) {
00936                 DBGC ( tftp, "TFTP %p received underlength packet length "
00937                        "%zd\n", tftp, len );
00938                 goto done;
00939         }
00940         if ( ! meta->src ) {
00941                 DBGC ( tftp, "TFTP %p received packet without source port\n",
00942                        tftp );
00943                 goto done;
00944         }
00945 
00946         /* Filter by TID.  Set TID on first response received */
00947         st_src = ( struct sockaddr_tcpip * ) meta->src;
00948         if ( ! tftp->peer.st_family ) {
00949                 memcpy ( &tftp->peer, st_src, sizeof ( tftp->peer ) );
00950                 DBGC ( tftp, "TFTP %p using remote port %d\n", tftp,
00951                        ntohs ( tftp->peer.st_port ) );
00952         } else if ( memcmp ( &tftp->peer, st_src,
00953                              sizeof ( tftp->peer ) ) != 0 ) {
00954                 DBGC ( tftp, "TFTP %p received packet from wrong source (got "
00955                        "%d, wanted %d)\n", tftp, ntohs ( st_src->st_port ),
00956                        ntohs ( tftp->peer.st_port ) );
00957                 goto done;
00958         }
00959 
00960         switch ( common->opcode ) {
00961         case htons ( TFTP_OACK ):
00962                 rc = tftp_rx_oack ( tftp, iobuf->data, len );
00963                 break;
00964         case htons ( TFTP_DATA ):
00965                 rc = tftp_rx_data ( tftp, iob_disown ( iobuf ) );
00966                 break;
00967         case htons ( TFTP_ERROR ):
00968                 rc = tftp_rx_error ( tftp, iobuf->data, len );
00969                 break;
00970         default:
00971                 DBGC ( tftp, "TFTP %p received strange packet type %d\n",
00972                        tftp, ntohs ( common->opcode ) );
00973                 break;
00974         };
00975 
00976  done:
00977         free_iob ( iobuf );
00978         return rc;
00979 }
00980 
00981 /**
00982  * Receive new data via socket
00983  *
00984  * @v socket            Transport layer interface
00985  * @v iobuf             I/O buffer
00986  * @v meta              Transfer metadata
00987  * @ret rc              Return status code
00988  */
00989 static int tftp_socket_deliver_iob ( struct xfer_interface *socket,
00990                                      struct io_buffer *iobuf,
00991                                      struct xfer_metadata *meta ) {
00992         struct tftp_request *tftp =
00993                 container_of ( socket, struct tftp_request, socket );
00994 
00995         /* Enable sending ACKs when we receive a unicast packet.  This
00996          * covers three cases:
00997          *
00998          * 1. Standard TFTP; we should always send ACKs, and will
00999          *    always receive a unicast packet before we need to send the
01000          *    first ACK.
01001          *
01002          * 2. RFC2090 multicast TFTP; the only unicast packets we will
01003          *    receive are the OACKs; enable sending ACKs here (before
01004          *    processing the OACK) and disable it when processing the
01005          *    multicast option if we are not the master client.
01006          *
01007          * 3. MTFTP; receiving a unicast datagram indicates that we
01008          *    are the "master client" and should send ACKs.
01009          */
01010         tftp->flags |= TFTP_FL_SEND_ACK;
01011 
01012         return tftp_rx ( tftp, iobuf, meta );
01013 }
01014 
01015 /** TFTP socket operations */
01016 static struct xfer_interface_operations tftp_socket_operations = {
01017         .close          = ignore_xfer_close,
01018         .vredirect      = xfer_vreopen,
01019         .window         = unlimited_xfer_window,
01020         .alloc_iob      = default_xfer_alloc_iob,
01021         .deliver_iob    = tftp_socket_deliver_iob,
01022         .deliver_raw    = xfer_deliver_as_iob,
01023 };
01024 
01025 /**
01026  * Receive new data via multicast socket
01027  *
01028  * @v mc_socket         Multicast transport layer interface
01029  * @v iobuf             I/O buffer
01030  * @v meta              Transfer metadata
01031  * @ret rc              Return status code
01032  */
01033 static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket,
01034                                         struct io_buffer *iobuf,
01035                                         struct xfer_metadata *meta ) {
01036         struct tftp_request *tftp =
01037                 container_of ( mc_socket, struct tftp_request, mc_socket );
01038 
01039         return tftp_rx ( tftp, iobuf, meta );
01040 }
01041 
01042 /** TFTP multicast socket operations */
01043 static struct xfer_interface_operations tftp_mc_socket_operations = {
01044         .close          = ignore_xfer_close,
01045         .vredirect      = xfer_vreopen,
01046         .window         = unlimited_xfer_window,
01047         .alloc_iob      = default_xfer_alloc_iob,
01048         .deliver_iob    = tftp_mc_socket_deliver_iob,
01049         .deliver_raw    = xfer_deliver_as_iob,
01050 };
01051 
01052 /**
01053  * Close TFTP data transfer interface
01054  *
01055  * @v xfer              Data transfer interface
01056  * @v rc                Reason for close
01057  */
01058 static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) {
01059         struct tftp_request *tftp =
01060                 container_of ( xfer, struct tftp_request, xfer );
01061 
01062         DBGC ( tftp, "TFTP %p interface closed: %s\n",
01063                tftp, strerror ( rc ) );
01064 
01065         tftp_done ( tftp, rc );
01066 }
01067 
01068 /**
01069  * Check flow control window
01070  *
01071  * @v xfer              Data transfer interface
01072  * @ret len             Length of window
01073  */
01074 static size_t tftp_xfer_window ( struct xfer_interface *xfer ) {
01075         struct tftp_request *tftp =
01076                 container_of ( xfer, struct tftp_request, xfer );
01077 
01078         /* We abuse this data-xfer method to convey the blocksize to
01079          * the caller.  This really should be done using some kind of
01080          * stat() method, but we don't yet have the facility to do
01081          * that.
01082          */
01083         return tftp->blksize;
01084 }
01085 
01086 /** TFTP data transfer interface operations */
01087 static struct xfer_interface_operations tftp_xfer_operations = {
01088         .close          = tftp_xfer_close,
01089         .vredirect      = ignore_xfer_vredirect,
01090         .window         = tftp_xfer_window,
01091         .alloc_iob      = default_xfer_alloc_iob,
01092         .deliver_iob    = xfer_deliver_as_raw,
01093         .deliver_raw    = ignore_xfer_deliver_raw,
01094 };
01095 
01096 /**
01097  * Initiate TFTP/TFTM/MTFTP download
01098  *
01099  * @v xfer              Data transfer interface
01100  * @v uri               Uniform Resource Identifier
01101  * @ret rc              Return status code
01102  */
01103 static int tftp_core_open ( struct xfer_interface *xfer, struct uri *uri,
01104                             unsigned int default_port,
01105                             struct sockaddr *multicast,
01106                             unsigned int flags ) {
01107         struct tftp_request *tftp;
01108         int rc;
01109 
01110         /* Sanity checks */
01111         if ( ! uri->host )
01112                 return -EINVAL;
01113         if ( ! uri->path )
01114                 return -EINVAL;
01115 
01116         /* Allocate and populate TFTP structure */
01117         tftp = zalloc ( sizeof ( *tftp ) );
01118         if ( ! tftp )
01119                 return -ENOMEM;
01120         tftp->refcnt.free = tftp_free;
01121         xfer_init ( &tftp->xfer, &tftp_xfer_operations, &tftp->refcnt );
01122         tftp->uri = uri_get ( uri );
01123         xfer_init ( &tftp->socket, &tftp_socket_operations, &tftp->refcnt );
01124         xfer_init ( &tftp->mc_socket, &tftp_mc_socket_operations,
01125                     &tftp->refcnt );
01126         tftp->blksize = TFTP_DEFAULT_BLKSIZE;
01127         tftp->flags = flags;
01128         tftp->timer.expired = tftp_timer_expired;
01129 
01130         /* Open socket */
01131         tftp->port = uri_port ( tftp->uri, default_port );
01132         if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
01133                 goto err;
01134 
01135         /* Open multicast socket */
01136         if ( multicast ) {
01137                 if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
01138                         goto err;
01139         }
01140 
01141         /* Start timer to initiate RRQ */
01142         start_timer_nodelay ( &tftp->timer );
01143 
01144         /* Attach to parent interface, mortalise self, and return */
01145         xfer_plug_plug ( &tftp->xfer, xfer );
01146         ref_put ( &tftp->refcnt );
01147         return 0;
01148 
01149  err:
01150         DBGC ( tftp, "TFTP %p could not create request: %s\n",
01151                tftp, strerror ( rc ) );
01152         tftp_done ( tftp, rc );
01153         ref_put ( &tftp->refcnt );
01154         return rc;
01155 }
01156 
01157 /**
01158  * Initiate TFTP download
01159  *
01160  * @v xfer              Data transfer interface
01161  * @v uri               Uniform Resource Identifier
01162  * @ret rc              Return status code
01163  */
01164 static int tftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
01165         return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
01166                                 TFTP_FL_RRQ_SIZES );
01167 
01168 }
01169 
01170 /** TFTP URI opener */
01171 struct uri_opener tftp_uri_opener __uri_opener = {
01172         .scheme = "tftp",
01173         .open   = tftp_open,
01174 };
01175 
01176 /**
01177  * Initiate TFTP-size request
01178  *
01179  * @v xfer              Data transfer interface
01180  * @v uri               Uniform Resource Identifier
01181  * @ret rc              Return status code
01182  */
01183 static int tftpsize_open ( struct xfer_interface *xfer, struct uri *uri ) {
01184         return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
01185                                 ( TFTP_FL_RRQ_SIZES |
01186                                   TFTP_FL_SIZEONLY ) );
01187 
01188 }
01189 
01190 /** TFTP URI opener */
01191 struct uri_opener tftpsize_uri_opener __uri_opener = {
01192         .scheme = "tftpsize",
01193         .open   = tftpsize_open,
01194 };
01195 
01196 /**
01197  * Initiate TFTM download
01198  *
01199  * @v xfer              Data transfer interface
01200  * @v uri               Uniform Resource Identifier
01201  * @ret rc              Return status code
01202  */
01203 static int tftm_open ( struct xfer_interface *xfer, struct uri *uri ) {
01204         return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
01205                                 ( TFTP_FL_RRQ_SIZES |
01206                                   TFTP_FL_RRQ_MULTICAST ) );
01207 
01208 }
01209 
01210 /** TFTM URI opener */
01211 struct uri_opener tftm_uri_opener __uri_opener = {
01212         .scheme = "tftm",
01213         .open   = tftm_open,
01214 };
01215 
01216 /**
01217  * Initiate MTFTP download
01218  *
01219  * @v xfer              Data transfer interface
01220  * @v uri               Uniform Resource Identifier
01221  * @ret rc              Return status code
01222  */
01223 static int mtftp_open ( struct xfer_interface *xfer, struct uri *uri ) {
01224         return tftp_core_open ( xfer, uri, MTFTP_PORT,
01225                                 ( struct sockaddr * ) &tftp_mtftp_socket,
01226                                 TFTP_FL_MTFTP_RECOVERY );
01227 }
01228 
01229 /** MTFTP URI opener */
01230 struct uri_opener mtftp_uri_opener __uri_opener = {
01231         .scheme = "mtftp",
01232         .open   = mtftp_open,
01233 };
01234 
01235 /******************************************************************************
01236  *
01237  * Settings
01238  *
01239  ******************************************************************************
01240  */
01241 
01242 /** TFTP server setting */
01243 struct setting next_server_setting __setting = {
01244         .name = "next-server",
01245         .description = "TFTP server",
01246         .tag = DHCP_EB_SIADDR,
01247         .type = &setting_type_ipv4,
01248 };
01249 
01250 /**
01251  * Apply TFTP configuration settings
01252  *
01253  * @ret rc              Return status code
01254  */
01255 static int tftp_apply_settings ( void ) {
01256         static struct in_addr tftp_server = { 0 };
01257         struct in_addr last_tftp_server;
01258         char uri_string[32];
01259         struct uri *uri;
01260 
01261         /* Retrieve TFTP server setting */
01262         last_tftp_server = tftp_server;
01263         fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
01264 
01265         /* If TFTP server setting has changed, set the current working
01266          * URI to match.  Do it only when the TFTP server has changed
01267          * to try to minimise surprises to the user, who probably
01268          * won't expect the CWURI to change just because they updated
01269          * an unrelated setting and triggered all the settings
01270          * applicators.
01271          */
01272         if ( tftp_server.s_addr != last_tftp_server.s_addr ) {
01273                 snprintf ( uri_string, sizeof ( uri_string ),
01274                            "tftp://%s/", inet_ntoa ( tftp_server ) );
01275                 uri = parse_uri ( uri_string );
01276                 if ( ! uri )
01277                         return -ENOMEM;
01278                 churi ( uri );
01279                 uri_put ( uri );
01280         }
01281 
01282         return 0;
01283 }
01284 
01285 /** TFTP settings applicator */
01286 struct settings_applicator tftp_settings_applicator __settings_applicator = {
01287         .apply = tftp_apply_settings,
01288 };

Generated on Tue Apr 6 20:01:11 2010 for gPXE by  doxygen 1.5.7.1