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