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

📄 tftp.c

📁 cf8020+cp2200(网络)的驱动实现
💻 C
字号:
#include "net.h"
#include "eth.h"
#include "ip.h"
#include "udp.h"
#include "tftp.h"
#include "utils.h"
#include "tftpput.h"

unsigned  long volatile client_ip;
unsigned short volatile client_port;
unsigned short volatile client_block = 0;

extern unsigned char TFTP_BUF[];
extern unsigned char UDP_BUF[];

int tftp_send_ack(char *buf, int block)
{
	tftphdr *tftp_ack;
	tftp_ack = (tftphdr *)(buf+42);

	tftp_ack->th_opcode = ACK;
	tftp_ack->th_block = block;

#ifdef __LITTLEENDIAN__
	tftp_ack->th_opcode = htons(tftp_ack->th_opcode);
	tftp_ack->th_block = htons(tftp_ack->th_block);
#endif

//	udp_send(skb, client_ip, TFTP, client_port);
	udp_send((char*)(buf), TFTP_PORT, sizeof(tftphdr));

	return 0;
}

int tftp_rcv_wrq(char *inbuf, int len)
{
	struct tftphdr *tftp_hdr;

//	client_ip = ip_get_source_ip(skb);
//	client_port = udp_get_source_port(skb);

//adjust by qg
	IP_HEADER  * ip;
    UDP_HEADER  * udp;
	ip = (IP_HEADER  *)(inbuf + 14);
	udp = (UDP_HEADER  *)(inbuf + 34);
#ifdef __LITTLEENDIAN__
	ip->source_ipaddr = ntohl(ip->source_ipaddr);
	udp->source_port =  ntohs(ip->source_port);
#endif
	client_ip = ip->source_ipaddr;
	client_port = udp->source_port;

	tftp_hdr = (tftphdr *)inbuf;
	tftp_send_ack((char*)tftp_hdr, 0);
	client_block = 1;

//	tftp_put_begin();//第一个包
//	event_tftpput = 1;
	udp_broadcast(UDP_BUF, 7001, 10);

	return 0;
}
//定时器中要进行event_tftpput复位工作,否则tcp连接会不正常;
int tftp_rcv_data(char* inbuf, int buflen)
{
	tftphdr *tftp_hdr;
	int len;

//adjust by qg
	IP_HEADER  * ip;
    UDP_HEADER  * udp;
	ip = (IP_HEADER  *)(inbuf + 14);
	udp = (UDP_HEADER  *)(inbuf + 34);
#ifdef __LITTLEENDIAN__
	ip->source_ipaddr = ntohl(ip->source_ipaddr);
	udp->source_port =  ntohs(ip->source_port);
#endif

	if (client_ip != ip->source_ipaddr)
		return -1;
	if (client_port != udp->source_port)
		return -1;

	tftp_hdr = (tftphdr *)(inbuf+42);
#ifdef __LITTLEENDIAN__
	tftp_hdr->th_block = ntohs(tftp_hdr->th_block);
#endif
	if (client_block == tftp_hdr->th_block) 
	{
		len = udp->length - sizeof( tftphdr)-8;

		//get put data in buf,do you want
		tftp_put((unsigned char *)tftp_hdr+sizeof(tftphdr), len);		

		tftp_hdr = (tftphdr *)(TFTP_BUF);

		tftp_send_ack((char*)tftp_hdr, client_block);
		client_block++;

		if (len < 512)		
			//tftp_put_end();		
			{//传输结束
			//	event_tftpput = 0;
			}

	} else if (client_block > tftp_hdr->th_block) {

		tftp_send_ack(tftp_hdr, tftp_hdr->th_block);

	} else {

		tftp_send_ack(tftp_hdr, client_block);
	}

	return 0;
}

int tftp_rcv_packet(char* buf, int len)
{
	tftphdr *tftp_hdr;
	
	tftp_hdr = (tftphdr *)(buf+42);

 #ifdef __LITTLEENDIAN__
	tftp_hdr->th_opcode = ntohs(tftp_hdr->th_opcode);
 #endif

	switch (tftp_hdr->th_opcode) {

	case RRQ:
		break;
	case WRQ:
		tftp_rcv_wrq(buf, len);
		break;
	case DATA:
		tftp_rcv_data(buf, len);
		break;
	case ACK:
		break;
	case ERROR:
		break;
	default:
		break;
	}

	return 0;
}

⌨️ 快捷键说明

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