【问题标题】:Set Don't Fragment flag using raw sockets for UDP使用 UDP 的原始套接字设置不分段标志
【发布时间】:2020-12-24 01:09:15
【问题描述】:

我正在编写一个 C++ 程序,允许我在发送 UDP 数据包之前使用原始套接字(MacOS 不支持设置此设置)设置 DF 标志(不分段位)。

我对网络编程比较陌生,我正在寻找可以做到这一点的资源/代码示例。

我在 SO 上进行了搜索,但所有答案大多使用 setsockopt(),在我的情况下我无法真正使用。他们中的大多数都指向使用原始套接字,但没有关于如何使用原始套接字来实现这一点的详细答案。

我对原始套接字有基本的了解。我正在寻找一个我找不到的实现。有人可以指导我查看代码示例/sn-p 或简要解释如何使用原始套接字来实现吗?

【问题讨论】:

  • 你告诉它你想要它发送的数据包,它就会发送它。您必须了解 IP 和 UDP 的工作原理才能了解如何完成第一部分。
  • 任何指向代码示例的链接都有助于理解@user253751
  • 如果数据包不被分片,那怎么办?如果它对于 MTU 来说太大,就放弃它?
  • @user4581301 大概 - 并发送回 ICMP“需要分段”消息。这就是路径 MTU 发现的工作原理。
  • 您需要什么样的“详细信息”? IP 标头中有一个flags 字段。第 1 位是“不要分段”。所以就做iphdr.flags |= 0x2;

标签: c++ c sockets


【解决方案1】:

创建原始套接字。

通过设置IP_HDRINCL 套接字选项启用对 IP 标头的访问:

int hdrincl=1;
if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&hdrincl,sizeof(hdrincl))==-1) {
    die("%s",strerror(errno));
}

标志位于struct ip 标头的ip_off 字段中,该字段在<netinet/ip.h> 中声明。 Don't Fragment 标志有一个宏 IP_DF

((struct ip*)&packet)->ip_off |= IP_DF;

填写 IP 和 UDP 标头以及 UDP 有效负载中的所有其余字段。

发送数据包。

【讨论】:

  • 我需要将原始套接字绑定到使用getaddrinfo()bind() 的地址吗?
  • 我不确定。阅读有关原始套接字的教程,了解如何使用它们。
  • 另外,如果我使用没有 iphdr 而有 struct ip 的“netinet/ip.h”怎么办。那么DF位的设置会怎样呢?
  • 我已经用struct ip的正确字段更新了答案。
  • 这是为 IPv4 和 IPv6 设置 DF 位的方法对吗?
猜你喜欢
  • 2011-05-10
  • 2017-10-28
  • 2010-11-01
  • 2016-08-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
相关资源
最近更新 更多