⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_ipv4_tftp.c

📁 bootloader源代码
💻 C
字号:
/***************************************** Copyright (c) 2001-2002  Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the boot loader *//* * net_ipv4_tftp.c * * TFTP client  * Based on RFC 1350 "The TFTP Protocol (Revision 2)" * Based on RFC 1782 "TFTP Option Extension" * * Written by Ho Lee 2002/11/20 */#include "util.h"#include "vsprintf.h"#include "uart.h"#include "timer.h"#include "net.h"#include "net_ipv4.h"/* 	TFTP file transfer example (from RFC 1782)    Read Request      client                                           server      -------------------------------------------------------      |1|foofile|0|octet|0|blksize|0|1432|0|  -->               RRQ                                    <--  |6|blksize|0|1432|0|   OACK      |4|0|  -->                                                ACK                             <--  |3|1| 1432 octets of data |   DATA      |4|1|  -->                                                ACK                             <--  |3|2| 1432 octets of data |   DATA      |4|2|  -->                                                ACK                             <--  |3|3|<1432 octets of data |   DATA      |4|3|  -->                                                ACK*/int tftp_parsepacket(struct sk_buff *skb){	skb->tftp = (struct tftphdr *) ((char *) skb->udp + sizeof(struct udphdr));	skb->tftp->opcode = ntohs(skb->tftp->opcode);	switch (skb->tftp->opcode) {	case TFTPOP_DATA :		skb->tftp->u.data.block = ntohs(skb->tftp->u.data.block);		break;	case TFTPOP_ACK :		skb->tftp->u.ack.block = ntohs(skb->tftp->u.ack.block);		break;	case TFTPOP_ERROR :		skb->tftp->u.err.errcode = ntohs(skb->tftp->u.err.errcode);		break;	}	return 0;}void tftp_dump_packet(struct sk_buff *skb, int need_parsing){	PrintFormat("TFTP : \n");}int ipv4_tftp(in_addr_t ipaddr, char *filename, unsigned int addr, unsigned int *datalen){	tftpip_t packet;	int len, nretry;	int nloop = 0, nloop2 = 0;	struct sk_buff *skb = NULL;	unsigned char *dataptr;	unsigned int iport = ipv4_alloc_port();   	dataptr	= (unsigned char *) addr;	*datalen = 0;	// send RRQ	packet.tftp.opcode = htons(TFTPOP_RRQ);	len = sizeof packet.tftp.opcode;	len += sprintf((char *) packet.tftp.u.rrq, "%s%coctet%cblksize%c%d", 		filename, 0, 0, 0, TFTP_MAX_PACKET);	len += 1;	for (nretry = 1; nretry <= MAX_TFTP_RETRIES; ++nretry) {		PrintUart("Connecting...\r\n", -1);		udp_transmit(ipaddr, iport, IPPORT_TFTP, len, &packet);		if ((skb = udp_receive(ipaddr, 0, iport, TIMEOUT)) != NULL)			break;		if (nretry == MAX_TFTP_RETRIES) {			PrintUart("Timeout. Connection failed.\r\n", -1);			return TFTPRET_NETWORKERR;		} else {			PrintUart("Timeout. Retrying...\r\n", -1);		}	}	while (skb) {		tftp_parsepacket(skb);		switch (skb->tftp->opcode) {		case TFTPOP_RRQ : 		case TFTPOP_WRQ : 		case TFTPOP_ACK :			// invalid op code for client			// just ignore them			break;		case TFTPOP_DATA :			// print progress			if ((nloop++ & 0x3f) == 0) {				if ((nloop2++ & 0x3f) == 0) {					if (nloop2 == 1)						PrintUart("Receiving : ", -1);					else						PrintUart("\r\n            ", -1);				}				PrintChar('.');			}						// Append to data buffer			len = skb->udpdata_len - 4;			PrintFormat("Received len=%d bytes\n", len);			memcpy(dataptr, skb->tftp->u.data.data, len);			dataptr += len;			*datalen += len;			// reply ACK			packet.tftp.opcode = htons(TFTPOP_ACK);			packet.tftp.u.ack.block = htons(skb->tftp->u.data.block);			udp_transmit(ipaddr, iport, skb->udp->src, 4, &packet);			if (len < TFTP_MAX_PACKET) {				PrintUart("\r\n", -1);				PrintFormat("Received Total=%d (0x%x) bytes\n", *datalen, *datalen);				return 0;			}			break;		case TFTPOP_ERROR :			switch (skb->tftp->u.err.errcode) {			case TFTPERR_FILENOTFOUND :				PrintUart("File not found\r\n", -1);				return TFTPRET_FILENOTFOUND;			case TFTPERR_ACCESSDENIED :				PrintUart("Access denied\r\n", -1);				return TFTPRET_ACCESSDENIED;			default :				PrintFormat("TFTP error %d : %s\n", 					skb->tftp->u.err.errcode, skb->tftp->u.err.errmsg);				return TFTPRET_OTHER;			}			break;		case TFTPOP_OACK :			// reply with ACK			packet.tftp.opcode = htons(TFTPOP_ACK);			packet.tftp.u.ack.block = 0;			udp_transmit(ipaddr, iport, skb->udp->src, 4, &packet);			break;		}		skb_free(skb);		for (nretry = 1; nretry <= MAX_TFTP_RETRIES; ++nretry) {			if ((skb = udp_receive(ipaddr, 0, iport, TIMEOUT)) != NULL)				break;			if (nretry == MAX_TFTP_RETRIES) {				PrintUart("Timeout. Transfer failed.\r\n", -1);				return TFTPRET_NETWORKERR;			}		}	}		return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -