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