TFTP 服务简单分析--uboot2009.08

来源:互联网 发布:淘宝运营团队靠谱吗 编辑:程序博客网 时间:2024/06/14 12:56

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/rfc1350https://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、大端