可能是这个问题有点愚蠢,但我会问它。我读了很多关于网络中原始套接字的内容,看过几个例子。因此,基本上使用原始套接字可以构建自己的头堆栈,例如堆栈 = IP + TCP/UDP + OWN_HEADER。我的问题是,是否有可能从 linux 内核中获取前两个(IP + TCP/UDP)的某种就绪帧,然后将自己的标头附加到它们?有问题的操作系统是linux,语言是C。
我找不到任何可以做这种事情的功能,但可能是我在挖掘错误的方向。
我将依赖现有的协议(即,UDP 为尽力而为,TCP 为可靠)并将我自己的标头封装在其中。实际上,这意味着在标准 UDP/TCP 连接上嵌入您自己的协议。这样,您可以使用现有的内核和用户级工具。
如果您想反其道而行之(即,UDP/TCP 封装在您自己的标头中),您必须在 linux 内核中设计/实现您自己的协议,这非常复杂。
不,这对于原始套接字是不可能的。
您要么坐在 TCP/UDP 之上,在这种情况下,IP 堆栈负责标头和协议的操作(例如,在 TCP 的情况下,如何将数据分割成段),
因此,如果您想在 TCP 或 UDP 之上添加内容,这就是普通 TCP 或 UDP 套接字的用途。
或者你坐在 IP 之上,在这种情况下,你有责任在 IP 之上制作你想要的任何东西——这就是原始套接字的用途。虽然在这种情况下,您也可以构建 IP 标头,或者选择让 IP 堆栈也生成 IP 标头。
我认为您不了解 RAW 套接字的用途。使用 RAW 套接字(s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)),您必须自己构建物理层之上的所有内容。
这意味着您构建 IP 标头(当然,如果您想在 IP 之上构建协议),您可以在这里使用 AF_PACKET 做自己的事情。如果你想要 TCP,你自己构建 TCP 标头,并将其添加到 IP 标头中。在大多数情况下,当您使用 RAW 套接字时,您会开始构建自己的协议来代替 TCP 或 UDP,否则为什么要首先使用 RAW 套接字?例如,如果您想构建自己的 ICMP 或 SCTP 实现,您将使用 RAW Sockets。
如果您真的想了解这是如何工作的,我建议您构建自己的“ping”版本(换句话说,ICMP 回显请求实现)。它易于操作且易于测试,并且会迫使您弄脏手。
如果您问我,手册页很好地涵盖了整个主题。从插座开始。