TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。
2009.08版本的 支持tftp的下载功能,但不支持上传功能,如果要想支持上传功能 可参考以下的这一个网友的博文:
http://blog.chinaunix.net/uid-20737871-id-2124122.html
1、涉及的文件与函数
cmd_net.c —>
static int netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
net.c —>
int NetLoop(proto_t protocol)
tftp.c —>
void TftpStart (void)
发送:
static void TftpSend (void)
接收:
static void TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
底层的收发在: fec_mxc.h(imx6q)
2、 tftp 协议解析
协议文档
https://tools.ietf.org/html/rfc1350
https://tools.ietf.org/html/rfc2347
注意:tftp是基于UDP的,而UDP又是基于IP的
所以tftp的头格式为:
---------------------------------------------------
| Local Medium | Internet | Datagram | TFTP |
---------------------------------------------------
通信流程
操作码
opcode operation
1 Read request (RRQ)
2 Write request (WRQ)
3 Data (DATA)
4 Acknowledgment (ACK)
5 Error (ERROR)
基本操作码
扩展操作码
关于OACK 可以参考:
此为后来新加的
https://tools.ietf.org/html/rfc2347
通信流程例子:
关于TID
在TFTP中,一次请求中所有包的源和目标都由Transfer ID(TID)来标示。TFTP规定TID值就是UDP包中的源和目标端口。也就是说,一次请求过程中,S和C通过UDP包的源和目标端口来判断这个包是不是发给自己的。
以WRQ为例,C向S的69端口发送一个文件请求包,这个文件请求包中UDP的源端口号为C的TID(假设C选择4845作为它的TID),目标端口为69(这个时候由于请求还未接受,所以这次请求的UDP包中目标端口不是TID)。S收到这个请求后,将另外采用一个UDP端口(应该另启动了一个UDP Socket)假设为4849来回复这个请求的ACK。这样,这个回复的UDP包的源端口就是S的TID(=4849),目标就是C的UDP端口(TID=4845)。以后,这次请求的后续所有包都在端口为4845和4849中来往。
上述过程隐含了一定程度上的容错处理。例如,C收到一个TID不是4849的包,则认为这个包是错误的。另外,S对于每个请求,都要采用一个不重复的新的UDP端口号作为它的TID,也就是说,S上同时存在的n个请求的TID都将不同。
/* Use a pseudo-random port unless a specific port is set */
TftpOurPort = 1024 + (get_timer(0) % 3072);
关于tftp几个规定
1、服务器端口为 69
2、默认情况下帧长 512个字节
3、在带OACK的情况下 帧长可以达到1468个字节,最多传65535个包,所以最大能传91MB的数据
4、大端