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