原始套接字如何工作?

原始套接字如何工作?

最近,我使用套接字模块在 Python 中开发了一个数据包嗅探器。为了做到这一点,我创建了一个 raw 类型的套接字。然后我开始接收和解析数据包。

我的假设是,默认情况下,操作系统上有一个原始套接字,它接收数据包并将其交给其他模块来解析该数据包。当我创建原始套接字时,它将是操作系统中的第二个原始套接字。

我的问题是,数据包是否被广播到操作系统中所有可用的原始套接字?因为在使用我的数据包嗅探器时,我可以看到与其他应用程序(例如浏览器)相关的数据包。这意味着这些数据包至少要经过两个套接字。其中一个是我的数据包嗅探器,另一个是真正的应用程序。对吗?

答案1

RAW 套接字与接口绑定。当消息到达接口时,内核将查找所有与数据包中看到的协议号绑定的原始套接字,或已向发送 IP 发出“连接”的原始套接字。

所有与这些匹配的原始套接字都将接收数据包。

有关更精确的规则,此文本取自 Microsoft 的 TCP/IP 原始套接字

收到的数据报被复制到所有 SOCK_RAW 套接字满足以下条件:

  • 创建套接字时在协议参数中指定的协议号应该与收到的数据报的 IP 头中的协议号相匹配。
  • 如果为套接字定义了本地 IP 地址,则该地址应与收到的数据报的 IP 报头中指定的目标地址相对应。应用程序可以通过调用 bind 函数来指定本地 IP 地址。如果没有为套接字指定本地 IP 地址,则无论收到的数据报的 IP 报头中的目标 IP 地址是什么,数据报都会被复制到套接字中。
  • 如果为套接字定义了外部地址,则该地址应与收到的数据报的 IP 标头中指定的源地址相对应。应用程序可以通过调用 connect 或 WSAConnect 函数来指定外部 IP 地址。如果没有为套接字指定外部 IP 地址,则无论收到的数据报的 IP 标头中的源 IP 地址是什么,数据报都会被复制到套接字中。

对于 Linux,在 raw(7) - Linux 手册页

与原始套接字指定的协议号匹配的所有数据包或错误都将传递到此套接字。

相关内容