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