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,htons(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 /* Check for 'blksize' option */ 280 for (i=0;i<len-8;i++) { 281 if (strcmp ((char*)pkt+i,"blksize") == 0) { 282 TftpBlkSize = (unsigned short) 283 simple_strtoul((char*)pkt+i+8,NULL,10); 284 #ifdef ET_DEBUG 285 printf ("Blocksize ack: %s, %d\n", 286 (char*)pkt+i+8,TftpBlkSize); 287 #endif 288 break; 289 } 290 } 291 #ifdef CONFIG_MCAST_TFTP 292 parse_multicast_oack((char *)pkt,len-1); 293 if ((Multicast) && (!MasterClient)) 294 TftpState = STATE_DATA; /* passive.. */ 295 else 296 #endif 297 TftpSend (); /* Send ACK */ 298 break; 299 case TFTP_DATA: 300 if (len < 2) 301 return; 302 len -= 2; 303 TftpBlock = ntohs(*(ushort *)pkt); 304 305 /* 306 * RFC1350 specifies that the first data packet will 307 * have sequence number 1. If we receive a sequence 308 * number of 0 this means that there was a wrap 309 * around of the (16 bit) counter. 310 */ 311 if (TftpBlock == 0) { 312 TftpBlockWrap++; 313 TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE; 314 printf ("\n\t %lu MB received\n\t ", TftpBlockWrapOffset>>20); 315 } else { 316 if (((TftpBlock - 1) % 10) == 0) { 317 putc ('#'); 318 } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) { 319 puts ("\n\t "); 320 } 321 } 322 323 #ifdef ET_DEBUG 324 if (TftpState == STATE_RRQ) { 325 puts ("Server did not acknowledge timeout option!\n"); 326 } 327 #endif 328 329 if (TftpState == STATE_RRQ || TftpState == STATE_OACK) { 330 /* first block received */ 331 TftpState = STATE_DATA; 332 TftpServerPort = src; 333 TftpLastBlock = 0; 334 TftpBlockWrap = 0; 335 TftpBlockWrapOffset = 0; 336 337 #ifdef CONFIG_MCAST_TFTP 338 if (Multicast) { /* start!=1 common if mcast */ 339 TftpLastBlock = TftpBlock - 1; 340 } else 341 #endif 342 if (TftpBlock != 1) { /* Assertion */ 343 printf ("\nTFTP error: " 344 "First block is not block 1 (%ld)\n" 345 "Starting again\n\n", 346 TftpBlock); 347 NetStartAgain (); 348 break; 349 } 350 } 351 352 if (TftpBlock == TftpLastBlock) { 353 /* 354 * Same block again; ignore it. 355 */ 356 break; 357 } 358 359 TftpLastBlock = TftpBlock; 360 NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); 361 362 store_block (TftpBlock - 1, pkt + 2, len); 363 364 /* 365 * Acknoledge the block just received, which will prompt 366 * the server for the next one. 367 */ 368 #ifdef CONFIG_MCAST_TFTP 369 /* if I am the MasterClient, actively calculate what my next 370 * needed block is; else I'm passive; not ACKING 371 */ 372 if (Multicast) { 373 if (len < TftpBlkSize) { 374 TftpEndingBlock = TftpBlock; 375 } else if (MasterClient) { 376 TftpBlock = PrevBitmapHole = 377 ext2_find_next_zero_bit( 378 Bitmap, 379 (Mapsize*8), 380 PrevBitmapHole); 381 if (TftpBlock > ((Mapsize*8) - 1)) { 382 printf ("tftpfile too big\n"); 383 /* try to double it and retry */ 384 Mapsize<<=1; 385 mcast_cleanup(); 386 NetStartAgain (); 387 return; 388 } 389 TftpLastBlock = TftpBlock; 390 } 391 } 392 #endif 393 TftpSend (); 394 395 #ifdef CONFIG_MCAST_TFTP 396 if (Multicast) { 397 if (MasterClient && (TftpBlock >= TftpEndingBlock)) { 398 puts ("\nMulticast tftp done\n"); 399 mcast_cleanup(); 400 NetState = NETLOOP_SUCCESS; 401 } 402 } 403 else 404 #endif 405 if (len < TftpBlkSize) { 406 /* 407 * We received the whole thing. Try to 408 * run it. 409 */ 410 puts ("\ndone\n"); 411 NetState = NETLOOP_SUCCESS; 412 } 413 break; 414 415 case TFTP_ERROR: 416 printf ("\nTFTP error: '%s' (%d)\n", 417 pkt + 2, ntohs(*(ushort *)pkt)); 418 puts ("Starting again\n\n"); 419 #ifdef CONFIG_MCAST_TFTP 420 mcast_cleanup(); 421 #endif 422 NetStartAgain (); 423 break; 424 } 425 } 426 427 428 static void 429 TftpTimeout (void) 430 { 431 if (++TftpTimeoutCount > TIMEOUT_COUNT) { 432 puts ("\nRetry count exceeded; starting again\n"); 433 #ifdef CONFIG_MCAST_TFTP 434 mcast_cleanup(); 435 #endif 436 NetStartAgain (); 437 } else { 438 puts ("T "); 439 NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); 440 TftpSend (); 441 } 442 } 443 444 445 void 446 TftpStart (void) 447 { 448 #ifdef CONFIG_TFTP_PORT 449 char *ep; /* Environment pointer */ 450 #endif 451 452 if (BootFile[0] == '\0') { 453 sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", 454 NetOurIP & 0xFF, 455 (NetOurIP >> 8) & 0xFF, 456 (NetOurIP >> 16) & 0xFF, 457 (NetOurIP >> 24) & 0xFF ); 458 tftp_filename = default_filename; 459 460 printf ("*** Warning: no boot file name; using '%s'\n", 461 tftp_filename); 462 } else { 463 tftp_filename = BootFile; 464 } 465 466 #if defined(CONFIG_NET_MULTI) 467 printf ("Using %s device\n", eth_get_name()); 468 #endif 469 puts ("TFTP from server "); print_IPaddr (NetServerIP); 470 puts ("; our IP address is "); print_IPaddr (NetOurIP); 471 472 /* Check if we need to send across this subnet */ 473 if (NetOurGatewayIP && NetOurSubnetMask) { 474 IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; 475 IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; 476 477 if (OurNet != ServerNet) { 478 puts ("; sending through gateway "); 479 print_IPaddr (NetOurGatewayIP) ; 480 } 481 } 482 putc ('\n'); 483 484 printf ("Filename '%s'.", tftp_filename); 485 486 if (NetBootFileSize) { 487 printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9); 488 print_size (NetBootFileSize<<9, ""); 489 } 490 491 putc ('\n'); 492 493 printf ("Load address: 0x%lx\n", load_addr); 494 495 puts ("Loading: *\b"); 496 497 NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); 498 NetSetHandler (TftpHandler); 499 500 TftpServerPort = WELL_KNOWN_PORT; 501 TftpTimeoutCount = 0; 502 TftpState = STATE_RRQ; 503 /* Use a pseudo-random port unless a specific port is set */ 504 TftpOurPort = 1024 + (get_timer(0) % 3072); 505 506 #ifdef CONFIG_TFTP_PORT 507 if ((ep = getenv("tftpdstp")) != NULL) { 508 TftpServerPort = simple_strtol(ep, NULL, 10); 509 } 510 if ((ep = getenv("tftpsrcp")) != NULL) { 511 TftpOurPort= simple_strtol(ep, NULL, 10); 512 } 513 #endif 514 TftpBlock = 0; 515 516 /* zero out server ether in case the server ip has changed */ 517 memset(NetServerEther, 0, 6); 518 /* Revert TftpBlkSize to dflt */ 519 TftpBlkSize = TFTP_BLOCK_SIZE; 520 #ifdef CONFIG_MCAST_TFTP 521 mcast_cleanup(); 522 #endif 523 524 TftpSend (); 525 } 526 527 #ifdef CONFIG_MCAST_TFTP 528 /* Credits: atftp project. 529 */ 530 531 /* pick up BcastAddr, Port, and whether I am [now] the master-client. * 532 * Frame: 533 * +-------+-----------+---+-------~~-------+---+ 534 * | opc | multicast | 0 | addr, port, mc | 0 | 535 * +-------+-----------+---+-------~~-------+---+ 536 * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then 537 * I am the new master-client so must send ACKs to DataBlocks. If I am not 538 * master-client, I'm a passive client, gathering what DataBlocks I may and 539 * making note of which ones I got in my bitmask. 540 * In theory, I never go from master->passive.. 541 * .. this comes in with pkt already pointing just past opc 542 */ 543 static void parse_multicast_oack(char *pkt, int len) 544 { 545 int i; 546 IPaddr_t addr; 547 char *mc_adr, *port, *mc; 548 549 mc_adr=port=mc=NULL; 550 /* march along looking for 'multicast\0', which has to start at least 551 * 14 bytes back from the end. 552 */ 553 for (i=0;i<len-14;i++) 554 if (strcmp (pkt+i,"multicast") == 0) 555 break; 556 if (i >= (len-14)) /* non-Multicast OACK, ign. */ 557 return; 558 559 i+=10; /* strlen multicast */ 560 mc_adr = pkt+i; 561 for (;i<len;i++) { 562 if (*(pkt+i) == ',') { 563 *(pkt+i) = '\0'; 564 if (port) { 565 mc = pkt+i+1; 566 break; 567 } else { 568 port = pkt+i+1; 569 } 570 } 571 } 572 if (!port || !mc_adr || !mc ) return; 573 if (Multicast && MasterClient) { 574 printf ("I got a OACK as master Client, WRONG!\n"); 575 return; 576 } 577 /* ..I now accept packets destined for this MCAST addr, port */ 578 if (!Multicast) { 579 if (Bitmap) { 580 printf ("Internal failure! no mcast.\n"); 581 free(Bitmap); 582 Bitmap=NULL; 583 ProhibitMcast=1; 584 return ; 585 } 586 /* I malloc instead of pre-declare; so that if the file ends 587 * up being too big for this bitmap I can retry 588 */ 589 if (!(Bitmap = malloc (Mapsize))) { 590 printf ("No Bitmap, no multicast. Sorry.\n"); 591 ProhibitMcast=1; 592 return; 593 } 594 memset (Bitmap,0,Mapsize); 595 PrevBitmapHole = 0; 596 Multicast = 1; 597 } 598 addr = string_to_ip(mc_adr); 599 if (Mcast_addr != addr) { 600 if (Mcast_addr) 601 eth_mcast_join(Mcast_addr, 0); 602 if (eth_mcast_join(Mcast_addr=addr, 1)) { 603 printf ("Fail to set mcast, revert to TFTP\n"); 604 ProhibitMcast=1; 605 mcast_cleanup(); 606 NetStartAgain(); 607 } 608 } 609 MasterClient = (unsigned char)simple_strtoul((char *)mc,NULL,10); 610 Mcast_port = (unsigned short)simple_strtoul(port,NULL,10); 611 printf ("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); 612 return; 613 } 614 615 #endif /* Multicast TFTP */ 616 617 #endif /* CFG_CMD_NET */ 618