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 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 *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ : 336 TFTP_WRQ); 337 pkt = (uchar *)s; 338 strcpy((char *)pkt, tftp_filename); 339 pkt += strlen(tftp_filename) + 1; 340 strcpy((char *)pkt, "octet"); 341 pkt += 5 /*strlen("octet")*/ + 1; 342 strcpy((char *)pkt, "timeout"); 343 pkt += 7 /*strlen("timeout")*/ + 1; 344 sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000); 345 debug("send option \"timeout %s\"\n", (char *)pkt); 346 pkt += strlen((char *)pkt) + 1; 347 #ifdef CONFIG_TFTP_TSIZE 348 pkt += sprintf((char *)pkt, "tsize%c%lu%c", 349 0, NetBootFileXferSize, 0); 350 #endif 351 /* try for more effic. blk size */ 352 pkt += sprintf((char *)pkt, "blksize%c%d%c", 353 0, TftpBlkSizeOption, 0); 354 #ifdef CONFIG_MCAST_TFTP 355 /* Check all preconditions before even trying the option */ 356 if (!ProhibitMcast 357 && (Bitmap = malloc(Mapsize)) 358 && eth_get_dev()->mcast) { 359 free(Bitmap); 360 Bitmap = NULL; 361 pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0); 362 } 363 #endif /* CONFIG_MCAST_TFTP */ 364 len = pkt - xp; 365 break; 366 367 case STATE_OACK: 368 #ifdef CONFIG_MCAST_TFTP 369 /* My turn! Start at where I need blocks I missed.*/ 370 if (Multicast) 371 TftpBlock = ext2_find_next_zero_bit(Bitmap, 372 (Mapsize*8), 0); 373 /*..falling..*/ 374 #endif 375 376 case STATE_RECV_WRQ: 377 case STATE_DATA: 378 xp = pkt; 379 s = (ushort *)pkt; 380 s[0] = htons(TFTP_ACK); 381 s[1] = htons(TftpBlock); 382 pkt = (uchar *)(s + 2); 383 #ifdef CONFIG_CMD_TFTPPUT 384 if (TftpWriting) { 385 int toload = TftpBlkSize; 386 int loaded = load_block(TftpBlock, pkt, toload); 387 388 s[0] = htons(TFTP_DATA); 389 pkt += loaded; 390 TftpFinalBlock = (loaded < toload); 391 } 392 #endif 393 len = pkt - xp; 394 break; 395 396 case STATE_TOO_LARGE: 397 xp = pkt; 398 s = (ushort *)pkt; 399 *s++ = htons(TFTP_ERROR); 400 *s++ = htons(3); 401 402 pkt = (uchar *)s; 403 strcpy((char *)pkt, "File too large"); 404 pkt += 14 /*strlen("File too large")*/ + 1; 405 len = pkt - xp; 406 break; 407 408 case STATE_BAD_MAGIC: 409 xp = pkt; 410 s = (ushort *)pkt; 411 *s++ = htons(TFTP_ERROR); 412 *s++ = htons(2); 413 pkt = (uchar *)s; 414 strcpy((char *)pkt, "File has bad magic"); 415 pkt += 18 /*strlen("File has bad magic")*/ + 1; 416 len = pkt - xp; 417 break; 418 } 419 420 NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort, 421 TftpOurPort, len); 422 } 423 424 #ifdef CONFIG_CMD_TFTPPUT 425 static void icmp_handler(unsigned type, unsigned code, unsigned dest, 426 IPaddr_t sip, unsigned src, uchar *pkt, unsigned len) 427 { 428 if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) { 429 /* Oh dear the other end has gone away */ 430 restart("TFTP server died"); 431 } 432 } 433 #endif 434 435 static void 436 TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 437 unsigned len) 438 { 439 ushort proto; 440 ushort *s; 441 int i; 442 443 if (dest != TftpOurPort) { 444 #ifdef CONFIG_MCAST_TFTP 445 if (Multicast 446 && (!Mcast_port || (dest != Mcast_port))) 447 #endif 448 return; 449 } 450 if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && 451 TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ) 452 return; 453 454 if (len < 2) 455 return; 456 len -= 2; 457 /* warning: don't use increment (++) in ntohs() macros!! */ 458 s = (ushort *)pkt; 459 proto = *s++; 460 pkt = (uchar *)s; 461 switch (ntohs(proto)) { 462 463 case TFTP_RRQ: 464 break; 465 466 case TFTP_ACK: 467 #ifdef CONFIG_CMD_TFTPPUT 468 if (TftpWriting) { 469 if (TftpFinalBlock) { 470 tftp_complete(); 471 } else { 472 /* 473 * Move to the next block. We want our block 474 * count to wrap just like the other end! 475 */ 476 int block = ntohs(*s); 477 int ack_ok = (TftpBlock == block); 478 479 TftpBlock = (unsigned short)(block + 1); 480 update_block_number(); 481 if (ack_ok) 482 TftpSend(); /* Send next data block */ 483 } 484 } 485 #endif 486 break; 487 488 default: 489 break; 490 491 #ifdef CONFIG_CMD_TFTPSRV 492 case TFTP_WRQ: 493 debug("Got WRQ\n"); 494 TftpRemoteIP = sip; 495 TftpRemotePort = src; 496 TftpOurPort = 1024 + (get_timer(0) % 3072); 497 new_transfer(); 498 TftpSend(); /* Send ACK(0) */ 499 break; 500 #endif 501 502 case TFTP_OACK: 503 debug("Got OACK: %s %s\n", 504 pkt, 505 pkt + strlen((char *)pkt) + 1); 506 TftpState = STATE_OACK; 507 TftpRemotePort = src; 508 /* 509 * Check for 'blksize' option. 510 * Careful: "i" is signed, "len" is unsigned, thus 511 * something like "len-8" may give a *huge* number 512 */ 513 for (i = 0; i+8 < len; i++) { 514 if (strcmp((char *)pkt+i, "blksize") == 0) { 515 TftpBlkSize = (unsigned short) 516 simple_strtoul((char *)pkt+i+8, NULL, 517 10); 518 debug("Blocksize ack: %s, %d\n", 519 (char *)pkt+i+8, TftpBlkSize); 520 } 521 #ifdef CONFIG_TFTP_TSIZE 522 if (strcmp((char *)pkt+i, "tsize") == 0) { 523 TftpTsize = simple_strtoul((char *)pkt+i+6, 524 NULL, 10); 525 debug("size = %s, %d\n", 526 (char *)pkt+i+6, TftpTsize); 527 } 528 #endif 529 } 530 #ifdef CONFIG_MCAST_TFTP 531 parse_multicast_oack((char *)pkt, len-1); 532 if ((Multicast) && (!MasterClient)) 533 TftpState = STATE_DATA; /* passive.. */ 534 else 535 #endif 536 #ifdef CONFIG_CMD_TFTPPUT 537 if (TftpWriting) { 538 /* Get ready to send the first block */ 539 TftpState = STATE_DATA; 540 TftpBlock++; 541 } 542 #endif 543 TftpSend(); /* Send ACK or first data block */ 544 break; 545 case TFTP_DATA: 546 if (len < 2) 547 return; 548 len -= 2; 549 TftpBlock = ntohs(*(ushort *)pkt); 550 551 update_block_number(); 552 553 if (TftpState == STATE_SEND_RRQ) 554 debug("Server did not acknowledge timeout option!\n"); 555 556 if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || 557 TftpState == STATE_RECV_WRQ) { 558 /* first block received */ 559 TftpState = STATE_DATA; 560 TftpRemotePort = src; 561 new_transfer(); 562 563 #ifdef CONFIG_MCAST_TFTP 564 if (Multicast) { /* start!=1 common if mcast */ 565 TftpLastBlock = TftpBlock - 1; 566 } else 567 #endif 568 if (TftpBlock != 1) { /* Assertion */ 569 printf("\nTFTP error: " 570 "First block is not block 1 (%ld)\n" 571 "Starting again\n\n", 572 TftpBlock); 573 NetStartAgain(); 574 break; 575 } 576 } 577 578 if (TftpBlock == TftpLastBlock) { 579 /* 580 * Same block again; ignore it. 581 */ 582 break; 583 } 584 585 TftpLastBlock = TftpBlock; 586 TftpTimeoutCountMax = TIMEOUT_COUNT; 587 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 588 589 store_block(TftpBlock - 1, pkt + 2, len); 590 591 /* 592 * Acknowledge the block just received, which will prompt 593 * the remote for the next one. 594 */ 595 #ifdef CONFIG_MCAST_TFTP 596 /* if I am the MasterClient, actively calculate what my next 597 * needed block is; else I'm passive; not ACKING 598 */ 599 if (Multicast) { 600 if (len < TftpBlkSize) { 601 TftpEndingBlock = TftpBlock; 602 } else if (MasterClient) { 603 TftpBlock = PrevBitmapHole = 604 ext2_find_next_zero_bit( 605 Bitmap, 606 (Mapsize*8), 607 PrevBitmapHole); 608 if (TftpBlock > ((Mapsize*8) - 1)) { 609 printf("tftpfile too big\n"); 610 /* try to double it and retry */ 611 Mapsize <<= 1; 612 mcast_cleanup(); 613 NetStartAgain(); 614 return; 615 } 616 TftpLastBlock = TftpBlock; 617 } 618 } 619 #endif 620 TftpSend(); 621 622 #ifdef CONFIG_MCAST_TFTP 623 if (Multicast) { 624 if (MasterClient && (TftpBlock >= TftpEndingBlock)) { 625 puts("\nMulticast tftp done\n"); 626 mcast_cleanup(); 627 NetState = NETLOOP_SUCCESS; 628 } 629 } 630 else 631 #endif 632 if (len < TftpBlkSize) 633 tftp_complete(); 634 break; 635 636 case TFTP_ERROR: 637 printf("\nTFTP error: '%s' (%d)\n", 638 pkt + 2, ntohs(*(ushort *)pkt)); 639 640 switch (ntohs(*(ushort *)pkt)) { 641 case TFTP_ERR_FILE_NOT_FOUND: 642 case TFTP_ERR_ACCESS_DENIED: 643 puts("Not retrying...\n"); 644 eth_halt(); 645 NetState = NETLOOP_FAIL; 646 break; 647 case TFTP_ERR_UNDEFINED: 648 case TFTP_ERR_DISK_FULL: 649 case TFTP_ERR_UNEXPECTED_OPCODE: 650 case TFTP_ERR_UNKNOWN_TRANSFER_ID: 651 case TFTP_ERR_FILE_ALREADY_EXISTS: 652 default: 653 puts("Starting again\n\n"); 654 #ifdef CONFIG_MCAST_TFTP 655 mcast_cleanup(); 656 #endif 657 NetStartAgain(); 658 break; 659 } 660 break; 661 } 662 } 663 664 665 static void 666 TftpTimeout(void) 667 { 668 if (++TftpTimeoutCount > TftpTimeoutCountMax) { 669 restart("Retry count exceeded"); 670 } else { 671 puts("T "); 672 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 673 if (TftpState != STATE_RECV_WRQ) 674 TftpSend(); 675 } 676 } 677 678 679 void TftpStart(enum proto_t protocol) 680 { 681 char *ep; /* Environment pointer */ 682 683 /* 684 * Allow the user to choose TFTP blocksize and timeout. 685 * TFTP protocol has a minimal timeout of 1 second. 686 */ 687 ep = getenv("tftpblocksize"); 688 if (ep != NULL) 689 TftpBlkSizeOption = simple_strtol(ep, NULL, 10); 690 691 ep = getenv("tftptimeout"); 692 if (ep != NULL) 693 TftpTimeoutMSecs = simple_strtol(ep, NULL, 10); 694 695 if (TftpTimeoutMSecs < 1000) { 696 printf("TFTP timeout (%ld ms) too low, " 697 "set minimum = 1000 ms\n", 698 TftpTimeoutMSecs); 699 TftpTimeoutMSecs = 1000; 700 } 701 702 debug("TFTP blocksize = %i, timeout = %ld ms\n", 703 TftpBlkSizeOption, TftpTimeoutMSecs); 704 705 TftpRemoteIP = NetServerIP; 706 if (BootFile[0] == '\0') { 707 sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", 708 NetOurIP & 0xFF, 709 (NetOurIP >> 8) & 0xFF, 710 (NetOurIP >> 16) & 0xFF, 711 (NetOurIP >> 24) & 0xFF); 712 713 strncpy(tftp_filename, default_filename, MAX_LEN); 714 tftp_filename[MAX_LEN-1] = 0; 715 716 printf("*** Warning: no boot file name; using '%s'\n", 717 tftp_filename); 718 } else { 719 char *p = strchr(BootFile, ':'); 720 721 if (p == NULL) { 722 strncpy(tftp_filename, BootFile, MAX_LEN); 723 tftp_filename[MAX_LEN-1] = 0; 724 } else { 725 TftpRemoteIP = string_to_ip(BootFile); 726 strncpy(tftp_filename, p + 1, MAX_LEN); 727 tftp_filename[MAX_LEN-1] = 0; 728 } 729 } 730 731 printf("Using %s device\n", eth_get_name()); 732 printf("TFTP %s server %pI4; our IP address is %pI4", 733 protocol == TFTPPUT ? "to" : "from", &TftpRemoteIP, &NetOurIP); 734 735 /* Check if we need to send across this subnet */ 736 if (NetOurGatewayIP && NetOurSubnetMask) { 737 IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; 738 IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask; 739 740 if (OurNet != RemoteNet) 741 printf("; sending through gateway %pI4", 742 &NetOurGatewayIP); 743 } 744 putc('\n'); 745 746 printf("Filename '%s'.", tftp_filename); 747 748 if (NetBootFileSize) { 749 printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); 750 print_size(NetBootFileSize<<9, ""); 751 } 752 753 putc('\n'); 754 #ifdef CONFIG_CMD_TFTPPUT 755 TftpWriting = (protocol == TFTPPUT); 756 if (TftpWriting) { 757 printf("Save address: 0x%lx\n", save_addr); 758 printf("Save size: 0x%lx\n", save_size); 759 NetBootFileXferSize = save_size; 760 puts("Saving: *\b"); 761 TftpState = STATE_SEND_WRQ; 762 new_transfer(); 763 } else 764 #endif 765 { 766 printf("Load address: 0x%lx\n", load_addr); 767 puts("Loading: *\b"); 768 TftpState = STATE_SEND_RRQ; 769 } 770 771 TftpTimeoutCountMax = TftpRRQTimeoutCountMax; 772 773 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 774 NetSetHandler(TftpHandler); 775 #ifdef CONFIG_CMD_TFTPPUT 776 net_set_icmp_handler(icmp_handler); 777 #endif 778 TftpRemotePort = WELL_KNOWN_PORT; 779 TftpTimeoutCount = 0; 780 /* Use a pseudo-random port unless a specific port is set */ 781 TftpOurPort = 1024 + (get_timer(0) % 3072); 782 783 #ifdef CONFIG_TFTP_PORT 784 ep = getenv("tftpdstp"); 785 if (ep != NULL) 786 TftpRemotePort = simple_strtol(ep, NULL, 10); 787 ep = getenv("tftpsrcp"); 788 if (ep != NULL) 789 TftpOurPort = simple_strtol(ep, NULL, 10); 790 #endif 791 TftpBlock = 0; 792 793 /* zero out server ether in case the server ip has changed */ 794 memset(NetServerEther, 0, 6); 795 /* Revert TftpBlkSize to dflt */ 796 TftpBlkSize = TFTP_BLOCK_SIZE; 797 #ifdef CONFIG_MCAST_TFTP 798 mcast_cleanup(); 799 #endif 800 #ifdef CONFIG_TFTP_TSIZE 801 TftpTsize = 0; 802 TftpNumchars = 0; 803 #endif 804 805 TftpSend(); 806 } 807 808 #ifdef CONFIG_CMD_TFTPSRV 809 void 810 TftpStartServer(void) 811 { 812 tftp_filename[0] = 0; 813 814 printf("Using %s device\n", eth_get_name()); 815 printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); 816 printf("Load address: 0x%lx\n", load_addr); 817 818 puts("Loading: *\b"); 819 820 TftpTimeoutCountMax = TIMEOUT_COUNT; 821 TftpTimeoutCount = 0; 822 TftpTimeoutMSecs = TIMEOUT; 823 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 824 825 /* Revert TftpBlkSize to dflt */ 826 TftpBlkSize = TFTP_BLOCK_SIZE; 827 TftpBlock = 0; 828 TftpOurPort = WELL_KNOWN_PORT; 829 830 #ifdef CONFIG_TFTP_TSIZE 831 TftpTsize = 0; 832 TftpNumchars = 0; 833 #endif 834 835 TftpState = STATE_RECV_WRQ; 836 NetSetHandler(TftpHandler); 837 } 838 #endif /* CONFIG_CMD_TFTPSRV */ 839 840 #ifdef CONFIG_MCAST_TFTP 841 /* Credits: atftp project. 842 */ 843 844 /* pick up BcastAddr, Port, and whether I am [now] the master-client. * 845 * Frame: 846 * +-------+-----------+---+-------~~-------+---+ 847 * | opc | multicast | 0 | addr, port, mc | 0 | 848 * +-------+-----------+---+-------~~-------+---+ 849 * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then 850 * I am the new master-client so must send ACKs to DataBlocks. If I am not 851 * master-client, I'm a passive client, gathering what DataBlocks I may and 852 * making note of which ones I got in my bitmask. 853 * In theory, I never go from master->passive.. 854 * .. this comes in with pkt already pointing just past opc 855 */ 856 static void parse_multicast_oack(char *pkt, int len) 857 { 858 int i; 859 IPaddr_t addr; 860 char *mc_adr, *port, *mc; 861 862 mc_adr = port = mc = NULL; 863 /* march along looking for 'multicast\0', which has to start at least 864 * 14 bytes back from the end. 865 */ 866 for (i = 0; i < len-14; i++) 867 if (strcmp(pkt+i, "multicast") == 0) 868 break; 869 if (i >= (len-14)) /* non-Multicast OACK, ign. */ 870 return; 871 872 i += 10; /* strlen multicast */ 873 mc_adr = pkt+i; 874 for (; i < len; i++) { 875 if (*(pkt+i) == ',') { 876 *(pkt+i) = '\0'; 877 if (port) { 878 mc = pkt+i+1; 879 break; 880 } else { 881 port = pkt+i+1; 882 } 883 } 884 } 885 if (!port || !mc_adr || !mc) 886 return; 887 if (Multicast && MasterClient) { 888 printf("I got a OACK as master Client, WRONG!\n"); 889 return; 890 } 891 /* ..I now accept packets destined for this MCAST addr, port */ 892 if (!Multicast) { 893 if (Bitmap) { 894 printf("Internal failure! no mcast.\n"); 895 free(Bitmap); 896 Bitmap = NULL; 897 ProhibitMcast = 1; 898 return ; 899 } 900 /* I malloc instead of pre-declare; so that if the file ends 901 * up being too big for this bitmap I can retry 902 */ 903 Bitmap = malloc(Mapsize); 904 if (!Bitmap) { 905 printf("No Bitmap, no multicast. Sorry.\n"); 906 ProhibitMcast = 1; 907 return; 908 } 909 memset(Bitmap, 0, Mapsize); 910 PrevBitmapHole = 0; 911 Multicast = 1; 912 } 913 addr = string_to_ip(mc_adr); 914 if (Mcast_addr != addr) { 915 if (Mcast_addr) 916 eth_mcast_join(Mcast_addr, 0); 917 Mcast_addr = addr; 918 if (eth_mcast_join(Mcast_addr, 1)) { 919 printf("Fail to set mcast, revert to TFTP\n"); 920 ProhibitMcast = 1; 921 mcast_cleanup(); 922 NetStartAgain(); 923 } 924 } 925 MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10); 926 Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); 927 printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); 928 return; 929 } 930 931 #endif /* Multicast TFTP */ 932