xref: /rk3399_rockchip-uboot/net/tftp.c (revision f5329bbc3f951f01c39c24f06a57c34d865f5a16)
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 static void TftpSend(void);
194 static void TftpTimeout(void);
195 
196 /**********************************************************************/
197 
198 static void show_block_marker(void)
199 {
200 #ifdef CONFIG_TFTP_TSIZE
201 	if (TftpTsize) {
202 		ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset;
203 
204 		while (TftpNumchars < pos * 50 / TftpTsize) {
205 			putc('#');
206 			TftpNumchars++;
207 		}
208 	}
209 #endif
210 	else {
211 		if (((TftpBlock - 1) % 10) == 0)
212 			putc('#');
213 		else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
214 			puts("\n\t ");
215 	}
216 }
217 
218 /* The TFTP get or put is complete */
219 static void tftp_complete(void)
220 {
221 #ifdef CONFIG_TFTP_TSIZE
222 	/* Print hash marks for the last packet received */
223 	while (TftpTsize && TftpNumchars < 49) {
224 		putc('#');
225 		TftpNumchars++;
226 	}
227 #endif
228 	puts("\ndone\n");
229 	NetState = NETLOOP_SUCCESS;
230 }
231 
232 static void
233 TftpSend(void)
234 {
235 	volatile uchar *pkt;
236 	volatile uchar *xp;
237 	int		len = 0;
238 	volatile ushort *s;
239 
240 #ifdef CONFIG_MCAST_TFTP
241 	/* Multicast TFTP.. non-MasterClients do not ACK data. */
242 	if (Multicast
243 	 && (TftpState == STATE_DATA)
244 	 && (MasterClient == 0))
245 		return;
246 #endif
247 	/*
248 	 *	We will always be sending some sort of packet, so
249 	 *	cobble together the packet headers now.
250 	 */
251 	pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
252 
253 	switch (TftpState) {
254 
255 	case STATE_SEND_RRQ:
256 		xp = pkt;
257 		s = (ushort *)pkt;
258 		*s++ = htons(TFTP_RRQ);
259 		pkt = (uchar *)s;
260 		strcpy((char *)pkt, tftp_filename);
261 		pkt += strlen(tftp_filename) + 1;
262 		strcpy((char *)pkt, "octet");
263 		pkt += 5 /*strlen("octet")*/ + 1;
264 		strcpy((char *)pkt, "timeout");
265 		pkt += 7 /*strlen("timeout")*/ + 1;
266 		sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
267 		debug("send option \"timeout %s\"\n", (char *)pkt);
268 		pkt += strlen((char *)pkt) + 1;
269 #ifdef CONFIG_TFTP_TSIZE
270 		memcpy((char *)pkt, "tsize\0000\0", 8);
271 		pkt += 8;
272 #endif
273 		/* try for more effic. blk size */
274 		pkt += sprintf((char *)pkt, "blksize%c%d%c",
275 				0, TftpBlkSizeOption, 0);
276 #ifdef CONFIG_MCAST_TFTP
277 		/* Check all preconditions before even trying the option */
278 		if (!ProhibitMcast
279 		 && (Bitmap = malloc(Mapsize))
280 		 && eth_get_dev()->mcast) {
281 			free(Bitmap);
282 			Bitmap = NULL;
283 			pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0);
284 		}
285 #endif /* CONFIG_MCAST_TFTP */
286 		len = pkt - xp;
287 		break;
288 
289 	case STATE_OACK:
290 #ifdef CONFIG_MCAST_TFTP
291 		/* My turn!  Start at where I need blocks I missed.*/
292 		if (Multicast)
293 			TftpBlock = ext2_find_next_zero_bit(Bitmap,
294 							    (Mapsize*8), 0);
295 		/*..falling..*/
296 #endif
297 
298 	case STATE_RECV_WRQ:
299 	case STATE_DATA:
300 		xp = pkt;
301 		s = (ushort *)pkt;
302 		*s++ = htons(TFTP_ACK);
303 		*s++ = htons(TftpBlock);
304 		pkt = (uchar *)s;
305 		len = pkt - xp;
306 		break;
307 
308 	case STATE_TOO_LARGE:
309 		xp = pkt;
310 		s = (ushort *)pkt;
311 		*s++ = htons(TFTP_ERROR);
312 		*s++ = htons(3);
313 		pkt = (uchar *)s;
314 		strcpy((char *)pkt, "File too large");
315 		pkt += 14 /*strlen("File too large")*/ + 1;
316 		len = pkt - xp;
317 		break;
318 
319 	case STATE_BAD_MAGIC:
320 		xp = pkt;
321 		s = (ushort *)pkt;
322 		*s++ = htons(TFTP_ERROR);
323 		*s++ = htons(2);
324 		pkt = (uchar *)s;
325 		strcpy((char *)pkt, "File has bad magic");
326 		pkt += 18 /*strlen("File has bad magic")*/ + 1;
327 		len = pkt - xp;
328 		break;
329 	}
330 
331 	NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort,
332 			 TftpOurPort, len);
333 }
334 
335 
336 static void
337 TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
338 	    unsigned len)
339 {
340 	ushort proto;
341 	ushort *s;
342 	int i;
343 
344 	if (dest != TftpOurPort) {
345 #ifdef CONFIG_MCAST_TFTP
346 		if (Multicast
347 		 && (!Mcast_port || (dest != Mcast_port)))
348 #endif
349 			return;
350 	}
351 	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
352 	    TftpState != STATE_RECV_WRQ)
353 		return;
354 
355 	if (len < 2)
356 		return;
357 	len -= 2;
358 	/* warning: don't use increment (++) in ntohs() macros!! */
359 	s = (ushort *)pkt;
360 	proto = *s++;
361 	pkt = (uchar *)s;
362 	switch (ntohs(proto)) {
363 
364 	case TFTP_RRQ:
365 	case TFTP_ACK:
366 		break;
367 	default:
368 		break;
369 
370 #ifdef CONFIG_CMD_TFTPSRV
371 	case TFTP_WRQ:
372 		debug("Got WRQ\n");
373 		TftpRemoteIP = sip;
374 		TftpRemotePort = src;
375 		TftpOurPort = 1024 + (get_timer(0) % 3072);
376 		TftpLastBlock = 0;
377 		TftpBlockWrap = 0;
378 		TftpBlockWrapOffset = 0;
379 		TftpSend(); /* Send ACK(0) */
380 		break;
381 #endif
382 
383 	case TFTP_OACK:
384 		debug("Got OACK: %s %s\n",
385 			pkt,
386 			pkt + strlen((char *)pkt) + 1);
387 		TftpState = STATE_OACK;
388 		TftpRemotePort = src;
389 		/*
390 		 * Check for 'blksize' option.
391 		 * Careful: "i" is signed, "len" is unsigned, thus
392 		 * something like "len-8" may give a *huge* number
393 		 */
394 		for (i = 0; i+8 < len; i++) {
395 			if (strcmp((char *)pkt+i, "blksize") == 0) {
396 				TftpBlkSize = (unsigned short)
397 					simple_strtoul((char *)pkt+i+8, NULL,
398 						       10);
399 				debug("Blocksize ack: %s, %d\n",
400 					(char *)pkt+i+8, TftpBlkSize);
401 			}
402 #ifdef CONFIG_TFTP_TSIZE
403 			if (strcmp((char *)pkt+i, "tsize") == 0) {
404 				TftpTsize = simple_strtoul((char *)pkt+i+6,
405 							   NULL, 10);
406 				debug("size = %s, %d\n",
407 					 (char *)pkt+i+6, TftpTsize);
408 			}
409 #endif
410 		}
411 #ifdef CONFIG_MCAST_TFTP
412 		parse_multicast_oack((char *)pkt, len-1);
413 		if ((Multicast) && (!MasterClient))
414 			TftpState = STATE_DATA;	/* passive.. */
415 		else
416 #endif
417 		TftpSend(); /* Send ACK */
418 		break;
419 	case TFTP_DATA:
420 		if (len < 2)
421 			return;
422 		len -= 2;
423 		TftpBlock = ntohs(*(ushort *)pkt);
424 
425 		/*
426 		 * RFC1350 specifies that the first data packet will
427 		 * have sequence number 1. If we receive a sequence
428 		 * number of 0 this means that there was a wrap
429 		 * around of the (16 bit) counter.
430 		 */
431 		if (TftpBlock == 0) {
432 			TftpBlockWrap++;
433 			TftpBlockWrapOffset +=
434 				TftpBlkSize * TFTP_SEQUENCE_SIZE;
435 			printf("\n\t %lu MB received\n\t ",
436 				TftpBlockWrapOffset>>20);
437 		} else {
438 			show_block_marker();
439 		}
440 
441 		if (TftpState == STATE_SEND_RRQ)
442 			debug("Server did not acknowledge timeout option!\n");
443 
444 		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK ||
445 		    TftpState == STATE_RECV_WRQ) {
446 			/* first block received */
447 			TftpState = STATE_DATA;
448 			TftpRemotePort = src;
449 			TftpLastBlock = 0;
450 			TftpBlockWrap = 0;
451 			TftpBlockWrapOffset = 0;
452 
453 #ifdef CONFIG_MCAST_TFTP
454 			if (Multicast) { /* start!=1 common if mcast */
455 				TftpLastBlock = TftpBlock - 1;
456 			} else
457 #endif
458 			if (TftpBlock != 1) {	/* Assertion */
459 				printf("\nTFTP error: "
460 				       "First block is not block 1 (%ld)\n"
461 				       "Starting again\n\n",
462 					TftpBlock);
463 				NetStartAgain();
464 				break;
465 			}
466 		}
467 
468 		if (TftpBlock == TftpLastBlock) {
469 			/*
470 			 *	Same block again; ignore it.
471 			 */
472 			break;
473 		}
474 
475 		TftpLastBlock = TftpBlock;
476 		TftpTimeoutCountMax = TIMEOUT_COUNT;
477 		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
478 
479 		store_block(TftpBlock - 1, pkt + 2, len);
480 
481 		/*
482 		 *	Acknowledge the block just received, which will prompt
483 		 *	the remote for the next one.
484 		 */
485 #ifdef CONFIG_MCAST_TFTP
486 		/* if I am the MasterClient, actively calculate what my next
487 		 * needed block is; else I'm passive; not ACKING
488 		 */
489 		if (Multicast) {
490 			if (len < TftpBlkSize)  {
491 				TftpEndingBlock = TftpBlock;
492 			} else if (MasterClient) {
493 				TftpBlock = PrevBitmapHole =
494 					ext2_find_next_zero_bit(
495 						Bitmap,
496 						(Mapsize*8),
497 						PrevBitmapHole);
498 				if (TftpBlock > ((Mapsize*8) - 1)) {
499 					printf("tftpfile too big\n");
500 					/* try to double it and retry */
501 					Mapsize <<= 1;
502 					mcast_cleanup();
503 					NetStartAgain();
504 					return;
505 				}
506 				TftpLastBlock = TftpBlock;
507 			}
508 		}
509 #endif
510 		TftpSend();
511 
512 #ifdef CONFIG_MCAST_TFTP
513 		if (Multicast) {
514 			if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
515 				puts("\nMulticast tftp done\n");
516 				mcast_cleanup();
517 				NetState = NETLOOP_SUCCESS;
518 			}
519 		}
520 		else
521 #endif
522 		if (len < TftpBlkSize)
523 			tftp_complete();
524 		break;
525 
526 	case TFTP_ERROR:
527 		printf("\nTFTP error: '%s' (%d)\n",
528 		       pkt + 2, ntohs(*(ushort *)pkt));
529 
530 		switch (ntohs(*(ushort *)pkt)) {
531 		case TFTP_ERR_FILE_NOT_FOUND:
532 		case TFTP_ERR_ACCESS_DENIED:
533 			puts("Not retrying...\n");
534 			eth_halt();
535 			NetState = NETLOOP_FAIL;
536 			break;
537 		case TFTP_ERR_UNDEFINED:
538 		case TFTP_ERR_DISK_FULL:
539 		case TFTP_ERR_UNEXPECTED_OPCODE:
540 		case TFTP_ERR_UNKNOWN_TRANSFER_ID:
541 		case TFTP_ERR_FILE_ALREADY_EXISTS:
542 		default:
543 			puts("Starting again\n\n");
544 #ifdef CONFIG_MCAST_TFTP
545 			mcast_cleanup();
546 #endif
547 			NetStartAgain();
548 			break;
549 		}
550 		break;
551 	}
552 }
553 
554 
555 static void
556 TftpTimeout(void)
557 {
558 	if (++TftpTimeoutCount > TftpTimeoutCountMax) {
559 		puts("\nRetry count exceeded; starting again\n");
560 #ifdef CONFIG_MCAST_TFTP
561 		mcast_cleanup();
562 #endif
563 		NetStartAgain();
564 	} else {
565 		puts("T ");
566 		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
567 		if (TftpState != STATE_RECV_WRQ)
568 			TftpSend();
569 	}
570 }
571 
572 
573 void
574 TftpStart(void)
575 {
576 	char *ep;             /* Environment pointer */
577 
578 	/*
579 	 * Allow the user to choose TFTP blocksize and timeout.
580 	 * TFTP protocol has a minimal timeout of 1 second.
581 	 */
582 	ep = getenv("tftpblocksize");
583 	if (ep != NULL)
584 		TftpBlkSizeOption = simple_strtol(ep, NULL, 10);
585 
586 	ep = getenv("tftptimeout");
587 	if (ep != NULL)
588 		TftpTimeoutMSecs = simple_strtol(ep, NULL, 10);
589 
590 	if (TftpTimeoutMSecs < 1000) {
591 		printf("TFTP timeout (%ld ms) too low, "
592 			"set minimum = 1000 ms\n",
593 			TftpTimeoutMSecs);
594 		TftpTimeoutMSecs = 1000;
595 	}
596 
597 	debug("TFTP blocksize = %i, timeout = %ld ms\n",
598 		TftpBlkSizeOption, TftpTimeoutMSecs);
599 
600 	TftpRemoteIP = NetServerIP;
601 	if (BootFile[0] == '\0') {
602 		sprintf(default_filename, "%02lX%02lX%02lX%02lX.img",
603 			NetOurIP & 0xFF,
604 			(NetOurIP >>  8) & 0xFF,
605 			(NetOurIP >> 16) & 0xFF,
606 			(NetOurIP >> 24) & 0xFF);
607 
608 		strncpy(tftp_filename, default_filename, MAX_LEN);
609 		tftp_filename[MAX_LEN-1] = 0;
610 
611 		printf("*** Warning: no boot file name; using '%s'\n",
612 			tftp_filename);
613 	} else {
614 		char *p = strchr(BootFile, ':');
615 
616 		if (p == NULL) {
617 			strncpy(tftp_filename, BootFile, MAX_LEN);
618 			tftp_filename[MAX_LEN-1] = 0;
619 		} else {
620 			TftpRemoteIP = string_to_ip(BootFile);
621 			strncpy(tftp_filename, p + 1, MAX_LEN);
622 			tftp_filename[MAX_LEN-1] = 0;
623 		}
624 	}
625 
626 	printf("Using %s device\n", eth_get_name());
627 	printf("TFTP from server %pI4"
628 		"; our IP address is %pI4", &TftpRemoteIP, &NetOurIP);
629 
630 	/* Check if we need to send across this subnet */
631 	if (NetOurGatewayIP && NetOurSubnetMask) {
632 		IPaddr_t OurNet	= NetOurIP    & NetOurSubnetMask;
633 		IPaddr_t RemoteNet	= TftpRemoteIP & NetOurSubnetMask;
634 
635 		if (OurNet != RemoteNet)
636 			printf("; sending through gateway %pI4",
637 			       &NetOurGatewayIP);
638 	}
639 	putc('\n');
640 
641 	printf("Filename '%s'.", tftp_filename);
642 
643 	if (NetBootFileSize) {
644 		printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
645 		print_size(NetBootFileSize<<9, "");
646 	}
647 
648 	putc('\n');
649 
650 	printf("Load address: 0x%lx\n", load_addr);
651 
652 	puts("Loading: *\b");
653 
654 	TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
655 
656 	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
657 	NetSetHandler(TftpHandler);
658 
659 	TftpRemotePort = WELL_KNOWN_PORT;
660 	TftpTimeoutCount = 0;
661 	TftpState = STATE_SEND_RRQ;
662 	/* Use a pseudo-random port unless a specific port is set */
663 	TftpOurPort = 1024 + (get_timer(0) % 3072);
664 
665 #ifdef CONFIG_TFTP_PORT
666 	ep = getenv("tftpdstp");
667 	if (ep != NULL)
668 		TftpRemotePort = simple_strtol(ep, NULL, 10);
669 	ep = getenv("tftpsrcp");
670 	if (ep != NULL)
671 		TftpOurPort = simple_strtol(ep, NULL, 10);
672 #endif
673 	TftpBlock = 0;
674 
675 	/* zero out server ether in case the server ip has changed */
676 	memset(NetServerEther, 0, 6);
677 	/* Revert TftpBlkSize to dflt */
678 	TftpBlkSize = TFTP_BLOCK_SIZE;
679 #ifdef CONFIG_MCAST_TFTP
680 	mcast_cleanup();
681 #endif
682 #ifdef CONFIG_TFTP_TSIZE
683 	TftpTsize = 0;
684 	TftpNumchars = 0;
685 #endif
686 
687 	TftpSend();
688 }
689 
690 #ifdef CONFIG_CMD_TFTPSRV
691 void
692 TftpStartServer(void)
693 {
694 	tftp_filename[0] = 0;
695 
696 	printf("Using %s device\n", eth_get_name());
697 	printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
698 	printf("Load address: 0x%lx\n", load_addr);
699 
700 	puts("Loading: *\b");
701 
702 	TftpTimeoutCountMax = TIMEOUT_COUNT;
703 	TftpTimeoutCount = 0;
704 	TftpTimeoutMSecs = TIMEOUT;
705 	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
706 
707 	/* Revert TftpBlkSize to dflt */
708 	TftpBlkSize = TFTP_BLOCK_SIZE;
709 	TftpBlock = 0;
710 	TftpOurPort = WELL_KNOWN_PORT;
711 
712 #ifdef CONFIG_TFTP_TSIZE
713 	TftpTsize = 0;
714 	TftpNumchars = 0;
715 #endif
716 
717 	TftpState = STATE_RECV_WRQ;
718 	NetSetHandler(TftpHandler);
719 }
720 #endif /* CONFIG_CMD_TFTPSRV */
721 
722 #ifdef CONFIG_MCAST_TFTP
723 /* Credits: atftp project.
724  */
725 
726 /* pick up BcastAddr, Port, and whether I am [now] the master-client. *
727  * Frame:
728  *    +-------+-----------+---+-------~~-------+---+
729  *    |  opc  | multicast | 0 | addr, port, mc | 0 |
730  *    +-------+-----------+---+-------~~-------+---+
731  * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
732  * I am the new master-client so must send ACKs to DataBlocks.  If I am not
733  * master-client, I'm a passive client, gathering what DataBlocks I may and
734  * making note of which ones I got in my bitmask.
735  * In theory, I never go from master->passive..
736  * .. this comes in with pkt already pointing just past opc
737  */
738 static void parse_multicast_oack(char *pkt, int len)
739 {
740 	int i;
741 	IPaddr_t addr;
742 	char *mc_adr, *port,  *mc;
743 
744 	mc_adr = port = mc = NULL;
745 	/* march along looking for 'multicast\0', which has to start at least
746 	 * 14 bytes back from the end.
747 	 */
748 	for (i = 0; i < len-14; i++)
749 		if (strcmp(pkt+i, "multicast") == 0)
750 			break;
751 	if (i >= (len-14)) /* non-Multicast OACK, ign. */
752 		return;
753 
754 	i += 10; /* strlen multicast */
755 	mc_adr = pkt+i;
756 	for (; i < len; i++) {
757 		if (*(pkt+i) == ',') {
758 			*(pkt+i) = '\0';
759 			if (port) {
760 				mc = pkt+i+1;
761 				break;
762 			} else {
763 				port = pkt+i+1;
764 			}
765 		}
766 	}
767 	if (!port || !mc_adr || !mc)
768 		return;
769 	if (Multicast && MasterClient) {
770 		printf("I got a OACK as master Client, WRONG!\n");
771 		return;
772 	}
773 	/* ..I now accept packets destined for this MCAST addr, port */
774 	if (!Multicast) {
775 		if (Bitmap) {
776 			printf("Internal failure! no mcast.\n");
777 			free(Bitmap);
778 			Bitmap = NULL;
779 			ProhibitMcast = 1;
780 			return ;
781 		}
782 		/* I malloc instead of pre-declare; so that if the file ends
783 		 * up being too big for this bitmap I can retry
784 		 */
785 		Bitmap = malloc(Mapsize);
786 		if (!Bitmap) {
787 			printf("No Bitmap, no multicast. Sorry.\n");
788 			ProhibitMcast = 1;
789 			return;
790 		}
791 		memset(Bitmap, 0, Mapsize);
792 		PrevBitmapHole = 0;
793 		Multicast = 1;
794 	}
795 	addr = string_to_ip(mc_adr);
796 	if (Mcast_addr != addr) {
797 		if (Mcast_addr)
798 			eth_mcast_join(Mcast_addr, 0);
799 		Mcast_addr = addr;
800 		if (eth_mcast_join(Mcast_addr, 1)) {
801 			printf("Fail to set mcast, revert to TFTP\n");
802 			ProhibitMcast = 1;
803 			mcast_cleanup();
804 			NetStartAgain();
805 		}
806 	}
807 	MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10);
808 	Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
809 	printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient);
810 	return;
811 }
812 
813 #endif /* Multicast TFTP */
814