xref: /rk3399_rockchip-uboot/net/tftp.c (revision e4cde2f70d2377fdf484cbbc1729b188f81b8ec8)
1 /*
2  * Copyright 1994, 1995, 2000 Neil Russell.
3  * (See License)
4  * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
5  * Copyright 2011 Comelit Group SpA,
6  *                Luca Ceresoli <luca.ceresoli@comelit.it>
7  */
8 
9 #include <common.h>
10 #include <command.h>
11 #include <net.h>
12 #include "tftp.h"
13 #include "bootp.h"
14 
15 /* Well known TFTP port # */
16 #define WELL_KNOWN_PORT	69
17 /* Millisecs to timeout for lost pkt */
18 #define TIMEOUT		5000UL
19 #ifndef	CONFIG_NET_RETRY_COUNT
20 /* # of timeouts before giving up */
21 # define TIMEOUT_COUNT	10
22 #else
23 # define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT * 2)
24 #endif
25 /* Number of "loading" hashes per line (for checking the image size) */
26 #define HASHES_PER_LINE	65
27 
28 /*
29  *	TFTP operations.
30  */
31 #define TFTP_RRQ	1
32 #define TFTP_WRQ	2
33 #define TFTP_DATA	3
34 #define TFTP_ACK	4
35 #define TFTP_ERROR	5
36 #define TFTP_OACK	6
37 
38 static ulong TftpTimeoutMSecs = TIMEOUT;
39 static int TftpTimeoutCountMax = TIMEOUT_COUNT;
40 
41 /*
42  * These globals govern the timeout behavior when attempting a connection to a
43  * TFTP server. TftpRRQTimeoutMSecs specifies the number of milliseconds to
44  * wait for the server to respond to initial connection. Second global,
45  * TftpRRQTimeoutCountMax, gives the number of such connection retries.
46  * TftpRRQTimeoutCountMax must be non-negative and TftpRRQTimeoutMSecs must be
47  * positive. The globals are meant to be set (and restored) by code needing
48  * non-standard timeout behavior when initiating a TFTP transfer.
49  */
50 ulong TftpRRQTimeoutMSecs = TIMEOUT;
51 int TftpRRQTimeoutCountMax = TIMEOUT_COUNT;
52 
53 enum {
54 	TFTP_ERR_UNDEFINED           = 0,
55 	TFTP_ERR_FILE_NOT_FOUND      = 1,
56 	TFTP_ERR_ACCESS_DENIED       = 2,
57 	TFTP_ERR_DISK_FULL           = 3,
58 	TFTP_ERR_UNEXPECTED_OPCODE   = 4,
59 	TFTP_ERR_UNKNOWN_TRANSFER_ID  = 5,
60 	TFTP_ERR_FILE_ALREADY_EXISTS = 6,
61 };
62 
63 static IPaddr_t TftpRemoteIP;
64 /* The UDP port at their end */
65 static int	TftpRemotePort;
66 /* The UDP port at our end */
67 static int	TftpOurPort;
68 static int	TftpTimeoutCount;
69 /* packet sequence number */
70 static ulong	TftpBlock;
71 /* last packet sequence number received */
72 static ulong	TftpLastBlock;
73 /* count of sequence number wraparounds */
74 static ulong	TftpBlockWrap;
75 /* memory offset due to wrapping */
76 static ulong	TftpBlockWrapOffset;
77 static int	TftpState;
78 #ifdef CONFIG_TFTP_TSIZE
79 /* The file size reported by the server */
80 static int	TftpTsize;
81 /* The number of hashes we printed */
82 static short	TftpNumchars;
83 #endif
84 
85 #define STATE_SEND_RRQ	1
86 #define STATE_DATA	2
87 #define STATE_TOO_LARGE	3
88 #define STATE_BAD_MAGIC	4
89 #define STATE_OACK	5
90 #define STATE_RECV_WRQ	6
91 
92 /* default TFTP block size */
93 #define TFTP_BLOCK_SIZE		512
94 /* sequence number is 16 bit */
95 #define TFTP_SEQUENCE_SIZE	((ulong)(1<<16))
96 
97 #define DEFAULT_NAME_LEN	(8 + 4 + 1)
98 static char default_filename[DEFAULT_NAME_LEN];
99 
100 #ifndef CONFIG_TFTP_FILE_NAME_MAX_LEN
101 #define MAX_LEN 128
102 #else
103 #define MAX_LEN CONFIG_TFTP_FILE_NAME_MAX_LEN
104 #endif
105 
106 static char tftp_filename[MAX_LEN];
107 
108 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
109 extern flash_info_t flash_info[];
110 #endif
111 
112 /* 512 is poor choice for ethernet, MTU is typically 1500.
113  * Minus eth.hdrs thats 1468.  Can get 2x better throughput with
114  * almost-MTU block sizes.  At least try... fall back to 512 if need be.
115  * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file)
116  */
117 #ifdef CONFIG_TFTP_BLOCKSIZE
118 #define TFTP_MTU_BLOCKSIZE CONFIG_TFTP_BLOCKSIZE
119 #else
120 #define TFTP_MTU_BLOCKSIZE 1468
121 #endif
122 
123 static unsigned short TftpBlkSize = TFTP_BLOCK_SIZE;
124 static unsigned short TftpBlkSizeOption = TFTP_MTU_BLOCKSIZE;
125 
126 #ifdef CONFIG_MCAST_TFTP
127 #include <malloc.h>
128 #define MTFTP_BITMAPSIZE	0x1000
129 static unsigned *Bitmap;
130 static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE;
131 static uchar ProhibitMcast, MasterClient;
132 static uchar Multicast;
133 extern IPaddr_t Mcast_addr;
134 static int Mcast_port;
135 static ulong TftpEndingBlock; /* can get 'last' block before done..*/
136 
137 static void parse_multicast_oack(char *pkt, int len);
138 
139 static void
140 mcast_cleanup(void)
141 {
142 	if (Mcast_addr)
143 		eth_mcast_join(Mcast_addr, 0);
144 	if (Bitmap)
145 		free(Bitmap);
146 	Bitmap = NULL;
147 	Mcast_addr = Multicast = Mcast_port = 0;
148 	TftpEndingBlock = -1;
149 }
150 
151 #endif	/* CONFIG_MCAST_TFTP */
152 
153 static __inline__ void
154 store_block(unsigned block, uchar *src, unsigned len)
155 {
156 	ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
157 	ulong newsize = offset + len;
158 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
159 	int i, rc = 0;
160 
161 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
162 		/* start address in flash? */
163 		if (flash_info[i].flash_id == FLASH_UNKNOWN)
164 			continue;
165 		if (load_addr + offset >= flash_info[i].start[0]) {
166 			rc = 1;
167 			break;
168 		}
169 	}
170 
171 	if (rc) { /* Flash is destination for this packet */
172 		rc = flash_write((char *)src, (ulong)(load_addr+offset), len);
173 		if (rc) {
174 			flash_perror(rc);
175 			NetState = NETLOOP_FAIL;
176 			return;
177 		}
178 	}
179 	else
180 #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
181 	{
182 		(void)memcpy((void *)(load_addr + offset), src, len);
183 	}
184 #ifdef CONFIG_MCAST_TFTP
185 	if (Multicast)
186 		ext2_set_bit(block, Bitmap);
187 #endif
188 
189 	if (NetBootFileXferSize < newsize)
190 		NetBootFileXferSize = newsize;
191 }
192 
193 /* Clear our state ready for a new transfer */
194 void new_transfer(void)
195 {
196 	TftpLastBlock = 0;
197 	TftpBlockWrap = 0;
198 	TftpBlockWrapOffset = 0;
199 #ifdef CONFIG_CMD_TFTPPUT
200 	TftpFinalBlock = 0;
201 #endif
202 }
203 
204 static void TftpSend(void);
205 static void TftpTimeout(void);
206 
207 /**********************************************************************/
208 
209 static void show_block_marker(void)
210 {
211 #ifdef CONFIG_TFTP_TSIZE
212 	if (TftpTsize) {
213 		ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset;
214 
215 		while (TftpNumchars < pos * 50 / TftpTsize) {
216 			putc('#');
217 			TftpNumchars++;
218 		}
219 	}
220 #endif
221 	else {
222 		if (((TftpBlock - 1) % 10) == 0)
223 			putc('#');
224 		else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
225 			puts("\n\t ");
226 	}
227 }
228 
229 /**
230  * restart the current transfer due to an error
231  *
232  * @param msg	Message to print for user
233  */
234 static void restart(const char *msg)
235 {
236 	printf("\n%s; starting again\n", msg);
237 #ifdef CONFIG_MCAST_TFTP
238 	mcast_cleanup();
239 #endif
240 	NetStartAgain();
241 }
242 
243 /*
244  * Check if the block number has wrapped, and update progress
245  *
246  * TODO: The egregious use of global variables in this file should be tidied.
247  */
248 static void update_block_number(void)
249 {
250 	/*
251 	 * RFC1350 specifies that the first data packet will
252 	 * have sequence number 1. If we receive a sequence
253 	 * number of 0 this means that there was a wrap
254 	 * around of the (16 bit) counter.
255 	 */
256 	if (TftpBlock == 0) {
257 		TftpBlockWrap++;
258 		TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
259 		TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */
260 	} else {
261 		show_block_marker();
262 	}
263 }
264 
265 /* The TFTP get or put is complete */
266 static void tftp_complete(void)
267 {
268 #ifdef CONFIG_TFTP_TSIZE
269 	/* Print hash marks for the last packet received */
270 	while (TftpTsize && TftpNumchars < 49) {
271 		putc('#');
272 		TftpNumchars++;
273 	}
274 #endif
275 	puts("\ndone\n");
276 	NetState = NETLOOP_SUCCESS;
277 }
278 
279 static void
280 TftpSend(void)
281 {
282 	volatile uchar *pkt;
283 	volatile uchar *xp;
284 	int		len = 0;
285 	volatile ushort *s;
286 
287 #ifdef CONFIG_MCAST_TFTP
288 	/* Multicast TFTP.. non-MasterClients do not ACK data. */
289 	if (Multicast
290 	 && (TftpState == STATE_DATA)
291 	 && (MasterClient == 0))
292 		return;
293 #endif
294 	/*
295 	 *	We will always be sending some sort of packet, so
296 	 *	cobble together the packet headers now.
297 	 */
298 	pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
299 
300 	switch (TftpState) {
301 
302 	case STATE_SEND_RRQ:
303 		xp = pkt;
304 		s = (ushort *)pkt;
305 		*s++ = htons(TFTP_RRQ);
306 		pkt = (uchar *)s;
307 		strcpy((char *)pkt, tftp_filename);
308 		pkt += strlen(tftp_filename) + 1;
309 		strcpy((char *)pkt, "octet");
310 		pkt += 5 /*strlen("octet")*/ + 1;
311 		strcpy((char *)pkt, "timeout");
312 		pkt += 7 /*strlen("timeout")*/ + 1;
313 		sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
314 		debug("send option \"timeout %s\"\n", (char *)pkt);
315 		pkt += strlen((char *)pkt) + 1;
316 #ifdef CONFIG_TFTP_TSIZE
317 		memcpy((char *)pkt, "tsize\0000\0", 8);
318 		pkt += 8;
319 #endif
320 		/* try for more effic. blk size */
321 		pkt += sprintf((char *)pkt, "blksize%c%d%c",
322 				0, TftpBlkSizeOption, 0);
323 #ifdef CONFIG_MCAST_TFTP
324 		/* Check all preconditions before even trying the option */
325 		if (!ProhibitMcast
326 		 && (Bitmap = malloc(Mapsize))
327 		 && eth_get_dev()->mcast) {
328 			free(Bitmap);
329 			Bitmap = NULL;
330 			pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0);
331 		}
332 #endif /* CONFIG_MCAST_TFTP */
333 		len = pkt - xp;
334 		break;
335 
336 	case STATE_OACK:
337 #ifdef CONFIG_MCAST_TFTP
338 		/* My turn!  Start at where I need blocks I missed.*/
339 		if (Multicast)
340 			TftpBlock = ext2_find_next_zero_bit(Bitmap,
341 							    (Mapsize*8), 0);
342 		/*..falling..*/
343 #endif
344 
345 	case STATE_RECV_WRQ:
346 	case STATE_DATA:
347 		xp = pkt;
348 		s = (ushort *)pkt;
349 		*s++ = htons(TFTP_ACK);
350 		*s++ = htons(TftpBlock);
351 		pkt = (uchar *)s;
352 		len = pkt - xp;
353 		break;
354 
355 	case STATE_TOO_LARGE:
356 		xp = pkt;
357 		s = (ushort *)pkt;
358 		*s++ = htons(TFTP_ERROR);
359 		*s++ = htons(3);
360 		pkt = (uchar *)s;
361 		strcpy((char *)pkt, "File too large");
362 		pkt += 14 /*strlen("File too large")*/ + 1;
363 		len = pkt - xp;
364 		break;
365 
366 	case STATE_BAD_MAGIC:
367 		xp = pkt;
368 		s = (ushort *)pkt;
369 		*s++ = htons(TFTP_ERROR);
370 		*s++ = htons(2);
371 		pkt = (uchar *)s;
372 		strcpy((char *)pkt, "File has bad magic");
373 		pkt += 18 /*strlen("File has bad magic")*/ + 1;
374 		len = pkt - xp;
375 		break;
376 	}
377 
378 	NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort,
379 			 TftpOurPort, len);
380 }
381 
382 
383 static void
384 TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
385 	    unsigned len)
386 {
387 	ushort proto;
388 	ushort *s;
389 	int i;
390 
391 	if (dest != TftpOurPort) {
392 #ifdef CONFIG_MCAST_TFTP
393 		if (Multicast
394 		 && (!Mcast_port || (dest != Mcast_port)))
395 #endif
396 			return;
397 	}
398 	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
399 	    TftpState != STATE_RECV_WRQ)
400 		return;
401 
402 	if (len < 2)
403 		return;
404 	len -= 2;
405 	/* warning: don't use increment (++) in ntohs() macros!! */
406 	s = (ushort *)pkt;
407 	proto = *s++;
408 	pkt = (uchar *)s;
409 	switch (ntohs(proto)) {
410 
411 	case TFTP_RRQ:
412 	case TFTP_ACK:
413 		break;
414 	default:
415 		break;
416 
417 #ifdef CONFIG_CMD_TFTPSRV
418 	case TFTP_WRQ:
419 		debug("Got WRQ\n");
420 		TftpRemoteIP = sip;
421 		TftpRemotePort = src;
422 		TftpOurPort = 1024 + (get_timer(0) % 3072);
423 		new_transfer();
424 		TftpSend(); /* Send ACK(0) */
425 		break;
426 #endif
427 
428 	case TFTP_OACK:
429 		debug("Got OACK: %s %s\n",
430 			pkt,
431 			pkt + strlen((char *)pkt) + 1);
432 		TftpState = STATE_OACK;
433 		TftpRemotePort = src;
434 		/*
435 		 * Check for 'blksize' option.
436 		 * Careful: "i" is signed, "len" is unsigned, thus
437 		 * something like "len-8" may give a *huge* number
438 		 */
439 		for (i = 0; i+8 < len; i++) {
440 			if (strcmp((char *)pkt+i, "blksize") == 0) {
441 				TftpBlkSize = (unsigned short)
442 					simple_strtoul((char *)pkt+i+8, NULL,
443 						       10);
444 				debug("Blocksize ack: %s, %d\n",
445 					(char *)pkt+i+8, TftpBlkSize);
446 			}
447 #ifdef CONFIG_TFTP_TSIZE
448 			if (strcmp((char *)pkt+i, "tsize") == 0) {
449 				TftpTsize = simple_strtoul((char *)pkt+i+6,
450 							   NULL, 10);
451 				debug("size = %s, %d\n",
452 					 (char *)pkt+i+6, TftpTsize);
453 			}
454 #endif
455 		}
456 #ifdef CONFIG_MCAST_TFTP
457 		parse_multicast_oack((char *)pkt, len-1);
458 		if ((Multicast) && (!MasterClient))
459 			TftpState = STATE_DATA;	/* passive.. */
460 		else
461 #endif
462 		TftpSend(); /* Send ACK */
463 		break;
464 	case TFTP_DATA:
465 		if (len < 2)
466 			return;
467 		len -= 2;
468 		TftpBlock = ntohs(*(ushort *)pkt);
469 
470 		update_block_number();
471 
472 		if (TftpState == STATE_SEND_RRQ)
473 			debug("Server did not acknowledge timeout option!\n");
474 
475 		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK ||
476 		    TftpState == STATE_RECV_WRQ) {
477 			/* first block received */
478 			TftpState = STATE_DATA;
479 			TftpRemotePort = src;
480 			new_transfer();
481 
482 #ifdef CONFIG_MCAST_TFTP
483 			if (Multicast) { /* start!=1 common if mcast */
484 				TftpLastBlock = TftpBlock - 1;
485 			} else
486 #endif
487 			if (TftpBlock != 1) {	/* Assertion */
488 				printf("\nTFTP error: "
489 				       "First block is not block 1 (%ld)\n"
490 				       "Starting again\n\n",
491 					TftpBlock);
492 				NetStartAgain();
493 				break;
494 			}
495 		}
496 
497 		if (TftpBlock == TftpLastBlock) {
498 			/*
499 			 *	Same block again; ignore it.
500 			 */
501 			break;
502 		}
503 
504 		TftpLastBlock = TftpBlock;
505 		TftpTimeoutCountMax = TIMEOUT_COUNT;
506 		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
507 
508 		store_block(TftpBlock - 1, pkt + 2, len);
509 
510 		/*
511 		 *	Acknowledge the block just received, which will prompt
512 		 *	the remote for the next one.
513 		 */
514 #ifdef CONFIG_MCAST_TFTP
515 		/* if I am the MasterClient, actively calculate what my next
516 		 * needed block is; else I'm passive; not ACKING
517 		 */
518 		if (Multicast) {
519 			if (len < TftpBlkSize)  {
520 				TftpEndingBlock = TftpBlock;
521 			} else if (MasterClient) {
522 				TftpBlock = PrevBitmapHole =
523 					ext2_find_next_zero_bit(
524 						Bitmap,
525 						(Mapsize*8),
526 						PrevBitmapHole);
527 				if (TftpBlock > ((Mapsize*8) - 1)) {
528 					printf("tftpfile too big\n");
529 					/* try to double it and retry */
530 					Mapsize <<= 1;
531 					mcast_cleanup();
532 					NetStartAgain();
533 					return;
534 				}
535 				TftpLastBlock = TftpBlock;
536 			}
537 		}
538 #endif
539 		TftpSend();
540 
541 #ifdef CONFIG_MCAST_TFTP
542 		if (Multicast) {
543 			if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
544 				puts("\nMulticast tftp done\n");
545 				mcast_cleanup();
546 				NetState = NETLOOP_SUCCESS;
547 			}
548 		}
549 		else
550 #endif
551 		if (len < TftpBlkSize)
552 			tftp_complete();
553 		break;
554 
555 	case TFTP_ERROR:
556 		printf("\nTFTP error: '%s' (%d)\n",
557 		       pkt + 2, ntohs(*(ushort *)pkt));
558 
559 		switch (ntohs(*(ushort *)pkt)) {
560 		case TFTP_ERR_FILE_NOT_FOUND:
561 		case TFTP_ERR_ACCESS_DENIED:
562 			puts("Not retrying...\n");
563 			eth_halt();
564 			NetState = NETLOOP_FAIL;
565 			break;
566 		case TFTP_ERR_UNDEFINED:
567 		case TFTP_ERR_DISK_FULL:
568 		case TFTP_ERR_UNEXPECTED_OPCODE:
569 		case TFTP_ERR_UNKNOWN_TRANSFER_ID:
570 		case TFTP_ERR_FILE_ALREADY_EXISTS:
571 		default:
572 			puts("Starting again\n\n");
573 #ifdef CONFIG_MCAST_TFTP
574 			mcast_cleanup();
575 #endif
576 			NetStartAgain();
577 			break;
578 		}
579 		break;
580 	}
581 }
582 
583 
584 static void
585 TftpTimeout(void)
586 {
587 	if (++TftpTimeoutCount > TftpTimeoutCountMax) {
588 		restart("Retry count exceeded");
589 	} else {
590 		puts("T ");
591 		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
592 		if (TftpState != STATE_RECV_WRQ)
593 			TftpSend();
594 	}
595 }
596 
597 
598 void
599 TftpStart(void)
600 {
601 	char *ep;             /* Environment pointer */
602 
603 	/*
604 	 * Allow the user to choose TFTP blocksize and timeout.
605 	 * TFTP protocol has a minimal timeout of 1 second.
606 	 */
607 	ep = getenv("tftpblocksize");
608 	if (ep != NULL)
609 		TftpBlkSizeOption = simple_strtol(ep, NULL, 10);
610 
611 	ep = getenv("tftptimeout");
612 	if (ep != NULL)
613 		TftpTimeoutMSecs = simple_strtol(ep, NULL, 10);
614 
615 	if (TftpTimeoutMSecs < 1000) {
616 		printf("TFTP timeout (%ld ms) too low, "
617 			"set minimum = 1000 ms\n",
618 			TftpTimeoutMSecs);
619 		TftpTimeoutMSecs = 1000;
620 	}
621 
622 	debug("TFTP blocksize = %i, timeout = %ld ms\n",
623 		TftpBlkSizeOption, TftpTimeoutMSecs);
624 
625 	TftpRemoteIP = NetServerIP;
626 	if (BootFile[0] == '\0') {
627 		sprintf(default_filename, "%02lX%02lX%02lX%02lX.img",
628 			NetOurIP & 0xFF,
629 			(NetOurIP >>  8) & 0xFF,
630 			(NetOurIP >> 16) & 0xFF,
631 			(NetOurIP >> 24) & 0xFF);
632 
633 		strncpy(tftp_filename, default_filename, MAX_LEN);
634 		tftp_filename[MAX_LEN-1] = 0;
635 
636 		printf("*** Warning: no boot file name; using '%s'\n",
637 			tftp_filename);
638 	} else {
639 		char *p = strchr(BootFile, ':');
640 
641 		if (p == NULL) {
642 			strncpy(tftp_filename, BootFile, MAX_LEN);
643 			tftp_filename[MAX_LEN-1] = 0;
644 		} else {
645 			TftpRemoteIP = string_to_ip(BootFile);
646 			strncpy(tftp_filename, p + 1, MAX_LEN);
647 			tftp_filename[MAX_LEN-1] = 0;
648 		}
649 	}
650 
651 	printf("Using %s device\n", eth_get_name());
652 	printf("TFTP from server %pI4"
653 		"; our IP address is %pI4", &TftpRemoteIP, &NetOurIP);
654 
655 	/* Check if we need to send across this subnet */
656 	if (NetOurGatewayIP && NetOurSubnetMask) {
657 		IPaddr_t OurNet	= NetOurIP    & NetOurSubnetMask;
658 		IPaddr_t RemoteNet	= TftpRemoteIP & NetOurSubnetMask;
659 
660 		if (OurNet != RemoteNet)
661 			printf("; sending through gateway %pI4",
662 			       &NetOurGatewayIP);
663 	}
664 	putc('\n');
665 
666 	printf("Filename '%s'.", tftp_filename);
667 
668 	if (NetBootFileSize) {
669 		printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
670 		print_size(NetBootFileSize<<9, "");
671 	}
672 
673 	putc('\n');
674 
675 	printf("Load address: 0x%lx\n", load_addr);
676 
677 	puts("Loading: *\b");
678 
679 	TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
680 
681 	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
682 	NetSetHandler(TftpHandler);
683 
684 	TftpRemotePort = WELL_KNOWN_PORT;
685 	TftpTimeoutCount = 0;
686 	TftpState = STATE_SEND_RRQ;
687 	/* Use a pseudo-random port unless a specific port is set */
688 	TftpOurPort = 1024 + (get_timer(0) % 3072);
689 
690 #ifdef CONFIG_TFTP_PORT
691 	ep = getenv("tftpdstp");
692 	if (ep != NULL)
693 		TftpRemotePort = simple_strtol(ep, NULL, 10);
694 	ep = getenv("tftpsrcp");
695 	if (ep != NULL)
696 		TftpOurPort = simple_strtol(ep, NULL, 10);
697 #endif
698 	TftpBlock = 0;
699 
700 	/* zero out server ether in case the server ip has changed */
701 	memset(NetServerEther, 0, 6);
702 	/* Revert TftpBlkSize to dflt */
703 	TftpBlkSize = TFTP_BLOCK_SIZE;
704 #ifdef CONFIG_MCAST_TFTP
705 	mcast_cleanup();
706 #endif
707 #ifdef CONFIG_TFTP_TSIZE
708 	TftpTsize = 0;
709 	TftpNumchars = 0;
710 #endif
711 
712 	TftpSend();
713 }
714 
715 #ifdef CONFIG_CMD_TFTPSRV
716 void
717 TftpStartServer(void)
718 {
719 	tftp_filename[0] = 0;
720 
721 	printf("Using %s device\n", eth_get_name());
722 	printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
723 	printf("Load address: 0x%lx\n", load_addr);
724 
725 	puts("Loading: *\b");
726 
727 	TftpTimeoutCountMax = TIMEOUT_COUNT;
728 	TftpTimeoutCount = 0;
729 	TftpTimeoutMSecs = TIMEOUT;
730 	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
731 
732 	/* Revert TftpBlkSize to dflt */
733 	TftpBlkSize = TFTP_BLOCK_SIZE;
734 	TftpBlock = 0;
735 	TftpOurPort = WELL_KNOWN_PORT;
736 
737 #ifdef CONFIG_TFTP_TSIZE
738 	TftpTsize = 0;
739 	TftpNumchars = 0;
740 #endif
741 
742 	TftpState = STATE_RECV_WRQ;
743 	NetSetHandler(TftpHandler);
744 }
745 #endif /* CONFIG_CMD_TFTPSRV */
746 
747 #ifdef CONFIG_MCAST_TFTP
748 /* Credits: atftp project.
749  */
750 
751 /* pick up BcastAddr, Port, and whether I am [now] the master-client. *
752  * Frame:
753  *    +-------+-----------+---+-------~~-------+---+
754  *    |  opc  | multicast | 0 | addr, port, mc | 0 |
755  *    +-------+-----------+---+-------~~-------+---+
756  * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
757  * I am the new master-client so must send ACKs to DataBlocks.  If I am not
758  * master-client, I'm a passive client, gathering what DataBlocks I may and
759  * making note of which ones I got in my bitmask.
760  * In theory, I never go from master->passive..
761  * .. this comes in with pkt already pointing just past opc
762  */
763 static void parse_multicast_oack(char *pkt, int len)
764 {
765 	int i;
766 	IPaddr_t addr;
767 	char *mc_adr, *port,  *mc;
768 
769 	mc_adr = port = mc = NULL;
770 	/* march along looking for 'multicast\0', which has to start at least
771 	 * 14 bytes back from the end.
772 	 */
773 	for (i = 0; i < len-14; i++)
774 		if (strcmp(pkt+i, "multicast") == 0)
775 			break;
776 	if (i >= (len-14)) /* non-Multicast OACK, ign. */
777 		return;
778 
779 	i += 10; /* strlen multicast */
780 	mc_adr = pkt+i;
781 	for (; i < len; i++) {
782 		if (*(pkt+i) == ',') {
783 			*(pkt+i) = '\0';
784 			if (port) {
785 				mc = pkt+i+1;
786 				break;
787 			} else {
788 				port = pkt+i+1;
789 			}
790 		}
791 	}
792 	if (!port || !mc_adr || !mc)
793 		return;
794 	if (Multicast && MasterClient) {
795 		printf("I got a OACK as master Client, WRONG!\n");
796 		return;
797 	}
798 	/* ..I now accept packets destined for this MCAST addr, port */
799 	if (!Multicast) {
800 		if (Bitmap) {
801 			printf("Internal failure! no mcast.\n");
802 			free(Bitmap);
803 			Bitmap = NULL;
804 			ProhibitMcast = 1;
805 			return ;
806 		}
807 		/* I malloc instead of pre-declare; so that if the file ends
808 		 * up being too big for this bitmap I can retry
809 		 */
810 		Bitmap = malloc(Mapsize);
811 		if (!Bitmap) {
812 			printf("No Bitmap, no multicast. Sorry.\n");
813 			ProhibitMcast = 1;
814 			return;
815 		}
816 		memset(Bitmap, 0, Mapsize);
817 		PrevBitmapHole = 0;
818 		Multicast = 1;
819 	}
820 	addr = string_to_ip(mc_adr);
821 	if (Mcast_addr != addr) {
822 		if (Mcast_addr)
823 			eth_mcast_join(Mcast_addr, 0);
824 		Mcast_addr = addr;
825 		if (eth_mcast_join(Mcast_addr, 1)) {
826 			printf("Fail to set mcast, revert to TFTP\n");
827 			ProhibitMcast = 1;
828 			mcast_cleanup();
829 			NetStartAgain();
830 		}
831 	}
832 	MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10);
833 	Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
834 	printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient);
835 	return;
836 }
837 
838 #endif /* Multicast TFTP */
839