00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00043
00044
00045
00046
00047
00048 FEATURE ( FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1 );
00049
00050
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
00061
00062
00063
00064 struct tftp_request {
00065
00066 struct refcnt refcnt;
00067
00068 struct xfer_interface xfer;
00069
00070
00071 struct uri *uri;
00072
00073 struct xfer_interface socket;
00074
00075 struct xfer_interface mc_socket;
00076
00077
00078
00079
00080
00081
00082
00083 unsigned int blksize;
00084
00085
00086
00087
00088
00089
00090 unsigned long tsize;
00091
00092
00093
00094
00095
00096 unsigned int port;
00097
00098
00099
00100
00101
00102 struct sockaddr_tcpip peer;
00103
00104 unsigned int flags;
00105
00106 unsigned int mtftp_timeouts;
00107
00108
00109 struct bitmap bitmap;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 size_t filesize;
00122
00123 struct retry_timer timer;
00124 };
00125
00126
00127 enum {
00128
00129 TFTP_FL_SEND_ACK = 0x0001,
00130
00131 TFTP_FL_RRQ_SIZES = 0x0002,
00132
00133 TFTP_FL_RRQ_MULTICAST = 0x0004,
00134
00135 TFTP_FL_MTFTP_RECOVERY = 0x0008,
00136
00137 TFTP_FL_SIZEONLY = 0x0010,
00138 };
00139
00140
00141 #define MTFTP_MAX_TIMEOUTS 3
00142
00143
00144
00145
00146
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
00159
00160
00161
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
00169 stop_timer ( &tftp->timer );
00170
00171
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
00182
00183
00184
00185
00186 static int tftp_reopen ( struct tftp_request *tftp ) {
00187 struct sockaddr_tcpip server;
00188 int rc;
00189
00190
00191 xfer_close ( &tftp->socket, 0 );
00192
00193
00194 tftp->flags &= ~TFTP_FL_SEND_ACK;
00195
00196
00197 memset ( &tftp->peer, 0, sizeof ( tftp->peer ) );
00198
00199
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
00215
00216
00217
00218
00219
00220 static int tftp_reopen_mc ( struct tftp_request *tftp,
00221 struct sockaddr *local ) {
00222 int rc;
00223
00224
00225 xfer_close ( &tftp->mc_socket, 0 );
00226
00227
00228
00229
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
00243
00244
00245
00246
00247
00248 static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
00249 unsigned int num_blocks;
00250 int rc;
00251
00252
00253 if ( filesize <= tftp->filesize )
00254 return 0;
00255
00256
00257 tftp->filesize = filesize;
00258
00259
00260 xfer_seek ( &tftp->xfer, filesize, SEEK_SET );
00261 xfer_seek ( &tftp->xfer, 0, SEEK_SET );
00262
00263
00264
00265
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
00279
00280
00281
00282 static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
00283
00284
00285
00286
00287
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
00297
00298
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
00308
00309
00310
00311 void tftp_set_mtftp_address ( struct in_addr address ) {
00312 tftp_mtftp_socket.sin_addr = address;
00313 }
00314
00315
00316
00317
00318
00319
00320 void tftp_set_mtftp_port ( unsigned int port ) {
00321 tftp_mtftp_socket.sin_port = htons ( port );
00322 }
00323
00324
00325
00326
00327
00328
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
00337
00338
00339
00340
00341
00342
00343
00344 path = tftp->uri->path;
00345 if ( *path == '/' )
00346 path++;
00347
00348 DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, path );
00349
00350
00351 len = ( sizeof ( *rrq ) + strlen ( path ) + 1
00352 + 5 + 1
00353 + 7 + 1 + 5 + 1
00354 + 5 + 1 + 1 + 1
00355 + 9 + 1 + 1 );
00356 iobuf = xfer_alloc_iob ( &tftp->socket, len );
00357 if ( ! iobuf )
00358 return -ENOMEM;
00359
00360
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
00378
00379
00380 return xfer_deliver_iob ( &tftp->socket, iobuf );
00381 }
00382
00383
00384
00385
00386
00387
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
00398 block = bitmap_first_gap ( &tftp->bitmap );
00399 DBGC2 ( tftp, "TFTP %p sending ACK for block %d\n", tftp, block );
00400
00401
00402 iobuf = xfer_alloc_iob ( &tftp->socket, sizeof ( *ack ) );
00403 if ( ! iobuf )
00404 return -ENOMEM;
00405
00406
00407 ack = iob_put ( iobuf, sizeof ( *ack ) );
00408 ack->opcode = htons ( TFTP_ACK );
00409 ack->block = htons ( block );
00410
00411
00412 return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
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
00436 msglen = sizeof ( *err ) + strlen ( errmsg ) + 1 ;
00437 iobuf = xfer_alloc_iob ( &tftp->socket, msglen );
00438 if ( ! iobuf )
00439 return -ENOMEM;
00440
00441
00442 err = iob_put ( iobuf, msglen );
00443 err->opcode = htons ( TFTP_ERROR );
00444 err->errcode = htons ( errcode );
00445 strcpy ( err->errmsg, errmsg );
00446
00447
00448 return xfer_deliver_iob_meta ( &tftp->socket, iobuf, &meta );
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 static int tftp_send_packet ( struct tftp_request *tftp ) {
00458
00459
00460
00461
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
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
00484
00485
00486
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
00494 if ( tftp->flags & TFTP_FL_MTFTP_RECOVERY ) {
00495 if ( tftp->peer.st_family ) {
00496
00497
00498
00499 DBGC ( tftp, "TFTP %p attempting reopen\n", tftp );
00500 if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
00501 goto err;
00502 } else {
00503
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
00514 xfer_close ( &tftp->mc_socket, 0 );
00515
00516
00517 start_timer_nodelay ( &tftp->timer );
00518
00519
00520
00521
00522 bitmap_free ( &tftp->bitmap );
00523 memset ( &tftp->bitmap, 0,
00524 sizeof ( tftp->bitmap ) );
00525
00526
00527 tftp->port = TFTP_PORT;
00528 if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
00529 goto err;
00530 }
00531 }
00532 } else {
00533
00534
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
00550
00551
00552
00553
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
00572
00573
00574
00575
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
00594
00595
00596
00597
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
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
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
00663 struct tftp_option {
00664
00665 const char *name;
00666
00667
00668
00669
00670
00671
00672 int ( * process ) ( struct tftp_request *tftp, const char *value );
00673 };
00674
00675
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
00685
00686
00687
00688
00689
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
00704 return 0;
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
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
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
00732 for ( name = oack->data ; name < end ; name = next ) {
00733
00734
00735
00736
00737
00738
00739
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
00763 if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
00764 goto done;
00765 }
00766
00767
00768 if ( tftp->tsize ) {
00769 if ( ( rc = tftp_presize ( tftp, tftp->tsize ) ) != 0 )
00770 goto done;
00771 }
00772
00773
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
00782 tftp_send_packet ( tftp );
00783
00784 done:
00785 if ( rc )
00786 tftp_done ( tftp, rc );
00787 return rc;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
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
00810 rc = -ENOTSUP;
00811 tftp_send_error ( tftp, 0, "TFTP Aborted" );
00812 goto done;
00813 }
00814
00815
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
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
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
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
00855 if ( ( rc = tftp_presize ( tftp, ( offset + data_len ) ) ) != 0 )
00856 goto done;
00857
00858
00859 bitmap_set ( &tftp->bitmap, block );
00860
00861
00862 tftp_send_packet ( tftp );
00863
00864
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
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
00884
00885
00886
00887
00888
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
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
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
00913 tftp_done ( tftp, rc );
00914
00915 return 0;
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
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
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
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
00983
00984
00985
00986
00987
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
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 tftp->flags |= TFTP_FL_SEND_ACK;
01011
01012 return tftp_rx ( tftp, iobuf, meta );
01013 }
01014
01015
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
01027
01028
01029
01030
01031
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
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
01054
01055
01056
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
01070
01071
01072
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
01079
01080
01081
01082
01083 return tftp->blksize;
01084 }
01085
01086
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
01098
01099
01100
01101
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
01111 if ( ! uri->host )
01112 return -EINVAL;
01113 if ( ! uri->path )
01114 return -EINVAL;
01115
01116
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
01131 tftp->port = uri_port ( tftp->uri, default_port );
01132 if ( ( rc = tftp_reopen ( tftp ) ) != 0 )
01133 goto err;
01134
01135
01136 if ( multicast ) {
01137 if ( ( rc = tftp_reopen_mc ( tftp, multicast ) ) != 0 )
01138 goto err;
01139 }
01140
01141
01142 start_timer_nodelay ( &tftp->timer );
01143
01144
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
01159
01160
01161
01162
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
01171 struct uri_opener tftp_uri_opener __uri_opener = {
01172 .scheme = "tftp",
01173 .open = tftp_open,
01174 };
01175
01176
01177
01178
01179
01180
01181
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
01191 struct uri_opener tftpsize_uri_opener __uri_opener = {
01192 .scheme = "tftpsize",
01193 .open = tftpsize_open,
01194 };
01195
01196
01197
01198
01199
01200
01201
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
01211 struct uri_opener tftm_uri_opener __uri_opener = {
01212 .scheme = "tftm",
01213 .open = tftm_open,
01214 };
01215
01216
01217
01218
01219
01220
01221
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
01230 struct uri_opener mtftp_uri_opener __uri_opener = {
01231 .scheme = "mtftp",
01232 .open = mtftp_open,
01233 };
01234
01235
01236
01237
01238
01239
01240
01241
01242
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
01252
01253
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
01262 last_tftp_server = tftp_server;
01263 fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
01264
01265
01266
01267
01268
01269
01270
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
01286 struct settings_applicator tftp_settings_applicator __settings_applicator = {
01287 .apply = tftp_apply_settings,
01288 };