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 printf("Using %s device\n", eth_get_name()); 619 printf("TFTP from server %pI4" 620 "; our IP address is %pI4", &TftpRemoteIP, &NetOurIP); 621 622 /* Check if we need to send across this subnet */ 623 if (NetOurGatewayIP && NetOurSubnetMask) { 624 IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; 625 IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask; 626 627 if (OurNet != RemoteNet) 628 printf("; sending through gateway %pI4", 629 &NetOurGatewayIP); 630 } 631 putc('\n'); 632 633 printf("Filename '%s'.", tftp_filename); 634 635 if (NetBootFileSize) { 636 printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); 637 print_size(NetBootFileSize<<9, ""); 638 } 639 640 putc('\n'); 641 642 printf("Load address: 0x%lx\n", load_addr); 643 644 puts("Loading: *\b"); 645 646 TftpTimeoutCountMax = TftpRRQTimeoutCountMax; 647 648 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 649 NetSetHandler(TftpHandler); 650 651 TftpRemotePort = WELL_KNOWN_PORT; 652 TftpTimeoutCount = 0; 653 TftpState = STATE_SEND_RRQ; 654 /* Use a pseudo-random port unless a specific port is set */ 655 TftpOurPort = 1024 + (get_timer(0) % 3072); 656 657 #ifdef CONFIG_TFTP_PORT 658 ep = getenv("tftpdstp"); 659 if (ep != NULL) 660 TftpRemotePort = simple_strtol(ep, NULL, 10); 661 ep = getenv("tftpsrcp"); 662 if (ep != NULL) 663 TftpOurPort = simple_strtol(ep, NULL, 10); 664 #endif 665 TftpBlock = 0; 666 667 /* zero out server ether in case the server ip has changed */ 668 memset(NetServerEther, 0, 6); 669 /* Revert TftpBlkSize to dflt */ 670 TftpBlkSize = TFTP_BLOCK_SIZE; 671 #ifdef CONFIG_MCAST_TFTP 672 mcast_cleanup(); 673 #endif 674 #ifdef CONFIG_TFTP_TSIZE 675 TftpTsize = 0; 676 TftpNumchars = 0; 677 #endif 678 679 TftpSend(); 680 } 681 682 #ifdef CONFIG_CMD_TFTPSRV 683 void 684 TftpStartServer(void) 685 { 686 tftp_filename[0] = 0; 687 688 printf("Using %s device\n", eth_get_name()); 689 printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); 690 printf("Load address: 0x%lx\n", load_addr); 691 692 puts("Loading: *\b"); 693 694 TftpTimeoutCountMax = TIMEOUT_COUNT; 695 TftpTimeoutCount = 0; 696 TftpTimeoutMSecs = TIMEOUT; 697 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 698 699 /* Revert TftpBlkSize to dflt */ 700 TftpBlkSize = TFTP_BLOCK_SIZE; 701 TftpBlock = 0; 702 TftpOurPort = WELL_KNOWN_PORT; 703 704 #ifdef CONFIG_TFTP_TSIZE 705 TftpTsize = 0; 706 TftpNumchars = 0; 707 #endif 708 709 TftpState = STATE_RECV_WRQ; 710 NetSetHandler(TftpHandler); 711 } 712 #endif /* CONFIG_CMD_TFTPSRV */ 713 714 #ifdef CONFIG_MCAST_TFTP 715 /* Credits: atftp project. 716 */ 717 718 /* pick up BcastAddr, Port, and whether I am [now] the master-client. * 719 * Frame: 720 * +-------+-----------+---+-------~~-------+---+ 721 * | opc | multicast | 0 | addr, port, mc | 0 | 722 * +-------+-----------+---+-------~~-------+---+ 723 * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then 724 * I am the new master-client so must send ACKs to DataBlocks. If I am not 725 * master-client, I'm a passive client, gathering what DataBlocks I may and 726 * making note of which ones I got in my bitmask. 727 * In theory, I never go from master->passive.. 728 * .. this comes in with pkt already pointing just past opc 729 */ 730 static void parse_multicast_oack(char *pkt, int len) 731 { 732 int i; 733 IPaddr_t addr; 734 char *mc_adr, *port, *mc; 735 736 mc_adr = port = mc = NULL; 737 /* march along looking for 'multicast\0', which has to start at least 738 * 14 bytes back from the end. 739 */ 740 for (i = 0; i < len-14; i++) 741 if (strcmp(pkt+i, "multicast") == 0) 742 break; 743 if (i >= (len-14)) /* non-Multicast OACK, ign. */ 744 return; 745 746 i += 10; /* strlen multicast */ 747 mc_adr = pkt+i; 748 for (; i < len; i++) { 749 if (*(pkt+i) == ',') { 750 *(pkt+i) = '\0'; 751 if (port) { 752 mc = pkt+i+1; 753 break; 754 } else { 755 port = pkt+i+1; 756 } 757 } 758 } 759 if (!port || !mc_adr || !mc) 760 return; 761 if (Multicast && MasterClient) { 762 printf("I got a OACK as master Client, WRONG!\n"); 763 return; 764 } 765 /* ..I now accept packets destined for this MCAST addr, port */ 766 if (!Multicast) { 767 if (Bitmap) { 768 printf("Internal failure! no mcast.\n"); 769 free(Bitmap); 770 Bitmap = NULL; 771 ProhibitMcast = 1; 772 return ; 773 } 774 /* I malloc instead of pre-declare; so that if the file ends 775 * up being too big for this bitmap I can retry 776 */ 777 Bitmap = malloc(Mapsize); 778 if (!Bitmap) { 779 printf("No Bitmap, no multicast. Sorry.\n"); 780 ProhibitMcast = 1; 781 return; 782 } 783 memset(Bitmap, 0, Mapsize); 784 PrevBitmapHole = 0; 785 Multicast = 1; 786 } 787 addr = string_to_ip(mc_adr); 788 if (Mcast_addr != addr) { 789 if (Mcast_addr) 790 eth_mcast_join(Mcast_addr, 0); 791 Mcast_addr = addr; 792 if (eth_mcast_join(Mcast_addr, 1)) { 793 printf("Fail to set mcast, revert to TFTP\n"); 794 ProhibitMcast = 1; 795 mcast_cleanup(); 796 NetStartAgain(); 797 } 798 } 799 MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10); 800 Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); 801 printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); 802 return; 803 } 804 805 #endif /* Multicast TFTP */ 806