📄 tftp.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 + -