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