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, 255 (Mapsize*8), 0); 256 /*..falling..*/ 257 #endif 258 case STATE_DATA: 259 xp = pkt; 260 s = (ushort *)pkt; 261 *s++ = htons(TFTP_ACK); 262 *s++ = htons(TftpBlock); 263 pkt = (uchar *)s; 264 len = pkt - xp; 265 break; 266 267 case STATE_TOO_LARGE: 268 xp = pkt; 269 s = (ushort *)pkt; 270 *s++ = htons(TFTP_ERROR); 271 *s++ = htons(3); 272 pkt = (uchar *)s; 273 strcpy((char *)pkt, "File too large"); 274 pkt += 14 /*strlen("File too large")*/ + 1; 275 len = pkt - xp; 276 break; 277 278 case STATE_BAD_MAGIC: 279 xp = pkt; 280 s = (ushort *)pkt; 281 *s++ = htons(TFTP_ERROR); 282 *s++ = htons(2); 283 pkt = (uchar *)s; 284 strcpy((char *)pkt, "File has bad magic"); 285 pkt += 18 /*strlen("File has bad magic")*/ + 1; 286 len = pkt - xp; 287 break; 288 } 289 290 NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, 291 TftpOurPort, len); 292 } 293 294 295 static void 296 TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 297 unsigned len) 298 { 299 ushort proto; 300 ushort *s; 301 int i; 302 303 if (dest != TftpOurPort) { 304 #ifdef CONFIG_MCAST_TFTP 305 if (Multicast 306 && (!Mcast_port || (dest != Mcast_port))) 307 #endif 308 return; 309 } 310 if (TftpState != STATE_RRQ && src != TftpServerPort) 311 return; 312 313 if (len < 2) 314 return; 315 len -= 2; 316 /* warning: don't use increment (++) in ntohs() macros!! */ 317 s = (ushort *)pkt; 318 proto = *s++; 319 pkt = (uchar *)s; 320 switch (ntohs(proto)) { 321 322 case TFTP_RRQ: 323 case TFTP_WRQ: 324 case TFTP_ACK: 325 break; 326 default: 327 break; 328 329 case TFTP_OACK: 330 debug("Got OACK: %s %s\n", 331 pkt, 332 pkt + strlen((char *)pkt) + 1); 333 TftpState = STATE_OACK; 334 TftpServerPort = src; 335 /* 336 * Check for 'blksize' option. 337 * Careful: "i" is signed, "len" is unsigned, thus 338 * something like "len-8" may give a *huge* number 339 */ 340 for (i = 0; i+8 < len; i++) { 341 if (strcmp((char *)pkt+i, "blksize") == 0) { 342 TftpBlkSize = (unsigned short) 343 simple_strtoul((char *)pkt+i+8, NULL, 344 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 if (TftpState == STATE_RRQ) 401 debug("Server did not acknowledge timeout option!\n"); 402 403 if (TftpState == STATE_RRQ || TftpState == STATE_OACK) { 404 /* first block received */ 405 TftpState = STATE_DATA; 406 TftpServerPort = src; 407 TftpLastBlock = 0; 408 TftpBlockWrap = 0; 409 TftpBlockWrapOffset = 0; 410 411 #ifdef CONFIG_MCAST_TFTP 412 if (Multicast) { /* start!=1 common if mcast */ 413 TftpLastBlock = TftpBlock - 1; 414 } else 415 #endif 416 if (TftpBlock != 1) { /* Assertion */ 417 printf("\nTFTP error: " 418 "First block is not block 1 (%ld)\n" 419 "Starting again\n\n", 420 TftpBlock); 421 NetStartAgain(); 422 break; 423 } 424 } 425 426 if (TftpBlock == TftpLastBlock) { 427 /* 428 * Same block again; ignore it. 429 */ 430 break; 431 } 432 433 TftpLastBlock = TftpBlock; 434 TftpTimeoutCountMax = TIMEOUT_COUNT; 435 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 436 437 store_block(TftpBlock - 1, pkt + 2, len); 438 439 /* 440 * Acknoledge the block just received, which will prompt 441 * the server for the next one. 442 */ 443 #ifdef CONFIG_MCAST_TFTP 444 /* if I am the MasterClient, actively calculate what my next 445 * needed block is; else I'm passive; not ACKING 446 */ 447 if (Multicast) { 448 if (len < TftpBlkSize) { 449 TftpEndingBlock = TftpBlock; 450 } else if (MasterClient) { 451 TftpBlock = PrevBitmapHole = 452 ext2_find_next_zero_bit( 453 Bitmap, 454 (Mapsize*8), 455 PrevBitmapHole); 456 if (TftpBlock > ((Mapsize*8) - 1)) { 457 printf("tftpfile too big\n"); 458 /* try to double it and retry */ 459 Mapsize <<= 1; 460 mcast_cleanup(); 461 NetStartAgain(); 462 return; 463 } 464 TftpLastBlock = TftpBlock; 465 } 466 } 467 #endif 468 TftpSend(); 469 470 #ifdef CONFIG_MCAST_TFTP 471 if (Multicast) { 472 if (MasterClient && (TftpBlock >= TftpEndingBlock)) { 473 puts("\nMulticast tftp done\n"); 474 mcast_cleanup(); 475 NetState = NETLOOP_SUCCESS; 476 } 477 } 478 else 479 #endif 480 if (len < TftpBlkSize) { 481 /* 482 * We received the whole thing. Try to 483 * run it. 484 */ 485 #ifdef CONFIG_TFTP_TSIZE 486 /* Print hash marks for the last packet received */ 487 while (TftpTsize && TftpNumchars < 49) { 488 putc('#'); 489 TftpNumchars++; 490 } 491 #endif 492 puts("\ndone\n"); 493 NetState = NETLOOP_SUCCESS; 494 } 495 break; 496 497 case TFTP_ERROR: 498 printf("\nTFTP error: '%s' (%d)\n", 499 pkt + 2, ntohs(*(ushort *)pkt)); 500 501 switch (ntohs(*(ushort *)pkt)) { 502 case TFTP_ERR_FILE_NOT_FOUND: 503 case TFTP_ERR_ACCESS_DENIED: 504 puts("Not retrying...\n"); 505 eth_halt(); 506 NetState = NETLOOP_FAIL; 507 break; 508 case TFTP_ERR_UNDEFINED: 509 case TFTP_ERR_DISK_FULL: 510 case TFTP_ERR_UNEXPECTED_OPCODE: 511 case TFTP_ERR_UNKNOWN_TRANSFER_ID: 512 case TFTP_ERR_FILE_ALREADY_EXISTS: 513 default: 514 puts("Starting again\n\n"); 515 #ifdef CONFIG_MCAST_TFTP 516 mcast_cleanup(); 517 #endif 518 NetStartAgain(); 519 break; 520 } 521 break; 522 } 523 } 524 525 526 static void 527 TftpTimeout(void) 528 { 529 if (++TftpTimeoutCount > TftpTimeoutCountMax) { 530 puts("\nRetry count exceeded; starting again\n"); 531 #ifdef CONFIG_MCAST_TFTP 532 mcast_cleanup(); 533 #endif 534 NetStartAgain(); 535 } else { 536 puts("T "); 537 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 538 TftpSend(); 539 } 540 } 541 542 543 void 544 TftpStart(void) 545 { 546 char *ep; /* Environment pointer */ 547 548 /* 549 * Allow the user to choose TFTP blocksize and timeout. 550 * TFTP protocol has a minimal timeout of 1 second. 551 */ 552 ep = getenv("tftpblocksize"); 553 if (ep != NULL) 554 TftpBlkSizeOption = simple_strtol(ep, NULL, 10); 555 556 ep = getenv("tftptimeout"); 557 if (ep != NULL) 558 TftpTimeoutMSecs = simple_strtol(ep, NULL, 10); 559 560 if (TftpTimeoutMSecs < 1000) { 561 printf("TFTP timeout (%ld ms) too low, " 562 "set minimum = 1000 ms\n", 563 TftpTimeoutMSecs); 564 TftpTimeoutMSecs = 1000; 565 } 566 567 debug("TFTP blocksize = %i, timeout = %ld ms\n", 568 TftpBlkSizeOption, TftpTimeoutMSecs); 569 570 TftpServerIP = NetServerIP; 571 if (BootFile[0] == '\0') { 572 sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", 573 NetOurIP & 0xFF, 574 (NetOurIP >> 8) & 0xFF, 575 (NetOurIP >> 16) & 0xFF, 576 (NetOurIP >> 24) & 0xFF); 577 578 strncpy(tftp_filename, default_filename, MAX_LEN); 579 tftp_filename[MAX_LEN-1] = 0; 580 581 printf("*** Warning: no boot file name; using '%s'\n", 582 tftp_filename); 583 } else { 584 char *p = strchr(BootFile, ':'); 585 586 if (p == NULL) { 587 strncpy(tftp_filename, BootFile, MAX_LEN); 588 tftp_filename[MAX_LEN-1] = 0; 589 } else { 590 TftpServerIP = string_to_ip(BootFile); 591 strncpy(tftp_filename, p + 1, MAX_LEN); 592 tftp_filename[MAX_LEN-1] = 0; 593 } 594 } 595 596 #if defined(CONFIG_NET_MULTI) 597 printf("Using %s device\n", eth_get_name()); 598 #endif 599 printf("TFTP from server %pI4" 600 "; our IP address is %pI4", &TftpServerIP, &NetOurIP); 601 602 /* Check if we need to send across this subnet */ 603 if (NetOurGatewayIP && NetOurSubnetMask) { 604 IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; 605 IPaddr_t ServerNet = TftpServerIP & NetOurSubnetMask; 606 607 if (OurNet != ServerNet) 608 printf("; sending through gateway %pI4", &NetOurGatewayIP); 609 } 610 putc('\n'); 611 612 printf("Filename '%s'.", tftp_filename); 613 614 if (NetBootFileSize) { 615 printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); 616 print_size(NetBootFileSize<<9, ""); 617 } 618 619 putc('\n'); 620 621 printf("Load address: 0x%lx\n", load_addr); 622 623 puts("Loading: *\b"); 624 625 TftpTimeoutCountMax = TftpRRQTimeoutCountMax; 626 627 NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); 628 NetSetHandler(TftpHandler); 629 630 TftpServerPort = WELL_KNOWN_PORT; 631 TftpTimeoutCount = 0; 632 TftpState = STATE_RRQ; 633 /* Use a pseudo-random port unless a specific port is set */ 634 TftpOurPort = 1024 + (get_timer(0) % 3072); 635 636 #ifdef CONFIG_TFTP_PORT 637 ep = getenv("tftpdstp"); 638 if (ep != NULL) 639 TftpServerPort = simple_strtol(ep, NULL, 10); 640 ep = getenv("tftpsrcp"); 641 if (ep != NULL) 642 TftpOurPort = simple_strtol(ep, NULL, 10); 643 #endif 644 TftpBlock = 0; 645 646 /* zero out server ether in case the server ip has changed */ 647 memset(NetServerEther, 0, 6); 648 /* Revert TftpBlkSize to dflt */ 649 TftpBlkSize = TFTP_BLOCK_SIZE; 650 #ifdef CONFIG_MCAST_TFTP 651 mcast_cleanup(); 652 #endif 653 #ifdef CONFIG_TFTP_TSIZE 654 TftpTsize = 0; 655 TftpNumchars = 0; 656 #endif 657 658 TftpSend(); 659 } 660 661 #ifdef CONFIG_MCAST_TFTP 662 /* Credits: atftp project. 663 */ 664 665 /* pick up BcastAddr, Port, and whether I am [now] the master-client. * 666 * Frame: 667 * +-------+-----------+---+-------~~-------+---+ 668 * | opc | multicast | 0 | addr, port, mc | 0 | 669 * +-------+-----------+---+-------~~-------+---+ 670 * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then 671 * I am the new master-client so must send ACKs to DataBlocks. If I am not 672 * master-client, I'm a passive client, gathering what DataBlocks I may and 673 * making note of which ones I got in my bitmask. 674 * In theory, I never go from master->passive.. 675 * .. this comes in with pkt already pointing just past opc 676 */ 677 static void parse_multicast_oack(char *pkt, int len) 678 { 679 int i; 680 IPaddr_t addr; 681 char *mc_adr, *port, *mc; 682 683 mc_adr = port = mc = NULL; 684 /* march along looking for 'multicast\0', which has to start at least 685 * 14 bytes back from the end. 686 */ 687 for (i = 0; i < len-14; i++) 688 if (strcmp(pkt+i, "multicast") == 0) 689 break; 690 if (i >= (len-14)) /* non-Multicast OACK, ign. */ 691 return; 692 693 i += 10; /* strlen multicast */ 694 mc_adr = pkt+i; 695 for (; i < len; i++) { 696 if (*(pkt+i) == ',') { 697 *(pkt+i) = '\0'; 698 if (port) { 699 mc = pkt+i+1; 700 break; 701 } else { 702 port = pkt+i+1; 703 } 704 } 705 } 706 if (!port || !mc_adr || !mc) return; 707 if (Multicast && MasterClient) { 708 printf("I got a OACK as master Client, WRONG!\n"); 709 return; 710 } 711 /* ..I now accept packets destined for this MCAST addr, port */ 712 if (!Multicast) { 713 if (Bitmap) { 714 printf("Internal failure! no mcast.\n"); 715 free(Bitmap); 716 Bitmap = NULL; 717 ProhibitMcast = 1; 718 return ; 719 } 720 /* I malloc instead of pre-declare; so that if the file ends 721 * up being too big for this bitmap I can retry 722 */ 723 Bitmap = malloc(Mapsize); 724 if (!Bitmap) { 725 printf("No Bitmap, no multicast. Sorry.\n"); 726 ProhibitMcast = 1; 727 return; 728 } 729 memset(Bitmap, 0, Mapsize); 730 PrevBitmapHole = 0; 731 Multicast = 1; 732 } 733 addr = string_to_ip(mc_adr); 734 if (Mcast_addr != addr) { 735 if (Mcast_addr) 736 eth_mcast_join(Mcast_addr, 0); 737 Mcast_addr = addr; 738 if (eth_mcast_join(Mcast_addr, 1)) { 739 printf("Fail to set mcast, revert to TFTP\n"); 740 ProhibitMcast = 1; 741 mcast_cleanup(); 742 NetStartAgain(); 743 } 744 } 745 MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10); 746 Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); 747 printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); 748 return; 749 } 750 751 #endif /* Multicast TFTP */ 752