1 /* 2 * Copyright 1994, 1995, 2000 Neil Russell. 3 * (See License) 4 * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de 5 * Copyright 2011 Comelit Group SpA, 6 * Luca Ceresoli <luca.ceresoli@comelit.it> 7 */ 8 9 #include <common.h> 10 #include <command.h> 11 #include <net.h> 12 #include "tftp.h" 13 #include "bootp.h" 14 15 /* Well known TFTP port # */ 16 #define WELL_KNOWN_PORT 69 17 /* Millisecs to timeout for lost pkt */ 18 #define TIMEOUT 5000UL 19 #ifndef CONFIG_NET_RETRY_COUNT 20 /* # of timeouts before giving up */ 21 # define TIMEOUT_COUNT 10 22 #else 23 # define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT * 2) 24 #endif 25 /* Number of "loading" hashes per line (for checking the image size) */ 26 #define HASHES_PER_LINE 65 27 28 /* 29 * TFTP operations. 30 */ 31 #define TFTP_RRQ 1 32 #define TFTP_WRQ 2 33 #define TFTP_DATA 3 34 #define TFTP_ACK 4 35 #define TFTP_ERROR 5 36 #define TFTP_OACK 6 37 38 static ulong TftpTimeoutMSecs = TIMEOUT; 39 static int TftpTimeoutCountMax = TIMEOUT_COUNT; 40 41 /* 42 * These globals govern the timeout behavior when attempting a connection to a 43 * TFTP server. TftpRRQTimeoutMSecs specifies the number of milliseconds to 44 * wait for the server to respond to initial connection. Second global, 45 * TftpRRQTimeoutCountMax, gives the number of such connection retries. 46 * TftpRRQTimeoutCountMax must be non-negative and TftpRRQTimeoutMSecs must be 47 * positive. The globals are meant to be set (and restored) by code needing 48 * non-standard timeout behavior when initiating a TFTP transfer. 49 */ 50 ulong TftpRRQTimeoutMSecs = TIMEOUT; 51 int TftpRRQTimeoutCountMax = TIMEOUT_COUNT; 52 53 enum { 54 TFTP_ERR_UNDEFINED = 0, 55 TFTP_ERR_FILE_NOT_FOUND = 1, 56 TFTP_ERR_ACCESS_DENIED = 2, 57 TFTP_ERR_DISK_FULL = 3, 58 TFTP_ERR_UNEXPECTED_OPCODE = 4, 59 TFTP_ERR_UNKNOWN_TRANSFER_ID = 5, 60 TFTP_ERR_FILE_ALREADY_EXISTS = 6, 61 }; 62 63 static IPaddr_t TftpRemoteIP; 64 /* The UDP port at their end */ 65 static int TftpRemotePort; 66 /* The UDP port at our end */ 67 static int TftpOurPort; 68 static int TftpTimeoutCount; 69 /* packet sequence number */ 70 static ulong TftpBlock; 71 /* last packet sequence number received */ 72 static ulong TftpLastBlock; 73 /* count of sequence number wraparounds */ 74 static ulong TftpBlockWrap; 75 /* memory offset due to wrapping */ 76 static ulong TftpBlockWrapOffset; 77 static int TftpState; 78 #ifdef CONFIG_TFTP_TSIZE 79 /* The file size reported by the server */ 80 static int TftpTsize; 81 /* The number of hashes we printed */ 82 static short TftpNumchars; 83 #endif 84 #ifdef CONFIG_CMD_TFTPPUT 85 static int TftpWriting; /* 1 if writing, else 0 */ 86 static int TftpFinalBlock; /* 1 if we have sent the last block */ 87 #else 88 #define TftpWriting 0 89 #endif 90 91 #define STATE_SEND_RRQ 1 92 #define STATE_DATA 2 93 #define STATE_TOO_LARGE 3 94 #define STATE_BAD_MAGIC 4 95 #define STATE_OACK 5 96 #define STATE_RECV_WRQ 6 97 #define STATE_SEND_WRQ 7 98 99 /* default TFTP block size */ 100 #define TFTP_BLOCK_SIZE 512 101 /* sequence number is 16 bit */ 102 #define TFTP_SEQUENCE_SIZE ((ulong)(1<<16)) 103 104 #define DEFAULT_NAME_LEN (8 + 4 + 1) 105 static char default_filename[DEFAULT_NAME_LEN]; 106 107 #ifndef CONFIG_TFTP_FILE_NAME_MAX_LEN 108 #define MAX_LEN 128 109 #else 110 #define MAX_LEN CONFIG_TFTP_FILE_NAME_MAX_LEN 111 #endif 112 113 static char tftp_filename[MAX_LEN]; 114 115 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP 116 extern flash_info_t flash_info[]; 117 #endif 118 119 /* 512 is poor choice for ethernet, MTU is typically 1500. 120 * Minus eth.hdrs thats 1468. Can get 2x better throughput with 121 * almost-MTU block sizes. At least try... fall back to 512 if need be. 122 * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file) 123 */ 124 #ifdef CONFIG_TFTP_BLOCKSIZE 125 #define TFTP_MTU_BLOCKSIZE CONFIG_TFTP_BLOCKSIZE 126 #else 127 #define TFTP_MTU_BLOCKSIZE 1468 128 #endif 129 130 static unsigned short TftpBlkSize = TFTP_BLOCK_SIZE; 131 static unsigned short TftpBlkSizeOption = TFTP_MTU_BLOCKSIZE; 132 133 #ifdef CONFIG_MCAST_TFTP 134 #include <malloc.h> 135 #define MTFTP_BITMAPSIZE 0x1000 136 static unsigned *Bitmap; 137 static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE; 138 static uchar ProhibitMcast, MasterClient; 139 static uchar Multicast; 140 extern IPaddr_t Mcast_addr; 141 static int Mcast_port; 142 static ulong TftpEndingBlock; /* can get 'last' block before done..*/ 143 144 static void parse_multicast_oack(char *pkt, int len); 145 146 static void 147 mcast_cleanup(void) 148 { 149 if (Mcast_addr) 150 eth_mcast_join(Mcast_addr, 0); 151 if (Bitmap) 152 free(Bitmap); 153 Bitmap = NULL; 154 Mcast_addr = Multicast = Mcast_port = 0; 155 TftpEndingBlock = -1; 156 } 157 158 #endif /* CONFIG_MCAST_TFTP */ 159 160 static __inline__ void 161 store_block(unsigned block, uchar *src, unsigned len) 162 { 163 ulong offset = block * TftpBlkSize + TftpBlockWrapOffset; 164 ulong newsize = offset + len; 165 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP 166 int i, rc = 0; 167 168 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { 169 /* start address in flash? */ 170 if (flash_info[i].flash_id == FLASH_UNKNOWN) 171 continue; 172 if (load_addr + offset >= flash_info[i].start[0]) { 173 rc = 1; 174 break; 175 } 176 } 177 178 if (rc) { /* Flash is destination for this packet */ 179 rc = flash_write((char *)src, (ulong)(load_addr+offset), len); 180 if (rc) { 181 flash_perror(rc); 182 NetState = NETLOOP_FAIL; 183 return; 184 } 185 } 186 else 187 #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */ 188 { 189 (void)memcpy((void *)(load_addr + offset), src, len); 190 } 191 #ifdef CONFIG_MCAST_TFTP 192 if (Multicast) 193 ext2_set_bit(block, Bitmap); 194 #endif 195 196 if (NetBootFileXferSize < newsize) 197 NetBootFileXferSize = newsize; 198 } 199 200 /* Clear our state ready for a new transfer */ 201 static void new_transfer(void) 202 { 203 TftpLastBlock = 0; 204 TftpBlockWrap = 0; 205 TftpBlockWrapOffset = 0; 206 #ifdef CONFIG_CMD_TFTPPUT 207 TftpFinalBlock = 0; 208 #endif 209 } 210 211 #ifdef CONFIG_CMD_TFTPPUT 212 /** 213 * Load the next block from memory to be sent over tftp. 214 * 215 * @param block Block number to send 216 * @param dst Destination buffer for data 217 * @param len Number of bytes in block (this one and every other) 218 * @return number of bytes loaded 219 */ 220 static int load_block(unsigned block, uchar *dst, unsigned len) 221 { 222 /* We may want to get the final block from the previous set */ 223 ulong offset = ((int)block - 1) * len + TftpBlockWrapOffset; 224 ulong tosend = len; 225 226 tosend = min(NetBootFileXferSize - offset, tosend); 227 (void)memcpy(dst, (void *)(save_addr + offset), tosend); 228 debug("%s: block=%d, offset=%ld, len=%d, tosend=%ld\n", __func__, 229 block, offset, len, tosend); 230 return tosend; 231 } 232 #endif 233 234 static void TftpSend(void); 235 static void TftpTimeout(void); 236 237 /**********************************************************************/ 238 239 static void show_block_marker(void) 240 { 241 #ifdef CONFIG_TFTP_TSIZE 242 if (TftpTsize) { 243 ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset; 244 245 while (TftpNumchars < pos * 50 / TftpTsize) { 246 putc('#'); 247 TftpNumchars++; 248 } 249 } else 250 #endif 251 { 252 if (((TftpBlock - 1) % 10) == 0) 253 putc('#'); 254 else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) 255 puts("\n\t "); 256 } 257 } 258 259 /** 260 * restart the current transfer due to an error 261 * 262 * @param msg Message to print for user 263 */ 264 static void restart(const char *msg) 265 { 266 printf("\n%s; starting again\n", msg); 267 #ifdef CONFIG_MCAST_TFTP 268 mcast_cleanup(); 269 #endif 270 NetStartAgain(); 271 } 272 273 /* 274 * Check if the block number has wrapped, and update progress 275 * 276 * TODO: The egregious use of global variables in this file should be tidied. 277 */ 278 static void update_block_number(void) 279 { 280 /* 281 * RFC1350 specifies that the first data packet will 282 * have sequence number 1. If we receive a sequence 283 * number of 0 this means that there was a wrap 284 * around of the (16 bit) counter. 285 */ 286 if (TftpBlock == 0) { 287 TftpBlockWrap++; 288 TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE; 289 TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */ 290 } else { 291 show_block_marker(); 292 } 293 } 294 295 /* The TFTP get or put is complete */ 296 static void tftp_complete(void) 297 { 298 #ifdef CONFIG_TFTP_TSIZE 299 /* Print hash marks for the last packet received */ 300 while (TftpTsize && TftpNumchars < 49) { 301 putc('#'); 302 TftpNumchars++; 303 } 304 #endif 305 puts("\ndone\n"); 306 NetState = NETLOOP_SUCCESS; 307 } 308 309 static void 310 TftpSend(void) 311 { 312 uchar *pkt; 313 volatile uchar *xp; 314 int len = 0; 315 volatile ushort *s; 316 317 #ifdef CONFIG_MCAST_TFTP 318 /* Multicast TFTP.. non-MasterClients do not ACK data. */ 319 if (Multicast 320 && (TftpState == STATE_DATA) 321 && (MasterClient == 0)) 322 return; 323 #endif 324 /* 325 * We will always be sending some sort of packet, so 326 * cobble together the packet headers now. 327 */ 328 pkt = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE); 329 330 switch (TftpState) { 331 case STATE_SEND_RRQ: 332 case STATE_SEND_WRQ: 333 xp = pkt; 334 s = (ushort *)pkt; 335 #ifdef CONFIG_CMD_TFTPPUT 336 *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ : 337 TFTP_WRQ); 338 #else 339 *s++ = htons(TFTP_RRQ); 340 #endif 341 pkt = (uchar *)s; 342 strcpy((char *)pkt, tftp_filename); 343 pkt += strlen(tftp_filename) + 1; 344 strcpy((char *)pkt, "octet"); 345 pkt += 5 /*strlen("octet")*/ + 1; 346 strcpy((char *)pkt, "timeout"); 347 pkt += 7 /*strlen("timeout")*/ + 1; 348 sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000); 349 debug("send option \"timeout %s\"\n", (char *)pkt); 350 pkt += strlen((char *)pkt) + 1; 351 #ifdef CONFIG_TFTP_TSIZE 352 pkt += sprintf((char *)pkt, "tsize%c%lu%c", 353 0, NetBootFileXferSize, 0); 354 #endif 355 /* try for more effic. blk size */ 356 pkt += sprintf((char *)pkt, "blksize%c%d%c", 357 0, TftpBlkSizeOption, 0); 358 #ifdef CONFIG_MCAST_TFTP 359 /* Check all preconditions before even trying the option */ 360 if (!ProhibitMcast 361 && (Bitmap = malloc(Mapsize)) 362 && eth_get_dev()->mcast) { 363 free(Bitmap); 364 Bitmap = NULL; 365 pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0); 366 } 367 #endif /* CONFIG_MCAST_TFTP */ 368 len = pkt - xp; 369 break; 370 371 case STATE_OACK: 372 #ifdef CONFIG_MCAST_TFTP 373 /* My turn! Start at where I need blocks I missed.*/ 374 if (Multicast) 375 TftpBlock = ext2_find_next_zero_bit(Bitmap, 376 (Mapsize*8), 0); 377 /*..falling..*/ 378 #endif 379 380 case STATE_RECV_WRQ: 381 case STATE_DATA: 382 xp = pkt; 383 s = (ushort *)pkt; 384 s[0] = htons(TFTP_ACK); 385 s[1] = htons(TftpBlock); 386 pkt = (uchar *)(s + 2); 387 #ifdef CONFIG_CMD_TFTPPUT 388 if (TftpWriting) { 389 int toload = TftpBlkSize; 390 int loaded = load_block(TftpBlock, pkt, toload); 391 392 s[0] = htons(TFTP_DATA); 393 pkt += loaded; 394 TftpFinalBlock = (loaded < toload); 395 } 396 #endif 397 len = pkt - xp; 398 break; 399 400 case STATE_TOO_LARGE: 401 xp = pkt; 402 s = (ushort *)pkt; 403 *s++ = htons(TFTP_ERROR); 404 *s++ = htons(3); 405 406 pkt = (uchar *)s; 407 strcpy((char *)pkt, "File too large"); 408 pkt += 14 /*strlen("File too large")*/ + 1; 409 len = pkt - xp; 410 break; 411 412 case STATE_BAD_MAGIC: 413 xp = pkt; 414 s = (ushort *)pkt; 415 *s++ = htons(TFTP_ERROR); 416 *s++ = htons(2); 417 pkt = (uchar *)s; 418 strcpy((char *)pkt, "File has bad magic"); 419 pkt += 18 /*strlen("File has bad magic")*/ + 1; 420 len = pkt - xp; 421 break; 422 } 423 424 NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort, 425 TftpOurPort, len); 426 } 427 428 #ifdef CONFIG_CMD_TFTPPUT 429 static void icmp_handler(unsigned type, unsigned code, unsigned dest, 430 IPaddr_t sip, unsigned src, uchar *pkt, unsigned len) 431 { 432 if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) { 433 /* Oh dear the other end has gone away */ 434 restart("TFTP server died"); 435 } 436 } 437 #endif 438 439 static void 440 TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 441 unsigned len) 442 { 443 ushort proto; 444 ushort *s; 445 int i; 446 447 if (dest != TftpOurPort) { 448 #ifdef CONFIG_MCAST_TFTP 449 if (Multicast 450 && (!Mcast_port || (dest != Mcast_port))) 451 #endif 452 return; 453 } 454 if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && 455 TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ) 456 return; 457 458 if (len < 2) 459 return; 460 len -= 2; 461 /* warning: don't use increment (++) in ntohs() macros!! */ 462 s = (ushort *)pkt; 463 proto = *s++; 464 pkt = (uchar *)s; 465 switch (ntohs(proto)) { 466 467 case TFTP_RRQ: 468 break; 469 470 case TFTP_ACK: 471 #ifdef CONFIG_CMD_TFTPPUT 472 if (TftpWriting) { 473 if (TftpFinalBlock) { 474 tftp_complete(); 475 } else { 476 /* 477 * Move to the next block. We want our block 478 * count to wrap just like the other end! 479 */ 480 int block = ntohs(*s); 481 int ack_ok = (TftpBlock == block); 482 483 TftpBlock = (unsigned short)(block + 1); 484 update_block_number(); 485 if (ack_ok) 486 TftpSend(); /* Send next data block */ 487 } 488 } 489 #endif 490 break; 491 492 default: 493 break; 494 495 #ifdef CONFIG_CMD_TFTPSRV 496 case TFTP_WRQ: 497 debug("Got WRQ\n"); 498 TftpRemoteIP = sip; 499 TftpRemotePort = src; 500 TftpOurPort = 1024 + (get_timer(0) % 3072); 501 new_transfer(); 502 TftpSend(); /* Send ACK(0) */ 503 break; 504 #endif 505 506 case TFTP_OACK: 507 debug("Got OACK: %s %s\n", 508 pkt, 509 pkt + strlen((char *)pkt) + 1); 510 TftpState = STATE_OACK; 511 TftpRemotePort = src; 512 /* 513 * Check for 'blksize' option. 514 * Careful: "i" is signed, "len" is unsigned, thus 515 * something like "len-8" may give a *huge* number 516 */ 517 for (i = 0; i+8 < len; i++) { 518 if (strcmp((char *)pkt+i, "blksize") == 0) { 519 TftpBlkSize = (unsigned short) 520 simple_strtoul((char *)pkt+i+8, NULL, 521 10); 522 debug("Blocksize ack: %s, %d\n", 523 (char *)pkt+i+8, TftpBlkSize); 524 } 525 #ifdef CONFIG_TFTP_TSIZE 526 if (strcmp((char *)pkt+i, "tsize") == 0) { 527 TftpTsize = simple_strtoul((char *)pkt+i+6, 528 NULL, 10); 529 debug("size = %s, %d\n", 530 (char *)pkt+i+6, TftpTsize); 531 } 532 #endif 533 } 534 #ifdef CONFIG_MCAST_TFTP 535 parse_multicast_oack((char *)pkt, len-1); 536 if ((Multicast) && (!MasterClient)) 537 TftpState = STATE_DATA; /* passive.. */ 538 else 539 #endif 540 #ifdef CONFIG_CMD_TFTPPUT 541 if (TftpWriting) { 542 /* Get ready to send the first block */ 543 TftpState = STATE_DATA; 544 TftpBlock++; 545 } 546 #endif 547 TftpSend(); /* Send ACK or first data block */ 548 break; 549 case TFTP_DATA: 550 if (len < 2) 551 return; 552 len -= 2; 553 TftpBlock = ntohs(*(ushort *)pkt); 554 555 update_block_number(); 556 557 if (TftpState == STATE_SEND_RRQ) 558 debug("Server did not acknowledge timeout option!\n"); 559 560 if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || 561 TftpState == STATE_RECV_WRQ) { 562 /* first block received */ 563 TftpState = STATE_DATA; 564 TftpRemotePort = src; 565 new_transfer(); 566 567 #ifdef CONFIG_MCAST_TFTP 568 if (Multicast) { /* start!=1 common if mcast */ 569 TftpLastBlock = TftpBlock - 1; 570 } else 571 #endif 572 if (TftpBlock != 1) { /* Assertion */ 573 printf("\nTFTP error: " 574 "First block is not block 1 (%ld)\n" 575 "Starting again\n\n", 576 TftpBlock); 577 NetStartAgain(); 578 break; 579 } 580 } 581 582 if (TftpBlock == TftpLastBlock) { 583 /* 584 * Same block again; ignore it. 585 */ 586 break; 587 } 588 589 TftpLastBlock = TftpBlock; 590 TftpTimeoutCountMax = TIMEOUT_COUNT; 591 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 592 593 store_block(TftpBlock - 1, pkt + 2, len); 594 595 /* 596 * Acknowledge the block just received, which will prompt 597 * the remote for the next one. 598 */ 599 #ifdef CONFIG_MCAST_TFTP 600 /* if I am the MasterClient, actively calculate what my next 601 * needed block is; else I'm passive; not ACKING 602 */ 603 if (Multicast) { 604 if (len < TftpBlkSize) { 605 TftpEndingBlock = TftpBlock; 606 } else if (MasterClient) { 607 TftpBlock = PrevBitmapHole = 608 ext2_find_next_zero_bit( 609 Bitmap, 610 (Mapsize*8), 611 PrevBitmapHole); 612 if (TftpBlock > ((Mapsize*8) - 1)) { 613 printf("tftpfile too big\n"); 614 /* try to double it and retry */ 615 Mapsize <<= 1; 616 mcast_cleanup(); 617 NetStartAgain(); 618 return; 619 } 620 TftpLastBlock = TftpBlock; 621 } 622 } 623 #endif 624 TftpSend(); 625 626 #ifdef CONFIG_MCAST_TFTP 627 if (Multicast) { 628 if (MasterClient && (TftpBlock >= TftpEndingBlock)) { 629 puts("\nMulticast tftp done\n"); 630 mcast_cleanup(); 631 NetState = NETLOOP_SUCCESS; 632 } 633 } 634 else 635 #endif 636 if (len < TftpBlkSize) 637 tftp_complete(); 638 break; 639 640 case TFTP_ERROR: 641 printf("\nTFTP error: '%s' (%d)\n", 642 pkt + 2, ntohs(*(ushort *)pkt)); 643 644 switch (ntohs(*(ushort *)pkt)) { 645 case TFTP_ERR_FILE_NOT_FOUND: 646 case TFTP_ERR_ACCESS_DENIED: 647 puts("Not retrying...\n"); 648 eth_halt(); 649 NetState = NETLOOP_FAIL; 650 break; 651 case TFTP_ERR_UNDEFINED: 652 case TFTP_ERR_DISK_FULL: 653 case TFTP_ERR_UNEXPECTED_OPCODE: 654 case TFTP_ERR_UNKNOWN_TRANSFER_ID: 655 case TFTP_ERR_FILE_ALREADY_EXISTS: 656 default: 657 puts("Starting again\n\n"); 658 #ifdef CONFIG_MCAST_TFTP 659 mcast_cleanup(); 660 #endif 661 NetStartAgain(); 662 break; 663 } 664 break; 665 } 666 } 667 668 669 static void 670 TftpTimeout(void) 671 { 672 if (++TftpTimeoutCount > TftpTimeoutCountMax) { 673 restart("Retry count exceeded"); 674 } else { 675 puts("T "); 676 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 677 if (TftpState != STATE_RECV_WRQ) 678 TftpSend(); 679 } 680 } 681 682 683 void TftpStart(enum proto_t protocol) 684 { 685 char *ep; /* Environment pointer */ 686 687 /* 688 * Allow the user to choose TFTP blocksize and timeout. 689 * TFTP protocol has a minimal timeout of 1 second. 690 */ 691 ep = getenv("tftpblocksize"); 692 if (ep != NULL) 693 TftpBlkSizeOption = simple_strtol(ep, NULL, 10); 694 695 ep = getenv("tftptimeout"); 696 if (ep != NULL) 697 TftpTimeoutMSecs = simple_strtol(ep, NULL, 10); 698 699 if (TftpTimeoutMSecs < 1000) { 700 printf("TFTP timeout (%ld ms) too low, " 701 "set minimum = 1000 ms\n", 702 TftpTimeoutMSecs); 703 TftpTimeoutMSecs = 1000; 704 } 705 706 debug("TFTP blocksize = %i, timeout = %ld ms\n", 707 TftpBlkSizeOption, TftpTimeoutMSecs); 708 709 TftpRemoteIP = NetServerIP; 710 if (BootFile[0] == '\0') { 711 sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", 712 NetOurIP & 0xFF, 713 (NetOurIP >> 8) & 0xFF, 714 (NetOurIP >> 16) & 0xFF, 715 (NetOurIP >> 24) & 0xFF); 716 717 strncpy(tftp_filename, default_filename, MAX_LEN); 718 tftp_filename[MAX_LEN-1] = 0; 719 720 printf("*** Warning: no boot file name; using '%s'\n", 721 tftp_filename); 722 } else { 723 char *p = strchr(BootFile, ':'); 724 725 if (p == NULL) { 726 strncpy(tftp_filename, BootFile, MAX_LEN); 727 tftp_filename[MAX_LEN-1] = 0; 728 } else { 729 TftpRemoteIP = string_to_ip(BootFile); 730 strncpy(tftp_filename, p + 1, MAX_LEN); 731 tftp_filename[MAX_LEN-1] = 0; 732 } 733 } 734 735 printf("Using %s device\n", eth_get_name()); 736 printf("TFTP %s server %pI4; our IP address is %pI4", 737 #ifdef CONFIG_CMD_TFTPPUT 738 protocol == TFTPPUT ? "to" : "from", 739 #else 740 "from", 741 #endif 742 &TftpRemoteIP, &NetOurIP); 743 744 /* Check if we need to send across this subnet */ 745 if (NetOurGatewayIP && NetOurSubnetMask) { 746 IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; 747 IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask; 748 749 if (OurNet != RemoteNet) 750 printf("; sending through gateway %pI4", 751 &NetOurGatewayIP); 752 } 753 putc('\n'); 754 755 printf("Filename '%s'.", tftp_filename); 756 757 if (NetBootFileSize) { 758 printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); 759 print_size(NetBootFileSize<<9, ""); 760 } 761 762 putc('\n'); 763 #ifdef CONFIG_CMD_TFTPPUT 764 TftpWriting = (protocol == TFTPPUT); 765 if (TftpWriting) { 766 printf("Save address: 0x%lx\n", save_addr); 767 printf("Save size: 0x%lx\n", save_size); 768 NetBootFileXferSize = save_size; 769 puts("Saving: *\b"); 770 TftpState = STATE_SEND_WRQ; 771 new_transfer(); 772 } else 773 #endif 774 { 775 printf("Load address: 0x%lx\n", load_addr); 776 puts("Loading: *\b"); 777 TftpState = STATE_SEND_RRQ; 778 } 779 780 TftpTimeoutCountMax = TftpRRQTimeoutCountMax; 781 782 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 783 NetSetHandler(TftpHandler); 784 #ifdef CONFIG_CMD_TFTPPUT 785 net_set_icmp_handler(icmp_handler); 786 #endif 787 TftpRemotePort = WELL_KNOWN_PORT; 788 TftpTimeoutCount = 0; 789 /* Use a pseudo-random port unless a specific port is set */ 790 TftpOurPort = 1024 + (get_timer(0) % 3072); 791 792 #ifdef CONFIG_TFTP_PORT 793 ep = getenv("tftpdstp"); 794 if (ep != NULL) 795 TftpRemotePort = simple_strtol(ep, NULL, 10); 796 ep = getenv("tftpsrcp"); 797 if (ep != NULL) 798 TftpOurPort = simple_strtol(ep, NULL, 10); 799 #endif 800 TftpBlock = 0; 801 802 /* zero out server ether in case the server ip has changed */ 803 memset(NetServerEther, 0, 6); 804 /* Revert TftpBlkSize to dflt */ 805 TftpBlkSize = TFTP_BLOCK_SIZE; 806 #ifdef CONFIG_MCAST_TFTP 807 mcast_cleanup(); 808 #endif 809 #ifdef CONFIG_TFTP_TSIZE 810 TftpTsize = 0; 811 TftpNumchars = 0; 812 #endif 813 814 TftpSend(); 815 } 816 817 #ifdef CONFIG_CMD_TFTPSRV 818 void 819 TftpStartServer(void) 820 { 821 tftp_filename[0] = 0; 822 823 printf("Using %s device\n", eth_get_name()); 824 printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); 825 printf("Load address: 0x%lx\n", load_addr); 826 827 puts("Loading: *\b"); 828 829 TftpTimeoutCountMax = TIMEOUT_COUNT; 830 TftpTimeoutCount = 0; 831 TftpTimeoutMSecs = TIMEOUT; 832 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 833 834 /* Revert TftpBlkSize to dflt */ 835 TftpBlkSize = TFTP_BLOCK_SIZE; 836 TftpBlock = 0; 837 TftpOurPort = WELL_KNOWN_PORT; 838 839 #ifdef CONFIG_TFTP_TSIZE 840 TftpTsize = 0; 841 TftpNumchars = 0; 842 #endif 843 844 TftpState = STATE_RECV_WRQ; 845 NetSetHandler(TftpHandler); 846 } 847 #endif /* CONFIG_CMD_TFTPSRV */ 848 849 #ifdef CONFIG_MCAST_TFTP 850 /* Credits: atftp project. 851 */ 852 853 /* pick up BcastAddr, Port, and whether I am [now] the master-client. * 854 * Frame: 855 * +-------+-----------+---+-------~~-------+---+ 856 * | opc | multicast | 0 | addr, port, mc | 0 | 857 * +-------+-----------+---+-------~~-------+---+ 858 * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then 859 * I am the new master-client so must send ACKs to DataBlocks. If I am not 860 * master-client, I'm a passive client, gathering what DataBlocks I may and 861 * making note of which ones I got in my bitmask. 862 * In theory, I never go from master->passive.. 863 * .. this comes in with pkt already pointing just past opc 864 */ 865 static void parse_multicast_oack(char *pkt, int len) 866 { 867 int i; 868 IPaddr_t addr; 869 char *mc_adr, *port, *mc; 870 871 mc_adr = port = mc = NULL; 872 /* march along looking for 'multicast\0', which has to start at least 873 * 14 bytes back from the end. 874 */ 875 for (i = 0; i < len-14; i++) 876 if (strcmp(pkt+i, "multicast") == 0) 877 break; 878 if (i >= (len-14)) /* non-Multicast OACK, ign. */ 879 return; 880 881 i += 10; /* strlen multicast */ 882 mc_adr = pkt+i; 883 for (; i < len; i++) { 884 if (*(pkt+i) == ',') { 885 *(pkt+i) = '\0'; 886 if (port) { 887 mc = pkt+i+1; 888 break; 889 } else { 890 port = pkt+i+1; 891 } 892 } 893 } 894 if (!port || !mc_adr || !mc) 895 return; 896 if (Multicast && MasterClient) { 897 printf("I got a OACK as master Client, WRONG!\n"); 898 return; 899 } 900 /* ..I now accept packets destined for this MCAST addr, port */ 901 if (!Multicast) { 902 if (Bitmap) { 903 printf("Internal failure! no mcast.\n"); 904 free(Bitmap); 905 Bitmap = NULL; 906 ProhibitMcast = 1; 907 return ; 908 } 909 /* I malloc instead of pre-declare; so that if the file ends 910 * up being too big for this bitmap I can retry 911 */ 912 Bitmap = malloc(Mapsize); 913 if (!Bitmap) { 914 printf("No Bitmap, no multicast. Sorry.\n"); 915 ProhibitMcast = 1; 916 return; 917 } 918 memset(Bitmap, 0, Mapsize); 919 PrevBitmapHole = 0; 920 Multicast = 1; 921 } 922 addr = string_to_ip(mc_adr); 923 if (Mcast_addr != addr) { 924 if (Mcast_addr) 925 eth_mcast_join(Mcast_addr, 0); 926 Mcast_addr = addr; 927 if (eth_mcast_join(Mcast_addr, 1)) { 928 printf("Fail to set mcast, revert to TFTP\n"); 929 ProhibitMcast = 1; 930 mcast_cleanup(); 931 NetStartAgain(); 932 } 933 } 934 MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10); 935 Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); 936 printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); 937 return; 938 } 939 940 #endif /* Multicast TFTP */ 941