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