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