TFTP协议解析及C/C++代码实现

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”

  • 数据包格式
    数据实际上以数据包的形式传输。

    数据包(操作码 = 3)具有块号和数据字段。 块数据包上的数字从 1 开始,每增加一个新的数据块。 此限制允许程序使用单个区分新数据包和重复数据包的编号。 数据字段长度为 0 到 512 个字节。 如果它是 512 字节长,则block 不是最后一个数据块; 如果它是从零到 511 字节长,它表示传输结束。

传输数据块的DATA数据包,它头2字节也是操作码,取值3用于表示数据包用于数据块传输,接下来的2字节用于表示数据块编号,最后是可变长字段Data,用于装载数据块。

  • ACK包

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)

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TFTP是一种简单的文件传输协议,它使用UDP协议进行数据传输。在实现TFTP协议层的c语言代码时,需要先了解TFTP的数据传输流程和协议规范。 TFTP的数据传输流程分为读模式和写模式。读模式是指客户端请求服务器从指定的文件中读取数据,写模式是指客户端向服务器写入数据到指定的文件中。在读模式下,客户端发送RRQ(读请求)报文给服务器服务器则发送DATA(数据)报文和ACK(确认)报文给客户端。在写模式下,客户端发送WRQ(写请求)报文给服务器服务器则发送ACK报文和DATA报文给客户端。 为实现TFTP协议层的c语言代码,我们需要了解TFTP的报文结构和协议规范。TFTP报文分为五种类型:RRQ、WRQ、DATA、ACK和ERROR。报文的数据格式如下: RRQ/WRQ报文格式: 2字节操作码(RRQ/WRQ) N字节文件名 1字节零 N字节传输模式(octet) DATA报文格式: 2字节操作码(DATA) 2字节块号 N字节数据 ACK报文格式: 2字节操作码(ACK) 2字节块号 ERROR报文格式: 2字节操作码(ERROR) 2字节错误码 N字节错误信息 1字节零 在实现TFTP协议层的c语言代码时,我们需要按照协议规范构造TFTP报文,并使用UDP协议进行报文的发送和接收。具体实现的步骤如下: 1. 创建socket对象,使用UDP协议进行数据传输。 2. 根据读模式或写模式构造RRQ/WRQ报文,并发送到服务器。 3. 接收服务器发回的DATA/ACK报文,并解析出数据块编号和数据内容。 4. 根据DATA/ACK报文的数据块编号,构造ACK/DATA报文,并发送回服务器。 5. 如果收到了ERROR报文,则需要解析出错误码和错误信息,并进行相应的处理。 通过以上步骤,我们可以实现TFTP协议层的c语言代码,从而实现文件的传输和下载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值