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