在 C 中使用 bsd/socket api 继续发送格式错误的 TCP header

Keep sending malformed TCP header using bsd/socket api in C

长话短说我目前正在试验 BSD/Socket C API.

我想尝试模拟完整的 TCP 握手。 我要做的第一件事是将第一个 SYN 数据包 发送到主机,在我的例子中是 路由器 (192.168.1.1)

这是生成 SYN 数据包 的代码的 片段

https://paste.ubuntu.com/23758682/

这是我从 wireshark 得到的,当我运行将这个程序设置为

sudo ./sendsyn -h 192.168.1.1 -p 80 -i enp5s0

http://prnt.sc/dsnmgq

代码在 linux x86 64 位上使用 GCC

编译
$ gcc --version
gcc (GCC) 6.2.1 20160830

我希望代码仅适用于 x86 平台,运行 仅适用于 Linux。我不太关心便携性。

此外,我在 gcc 中使用了这个标志。

gcc  -DDEBUG_MODE  -std=gnu11 -fno-strict-aliasing 
-Wall -Wextra -pedantic -Wshadow -Wpointer-arith 
-Wcast-align -Wmissing-prototypes -Wmissing-declarations 
-Winline -Wuninitialized -Wstrict-prototypes 
-Werror -Wno-variadic-macros

所以请注意,在编译时我关闭了 -fno-strict-aliasing 规则。

问题

为什么 tcp header 在 wireshark 中不显示为 tcp header?

之前我尝试将数据包作为结构发送,例如

typedef struct packet_t {
  struct iphdr iph;
  struct tcphdr tcph;
}__attribute__((packed)) packet_t;

现在在代码中,我首先创建一个 uint8_t 数据报,然后在我的 IP [=85] 中填写所有信息=]TCP Headermemcpy 进入数据报,然后通过网络发送它们。

为什么 ip header 标志没有设置为 0x4000(不要分段)?

任何人都可以在片段中提供我的问题的解决方案以及一些好的解释吗?

我找到了解决问题的方法。

iph.frag_off = 0x4000;

这一行应该是

iph.frag_off = htons(0x4000);

因为 0x4000 是 16 位宽,所有需要超过 8 位才能存储的值都应始终转换为网络字节顺序(大端)。

现在可以使用了,请参阅 wireshark tcp syn