【问题标题】:Malformed DNS Request Packet格式错误的 DNS 请求数据包
【发布时间】:2015-08-19 08:27:34
【问题描述】:

我一直在从事一个项目,该项目涉及在问题(其中 2 个)中发送带有信息(不是实际域)的 DNS 请求。我一直在用wireshark 跟踪数据包。

这是创建的数据包的tcp 转储。

00000000 00 02 01 00 00 02 00 00 00 00 00 00 01 32 03 65

00000010 6e 64 03 63 6f 6d 00 00 01 00 01 01 32 04 73 61

00000020 76 65 03 63 6f 6d 00 00 01 00 01

........ .....2.e

nd.com.. ....2.sa

ve.com.. ...

i.d.qdcount 应该是 2,需要递归,并且显示的域是正确的。 Wireshark 表示它是格式错误的 DNS 数据包。知道数据包有什么问题吗?

【问题讨论】:

  • 这是通过 UDP 还是 TCP 发送的?如果它是通过 TCP 发送的,你需要在数据包前面加上一个 2 字节的长度字段,给出 DNS 数据包的长度;请参阅RFC 1035 中的第 4.2.2 节“TCP 使用”。
  • 它应该通过UDP发送;但是,对于 UDP 和 TCP 之间的区别,我仍然很模糊。据我了解,当 DNS 数据包太大(>512 字节)时使用 TCP。
  • 成功了,谢谢!

标签: tcp dns wireshark


【解决方案1】:

好的,所以:

  • 如果您自己进行传输层网络,您的代码将通过在创建用于发送数据包的套接字时指定是 UDP 还是 TCP 套接字来确定它是通过 UDP 还是 TCP;
  • 如果数据包不适合最大大小的 UDP 数据包,则使用 TCP;
  • 如果您通过 TCP 发送它,您需要在它前面加上一个标头,根据 RFC 1035 中的第 4.2.2 节“TCP 使用”。

“最大尺寸”有点模糊。 RFC 791,IPv4 规范,在第 3.1 节“Internet Header Format”中说:

Total Length:  16 bits

  Total Length is the length of the datagram, measured in octets,
  including internet header and data.  This field allows the length of
  a datagram to be up to 65,535 octets.  Such long datagrams are
  impractical for most hosts and networks.  All hosts must be prepared
  to accept datagrams of up to 576 octets (whether they arrive whole
  or in fragments).  It is recommended that hosts only send datagrams
  larger than 576 octets if they have assurance that the destination
  is prepared to accept the larger datagrams.

  The number 576 is selected to allow a reasonable sized data block to
  be transmitted in addition to the required header information.  For
  example, this size allows a data block of 512 octets plus 64 header
  octets to fit in a datagram.  The maximal internet header is 60
  octets, and a typical internet header is 20 octets, allowing a
  margin for headers of higher level protocols.

然而,这些天来,将最大数据包大小限制低至 576 字节的旧网络硬件即使没有完全消失,也基本上已经消失,而现实世界的“最大数据包大小”通常是以太网数据包大小 -总长度为 1518 字节,包含 14 字节的以太网头和 4 字节的 FCS,剩下 1500 字节的有效载荷。对于 UDP,典型的 IPv4 报头长度为 20 字节,UDP 报头长度为 8 字节,即 1472 字节的数据,因此对于大于 1472 字节的 DNS 消息(IP 分段和重组)使用 TCP 而不是 UDP 可能就足够了如果网络路由中的任何一跳无法处理 1500 字节的 IPv4 数据包,则会发生这种情况;这确实会增加数据包无法通过的机会,因为如果一个片段通过但另一个片段没有通过,则整个数据包不会通过'不通过)。

【讨论】:

  • 我正在使用 python 并且正在使用 python 套接字库发送 dns 请求。我想通过UDP发送它。我会在什么函数/哪些参数中执行此操作?
  • 是 SOCK_DGRAM 而不是 SOCK_STREAM?
  • AF_INET/AF_INET6 + SOCK_DGRAM 是UDP的socket类型; AF_INET/AF_INET6 + SOCK_STREAM 是 TCP 的套接字类型。
  • IPv6 标头的最小长度为 80 字节,因此 UDP 有效负载的 (1500-(80+8)) 字节 = 在 IPv6+ 之上运行的 DNS(或其他)协议的 1412 字节UDP 在以太网上运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多