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