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