Ejemplo n.º 1
0
void
TftpStart (void)
{
	struct timestamp now;
	time_get(&now);

#ifdef ET_DEBUG
	printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n",
		NetServerEther[0],
		NetServerEther[1],
		NetServerEther[2],
		NetServerEther[3],
		NetServerEther[4],
		NetServerEther[5]
	);
#endif /* DEBUG */

	printf ("TFTP from server %s", inet_ntoa(NetServerIP));
	printf ("; our IP address is %s", inet_ntoa(NetOurIP));


	// Check if we need to send across this subnet
	if (NetOurGatewayIP && NetOurSubnetMask) {
	    IPaddr_t OurNet 	= NetOurIP    & NetOurSubnetMask;
	    IPaddr_t ServerNet 	= NetServerIP & NetOurSubnetMask;

	    if (OurNet != ServerNet) {
		printf ("; sending through gateway ");
		print_IPaddr (NetOurGatewayIP) ;
	    }
	}
	printf("\n");

	printf ("Filename '%s'.", tftp_filename);

	if (NetBootFileSize) {
	    printf (" Size is %d%s kB => %x Bytes", NetBootFileSize/2, (NetBootFileSize%2) ? ".5" : "",	NetBootFileSize<<9);
	}

	printf("\n");

	printf ("Load address: 0x%lx\n\n", get_board_desc()->memctrl_membase);
	printf ("Press Ctrl-C to abort...\n");
	printf ("Loading: *\b");


	NetSetTimeout (TIMEOUT * 1000, TftpTimeout);
	NetSetHandler (TftpHandler);

	TftpServerPort = WELL_KNOWN_PORT;
	TftpTimeoutCount = 0;
	TftpState = STATE_RRQ;
	TftpOurPort = 1024 + (now.usec % 3072); //FIXED

	TftpSend ();
}
Ejemplo n.º 2
0
static void TftpTimeout (void)
{
	if (++TftpTimeoutCount >= TIMEOUT_COUNT) {
		printf ("\nRetry count exceeded; starting again\n");
		NetStartAgain ();
	} else {
		printf ("T ");
		NetSetTimeout (TIMEOUT * 1000, TftpTimeout);
		TftpSend ();
	}
}
Ejemplo n.º 3
0
static void
TftpTimeout(void)
{
	if (++TftpTimeoutCount > TftpTimeoutCountMax) {
		restart("Retry count exceeded");
	} else {
		puts("T ");
		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
		if (TftpState != STATE_RECV_WRQ)
			TftpSend();
	}
}
Ejemplo n.º 4
0
static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){
	bd_t *bd = gd->bd;
	ushort proto;
	ushort *s;

	if(dest != TftpOurPort){
		return;
	}

	if(TftpState != STATE_RRQ && src != TftpServerPort){
		return;
	}

	if(len < 2){
		return;
	}

	len -= 2;

	/* warning: don't use increment (++) in ntohs() macros!! */
	s = (ushort *)pkt;
	proto = *s++;
	pkt = (uchar *)s;

	switch(ntohs(proto)){
		case TFTP_RRQ:
		case TFTP_WRQ:
		case TFTP_ACK:
			break;

		default:
			break;

		case TFTP_OACK:
	#ifdef ET_DEBUG
			printf("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1);
	#endif
			TftpState = STATE_OACK;
			TftpServerPort = src;
			TftpSend(); /* Send ACK */
			break;

		// TFTP DATA PACKET
		case TFTP_DATA:
			if(len < 2){
				return;
			}

			len -= 2;
			TftpBlock = ntohs(*(ushort *)pkt);

			/*
			 * RFC1350 specifies that the first data packet will
			 * have sequence number 1. If we receive a sequence
			 * number of 0 this means that there was a wrap
			 * around of the (16 bit) counter.
			 */
			if(TftpBlock == 0){
				TftpBlockWrap++;
				TftpBlockWrapOffset += TFTP_BLOCK_SIZE * TFTP_SEQUENCE_SIZE;
				printf("\n         %lu MB received\n         ", TftpBlockWrapOffset>>20);
			} else {
				if(((TftpBlock - 1) % 10) == 0){
Ejemplo n.º 5
0
static void
TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
	    unsigned len)
{
	__be16 proto;
	__be16 *s;
	int i;

	if (dest != TftpOurPort) {
#ifdef CONFIG_MCAST_TFTP
		if (Multicast
		 && (!Mcast_port || (dest != Mcast_port)))
#endif
			return;
	}
	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
	    TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ)
		return;

	if (len < 2)
		return;
	len -= 2;
	/* warning: don't use increment (++) in ntohs() macros!! */
	s = (__be16 *)pkt;
	proto = *s++;
	pkt = (uchar *)s;
	switch (ntohs(proto)) {

	case TFTP_RRQ:
		break;

	case TFTP_ACK:
#ifdef CONFIG_CMD_TFTPPUT
		if (TftpWriting) {
			if (TftpFinalBlock) {
				tftp_complete();
			} else {
				/*
				 * Move to the next block. We want our block
				 * count to wrap just like the other end!
				 */
				int block = ntohs(*s);
				int ack_ok = (TftpBlock == block);

				TftpBlock = (unsigned short)(block + 1);
				update_block_number();
				if (ack_ok)
					TftpSend(); /* Send next data block */
			}
		}
#endif
		break;

	default:
		break;

#ifdef CONFIG_CMD_TFTPSRV
	case TFTP_WRQ:
		debug("Got WRQ\n");
		TftpRemoteIP = sip;
		TftpRemotePort = src;
		TftpOurPort = 1024 + (get_timer(0) % 3072);
		new_transfer();
		TftpSend(); /* Send ACK(0) */
		break;
#endif

	case TFTP_OACK:
		debug("Got OACK: %s %s\n",
			pkt,
			pkt + strlen((char *)pkt) + 1);
		TftpState = STATE_OACK;
		TftpRemotePort = src;
		/*
		 * Check for 'blksize' option.
		 * Careful: "i" is signed, "len" is unsigned, thus
		 * something like "len-8" may give a *huge* number
		 */
		for (i = 0; i+8 < len; i++) {
			if (strcmp((char *)pkt+i, "blksize") == 0) {
				TftpBlkSize = (unsigned short)
					simple_strtoul((char *)pkt+i+8, NULL,
						       10);
				debug("Blocksize ack: %s, %d\n",
					(char *)pkt+i+8, TftpBlkSize);
			}
#ifdef CONFIG_TFTP_TSIZE
			if (strcmp((char *)pkt+i, "tsize") == 0) {
				TftpTsize = simple_strtoul((char *)pkt+i+6,
							   NULL, 10);
				debug("size = %s, %d\n",
					 (char *)pkt+i+6, TftpTsize);
			}
#endif
		}
#ifdef CONFIG_MCAST_TFTP
		parse_multicast_oack((char *)pkt, len-1);
		if ((Multicast) && (!MasterClient))
			TftpState = STATE_DATA;	/* passive.. */
		else
#endif
#ifdef CONFIG_CMD_TFTPPUT
		if (TftpWriting) {
			/* Get ready to send the first block */
			TftpState = STATE_DATA;
			TftpBlock++;
		}
#endif
		TftpSend(); /* Send ACK or first data block */
		break;
	case TFTP_DATA:
		if (len < 2)
			return;
		len -= 2;
		TftpBlock = ntohs(*(__be16 *)pkt);

		update_block_number();

		if (TftpState == STATE_SEND_RRQ)
			debug("Server did not acknowledge timeout option!\n");

		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK ||
		    TftpState == STATE_RECV_WRQ) {
			/* first block received */
			TftpState = STATE_DATA;
			TftpRemotePort = src;
			new_transfer();

#ifdef CONFIG_MCAST_TFTP
			if (Multicast) { /* start!=1 common if mcast */
				TftpLastBlock = TftpBlock - 1;
			} else
#endif
			if (TftpBlock != 1) {	/* Assertion */
				printf("\nTFTP error: "
				       "First block is not block 1 (%ld)\n"
				       "Starting again\n\n",
					TftpBlock);
				NetStartAgain();
				break;
			}
		}

		if (TftpBlock == TftpLastBlock) {
			/*
			 *	Same block again; ignore it.
			 */
			break;
		}

		TftpLastBlock = TftpBlock;
		TftpTimeoutCountMax = TIMEOUT_COUNT;
		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);

		store_block(TftpBlock - 1, pkt + 2, len);

		/*
		 *	Acknowledge the block just received, which will prompt
		 *	the remote for the next one.
		 */
#ifdef CONFIG_MCAST_TFTP
		/* if I am the MasterClient, actively calculate what my next
		 * needed block is; else I'm passive; not ACKING
		 */
		if (Multicast) {
			if (len < TftpBlkSize)  {
				TftpEndingBlock = TftpBlock;
			} else if (MasterClient) {
				TftpBlock = PrevBitmapHole =
					ext2_find_next_zero_bit(
						Bitmap,
						(Mapsize*8),
						PrevBitmapHole);
				if (TftpBlock > ((Mapsize*8) - 1)) {
					printf("tftpfile too big\n");
					/* try to double it and retry */
					Mapsize <<= 1;
					mcast_cleanup();
					NetStartAgain();
					return;
				}
				TftpLastBlock = TftpBlock;
			}
		}
#endif
		TftpSend();

#ifdef CONFIG_MCAST_TFTP
		if (Multicast) {
			if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
				puts("\nMulticast tftp done\n");
				mcast_cleanup();
				net_set_state(NETLOOP_SUCCESS);
			}
		} else
#endif
		if (len < TftpBlkSize)
			tftp_complete();
		break;

	case TFTP_ERROR:
		printf("\nTFTP error: '%s' (%d)\n",
		       pkt + 2, ntohs(*(__be16 *)pkt));

		switch (ntohs(*(__be16 *)pkt)) {
		case TFTP_ERR_FILE_NOT_FOUND:
		case TFTP_ERR_ACCESS_DENIED:
			puts("Not retrying...\n");
			eth_halt();
			net_set_state(NETLOOP_FAIL);
			break;
		case TFTP_ERR_UNDEFINED:
		case TFTP_ERR_DISK_FULL:
		case TFTP_ERR_UNEXPECTED_OPCODE:
		case TFTP_ERR_UNKNOWN_TRANSFER_ID:
		case TFTP_ERR_FILE_ALREADY_EXISTS:
		default:
			puts("Starting again\n\n");
#ifdef CONFIG_MCAST_TFTP
			mcast_cleanup();
#endif
			NetStartAgain();
			break;
		}
		break;
	}
}
Ejemplo n.º 6
0
static void
TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
	ushort proto;
	ushort *s;
	int i;

	if (dest != TftpOurPort) {
#ifdef CONFIG_MCAST_TFTP
		if (Multicast
		 && (!Mcast_port || (dest != Mcast_port)))
#endif
		return;
	}
	if (TftpState != STATE_RRQ && src != TftpServerPort) {
		return;
	}

	if (len < 2) {
		return;
	}
	len -= 2;
	/* warning: don't use increment (++) in ntohs() macros!! */
	s = (ushort *)pkt;
	proto = *s++;
	pkt = (uchar *)s;
	switch (ntohs(proto)) {

	case TFTP_RRQ:
	case TFTP_WRQ:
	case TFTP_ACK:
		break;
	default:
		break;

	case TFTP_OACK:
		debug("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1);
		TftpState = STATE_OACK;
		TftpServerPort = src;
		/*
		 * Check for 'blksize' option.
		 * Careful: "i" is signed, "len" is unsigned, thus
		 * something like "len-8" may give a *huge* number
		 */
		for (i=0; i+8<len; i++) {
			if (strcmp ((char*)pkt+i,"blksize") == 0) {
				TftpBlkSize = (unsigned short)
					simple_strtoul((char*)pkt+i+8,NULL,10);
				debug ("Blocksize ack: %s, %d\n",
					(char*)pkt+i+8,TftpBlkSize);
				break;
			}
		}
#ifdef CONFIG_MCAST_TFTP
		parse_multicast_oack((char *)pkt,len-1);
		if ((Multicast) && (!MasterClient))
			TftpState = STATE_DATA;	/* passive.. */
		else
#endif
		TftpSend (); /* Send ACK */
		break;
	case TFTP_DATA:
		if (len < 2)
			return;
		len -= 2;
		TftpBlock = ntohs(*(ushort *)pkt);

		/*
		 * RFC1350 specifies that the first data packet will
		 * have sequence number 1. If we receive a sequence
		 * number of 0 this means that there was a wrap
		 * around of the (16 bit) counter.
		 */
		if (TftpBlock == 0) {
			TftpBlockWrap++;
			TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
			printf("\n\t %lu MB received\n\t ", TftpBlockWrapOffset>>20);
		} else {
			if (((TftpBlock - 1) % 10) == 0) {
Ejemplo n.º 7
0
static void
TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
	    unsigned len)
{
	ushort proto;
	ushort *s;
	int i;

	if (dest != TftpOurPort) {
#ifdef CONFIG_MCAST_TFTP
		if (Multicast
		 && (!Mcast_port || (dest != Mcast_port)))
#endif
			return;
	}
	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
	    TftpState != STATE_RECV_WRQ)
		return;

	if (len < 2)
		return;
	len -= 2;
	/* warning: don't use increment (++) in ntohs() macros!! */
	s = (ushort *)pkt;
	proto = *s++;
	pkt = (uchar *)s;
	switch (ntohs(proto)) {

	case TFTP_RRQ:
	case TFTP_ACK:
		break;
	default:
		break;

#ifdef CONFIG_CMD_TFTPSRV
	case TFTP_WRQ:
		debug("Got WRQ\n");
		TftpRemoteIP = sip;
		TftpRemotePort = src;
		TftpOurPort = 1024 + (get_timer(0) % 3072);
		TftpLastBlock = 0;
		TftpBlockWrap = 0;
		TftpBlockWrapOffset = 0;
		TftpSend(); /* Send ACK(0) */
		break;
#endif

	case TFTP_OACK:
		debug("Got OACK: %s %s\n",
			pkt,
			pkt + strlen((char *)pkt) + 1);
		TftpState = STATE_OACK;
		TftpRemotePort = src;
		/*
		 * Check for 'blksize' option.
		 * Careful: "i" is signed, "len" is unsigned, thus
		 * something like "len-8" may give a *huge* number
		 */
		for (i = 0; i+8 < len; i++) {
			if (strcmp((char *)pkt+i, "blksize") == 0) {
				TftpBlkSize = (unsigned short)
					simple_strtoul((char *)pkt+i+8, NULL,
						       10);
				debug("Blocksize ack: %s, %d\n",
					(char *)pkt+i+8, TftpBlkSize);
			}
#ifdef CONFIG_TFTP_TSIZE
			if (strcmp((char *)pkt+i, "tsize") == 0) {
				TftpTsize = simple_strtoul((char *)pkt+i+6,
							   NULL, 10);
				debug("size = %s, %d\n",
					 (char *)pkt+i+6, TftpTsize);
			}
#else
    #ifdef CONFIG_MSTAR_PM_SWIR
            if(strcmp((char *)pkt+i, "tsize") == 0)
            {
                TftpImageSize = simple_strtoul((char *)pkt+i+6,
							   NULL, 10);
                //if image size is bigger than limited image size, it'll overwrite Uboot and make Uboot crash.
                //then you need split load image, load image more than one time.
        #if CONFIG_LZO
                if(TftpImageSize > ((CONFIG_UNLZO_DST_ADDR - load_addr) - gd->mon_len))
                {
                    printf("warning: image size is (0x%lx), which is bigger than (0x%lx),pls consider to split the image.\n",
                        (long unsigned int)TftpImageSize,((CONFIG_UNLZO_DST_ADDR - load_addr) - gd->mon_len));
                }
        #else
                if(TftpImageSize > ((gd->ram_size - gd->mon_len)- load_addr))
                {
                    printf("warning: image size is (0x%lx), which is bigger than (0x%lx),pls consider to split the image.\n",
                        (long unsigned int)TftpImageSize,((gd->ram_size - gd->mon_len)- load_addr));
                }
        #endif
            }
     #endif
#endif
		}
#ifdef CONFIG_MCAST_TFTP
		parse_multicast_oack((char *)pkt, len-1);
		if ((Multicast) && (!MasterClient))
			TftpState = STATE_DATA;	/* passive.. */
		else
#endif
		TftpSend(); /* Send ACK */
		break;
	case TFTP_DATA:
		if (len < 2)
			return;
		len -= 2;
		TftpBlock = ntohs(*(ushort *)pkt);

		/*
		 * RFC1350 specifies that the first data packet will
		 * have sequence number 1. If we receive a sequence
		 * number of 0 this means that there was a wrap
		 * around of the (16 bit) counter.
		 */
		if (TftpBlock == 0) {
			TftpBlockWrap++;
			TftpBlockWrapOffset +=
				TftpBlkSize * TFTP_SEQUENCE_SIZE;
			printf("\n\t %lu MB received\n\t ",
				TftpBlockWrapOffset>>20);
		}
#ifdef CONFIG_TFTP_TSIZE
		else if (TftpTsize) {
Ejemplo n.º 8
0
static void TftpHandler (unsigned char * pkt, unsigned dest, unsigned src, unsigned len) {


	if (dest != TftpOurPort) {
		return;
	}
	if (TftpState != STATE_RRQ && src != TftpServerPort) {
		return;
	}

	if (len < 2) {
		return;
	}
	len -= 2;

	unsigned short val = *((unsigned short *) pkt);
	pkt += sizeof(unsigned short);

	switch (val) {

	case TFTP_RRQ:
	case TFTP_WRQ:
	case TFTP_ACK:
		break;
	default:
		break;

	case TFTP_DATA:
		if (len < 2)
			return;
		len -= 2;
		TftpBlock = *(unsigned short *)pkt;
		if (((TftpBlock - 1) % 10) == 0) {
			printf("#");
			TftpTimeoutCount = 0;
		} else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) {
			printf ("\n\t ");
		}

		if (TftpState == STATE_RRQ) {
			TftpState = STATE_DATA;
			TftpServerPort = src;
			TftpLastBlock = 0;

			if (TftpBlock != 1) {	/* Assertion */
				printf ("\nTFTP error: "
					"First block is not block 1 (%d)\n"
					"Starting again\n\n",
					TftpBlock);
				NetStartAgain ();
				break;
			}
		}

		if (TftpBlock == TftpLastBlock) {
			/*
			 *	Same block again; ignore it.
			 */
			break;
		}

		TftpLastBlock = TftpBlock;
		NetSetTimeout (TIMEOUT * 1000, TftpTimeout);

		store_block (TftpBlock - 1, pkt + 2, len);

		/*
		 *	Acknoledge the block just received, which will prompt
		 *	the server for the next one.
		 */
		TftpSend ();

		if (len < 512) {
			/*
			 *	We received the whole thing.  Try to
			 *	run it.
			 */
			printf ("\ndone\n");
			NetState = NETLOOP_SUCCESS;
		}
		break;

	case TFTP_ERROR:
		printf ("\nTFTP error: '%s' (%d)\n", pkt + 2, *(unsigned short *)pkt);
		printf ("Starting again\n\n");
		NetStartAgain ();
		break;
	}
}