TFTP 用于以非常简单的方式传输文件。与其他文件传输协议(如:FTP 或 HTTP)相比,TFTP 更简单,代码量也更小,因此更易于实现。
通常,TFTP 使用 UDP 作为其传输协议。众所周知的 TFTP 流量 UDP 端口是 69。
什么是 TFTP? (普通文件传输协议)
普通文件传输协议是一种在网络设备之间传输文件的技术,是更强大的文件传输协议的简化版本。 TFTP 是在 1970 年代为缺乏足够内存或磁盘空间以提供完整 FTP 支持的计算机开发的。
与 FTP 一样,TFTP 使用客户端和服务器软件在两个设备之间建立连接。 从 TFTP 客户端,可以将单个文件上传到服务器或从服务器下载。 服务器托管文件,客户端请求或发送文件。
TFTP 协议如何工作?
要启动传输过程,主要要求是服务器形成连接,以便它可以读取或写入要传输的文件。一旦建立连接,发送文件的过程就开始了。这些文件以 512 字节的固定长度块的小数据包传输。
这些数据包进一步分为块,每个包由一个块组成。
一旦发送了一个数据包,它需要在发送另一个数据包之前由确认包确认。
现在要完全传输并得到确认,数据包至少应为 512 字节。如果数据包的大小小于 512 字节,则导致数据包终止。反过来,这会导致传输过程超时,发送方必须重新传输数据包。
该过程中涉及的两台机器都被视为发送者和接收者。这是因为当一个发送数据并接收确认时,另一个发送确认并接受数据。
TFTP 存在的安全隐患
由于 TFTP 是为简单易用而设计的,因此通常用于保护数据的任何机制都没有在其协议中实现。
这导致了许多安全问题。因为所有 TFTP 数据包都是通过网络以明文形式发送的,没有数据加密。
任何在与 TFTP 会话相同的网段上捕获网络流量的人都可以轻松收集传输的数据并重新创建原始文件。
如果文件包含敏感数据,例如用户名和密码,那么任何捕获流量的人都可以轻松使用它。
TFTP 三种传输模式
目前支持三种传输方式:
1、 netascii
2、octet
3、mail
支持三种不同的传输模式:“netascii”,“octet"和"mail”,前两种符合FTP协议中的"ASCII"和"image(binary)"模式;第三种从来很少使用,当前已经废弃。
TFTP 协议格式
TFTP共定义了五种类型的包格式,格式的区分由包数据前两个字节的Opcode字段区分,分别是:
读文件请求包:Read request,简写为RRQ,对应Opcode字段值为1
写文件请求包:Write requst,简写为WRQ,对应Opcode字段值为2
文件数据包:Data,简写为DATA,对应Opcode字段值为3
回应包:Acknowledgement,简写为ACK,对应Opcode字段值为4
错误信息包:Error,简写为ERROR,对应Opcode字段值为5
Opcode字段区分:
#define RRQ 01 /* read request */
#define WRQ 02 /* write request */
#define DATA 03 /* data packet */
#define ACK 04 /* acknowledgement */
#define ERROR 05 /* error code */
1.操作码(2字节),它用来表示当前数据包的类型(取值1表示该数据包是个读请求,2表示该数据包是写请求);
2.可变长字段,它用来表示要读取或上传的文件名,它使用ASCII码并以0表示结尾;
3.Mode,也是可变长字段,用来表示传输文件的数据类型,如果传输的是字符串文件,那么它填写字符串”netascii”,如果传输的是二进制文件,那么它填写字符串”octet”,这些字符串都以0结尾。
RRQ 和 WRQ 数据包(分别为操作码 1 和 2)具有以下格式
文件名是netascii中的字节序列以零字节终止。 模式字段包含字符串“netascii”、“octet”或“mail”
传输数据块的DATA数据包,它头2字节也是操作码,取值3用于表示数据包用于数据块传输,接下来的2字节用于表示数据块编号,最后是可变长字段Data,用于装载数据块。
ACK 数据包由 DATA 或 ERROR 数据包确认。ACK包(Acknowledgement)用于确认数据包已收到,和接收到的数据包数据块号相同。ACK包的操作码为4。
当接收方收到一个数据包后,会向发送方发送一个ACK包;而发送方则会在收到一个ACK包后继续发送下一个包。若发送完未能收到ACK包,则会使用超时机制,重新发送刚才的数据包。
错误ERROR数据包,它开始的2字节表示操作码,取值5;接下来2字节表示错误码;最后的是可变长字段,它用字符串的形式描述具体错误。
TFTP协议解析及C/C++代码实现
static bool dissect_embeddedtftp_heur(u_char *tvb, packet_info *pinfo)
{
conversation_t *conversation;
unsigned short opcode;
if (tvb_captured_length(tvb) < MIN_HDR_LEN)
return FALSE;
opcode = tvb_get_ntohs(tvb, 0);
switch (opcode)
{
case TFTP_RRQ:
case TFTP_WRQ:
if (!is_valid_requerest_body(tvb))
return FALSE;
case TFTP_DATA:
case TFTP_ACK:
case TFTP_OACK:
case TFTP_INFO:
break;
case TFTP_ERROR:
switch (tvb_get_ntohs(tvb, 2)) {
case TFTP_ERR_NOT_DEF:
case TFTP_ERR_NOT_FOUND:
case TFTP_ERR_NOT_ALLOWED:
case TFTP_ERR_DISK_FULL:
case TFTP_ERR_BAD_OP:
case TFTP_ERR_BAD_ID:
case TFTP_ERR_EXISTS:
case TFTP_ERR_NO_USER:
case TFTP_ERR_OPT_FAIL:
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
dissect_tftp_message(tftp_info_for_conversation(conversation), tvb, pinfo);
return TRUE;
}
static void dissect_tftp_message(tftp_conv_info_t *tftp_info,
u_char *tvb, packet_info *pinfo,)
{
switch (opcode) {
case TFTP_RRQ:
...
break;
case TFTP_WRQ:
...
break;
case TFTP_INFO:
...
break;
case TFTP_DATA:
...
break;
case TFTP_ACK:
...
break;
case TFTP_ERROR:
...
break;
case TFTP_OACK:
...
break;
default:
...
break;
}
...
}
...
运行结果:
FTP 与 TFTP 协议
尽管这两种协议都用于将文件从一台计算机传输到另一台计算机,但它们之间仍然存在一些显着差异。 一些变化点如下:
1、FTP 使用 TCP(传输控制协议),而 TFTP 使用 UDP(用户数据报协议)。
2、FTP 协议适用于两个端口,即。 20 和 21,而 TFTP 协议在单个端口(69)上工作。
3、与 TFTP 协议相比,FTP 协议非常复杂。
4、FTP 协议提供了许多消息,而 TFTP 协议只有五个消息。
总结
TFTP 是一种非常有用的技术,用于服务器和客户端之间的文件通信。它可以轻松使用,因为它需要更少的编码,更少的内存使用,并且由于不需要身份验证和安全机制,因此可以轻松使用。
参考:RFC1350
欢迎关注微信公众号【程序猿编码】,需要 TFTP协议解析完整源码 的添加本人微信号(c17865354792)