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