首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混淆AF_INET,SOCK_RAW作为套接字类型,V/S AF_PACKET,SOCK_DGRAM和SOCK_RAW作为套接字类型

混淆AF_INET,SOCK_RAW作为套接字类型,V/S AF_PACKET,SOCK_DGRAM和SOCK_RAW作为套接字类型
EN

Stack Overflow用户
提问于 2018-03-15 20:55:39
回答 1查看 3.4K关注 0票数 8

我对网络编程非常陌生,我已经尝试了很长一段时间都在想这件事。在通过互联网浏览了大量的资源之后,我得出了以下的结论,并对此感到困惑。

结论1:当我们讨论将套接字创建为:

代码语言:javascript
复制
s = socket(AF_INET, SOCK_RAW, 0);

我们基本上是在尝试创建一个原始套接字。使用这样创建的原始套接字,可以绕过OSI堆栈中的TCP/UDP层。这意味着,当应用程序通过这个套接字接收到数据包时,应用程序将有包含网络层(第三层)报头的包包装第二层报头,包装实际数据。因此,应用程序可以自由地处理这个包,超过第三层,在任何它想要的。

类似地,当通过这个套接字发送数据包时,应用程序也可以自由地处理数据包的创建,直到第4层,然后将其传递到第3层,从第三层开始,内核上的点将处理这些事情。

结论2:当我们讨论将套接字创建为:

代码语言:javascript
复制
s = socket(AF_PACKET, SOCK_RAW, 0);

我们再次尝试创建一个原始套接字。使用这样创建的原始套接字,您将能够完全绕过OSI的所有层。一个纯粹的原始包将提供给用户土地应用程序,它可以自由地对该包做它想做的任何事情。通过这样一个套接字接收的数据包将完整地拥有所有的标头,并且应用程序还可以访问所有这些标头。

类似地,在通过这样一个套接字发送数据时,用户应用程序必须处理与创建数据包和用每个层的头部包装实际数据有关的所有内容,然后才能将其实际放置到要传输的物理介质上。

结论3:当我们讨论创建套接字时,是:

代码语言:javascript
复制
s = socket(AF_PACKET, SOCK_DGRAM, 0);

我们再次尝试创建一个原始套接字。使用这样创建的原始套接字,您将能够绕过OSI堆栈中的数据链路层(第2层)。也就是说,当用户陆地应用程序接收到这样一个套接字上的数据包时,数据链路层报头被从数据包中移除。

类似地,在通过此套接字发送数据包时,根据sockaddr_ll目标地址中的信息,向数据包添加合适的数据链路层报头。

下面是我的疑问/困惑之处:

  1. 上述关于原始套接字的结论是否正确?
  2. 我不太清楚上面的结论3。谁能解释一下吗?例如,它是否意味着当用户land应用程序通过这个套接字接收到一个数据包时,只有数据链路层报头才会被内核处理?所以这个包就像直接用第三层的头包起来的消息,然后被上面的层包裹起来?
  3. 如果上述结论是正确的,则结论1和结论2仍有意义。但是,如果上面的结论3(以及上面2中围绕它的推测)是正确的,什么时候会有任何应用程序需要这样做呢?

我刚才所提及的一些资源,旨在了解上述各点:

https://docs.freebsd.org/44doc/psd/21.ipc/paper.pdf

raw

INET-in-python-socket

PACKET/

http://opensourceforu.com/2015/03/a-guide-to-using-raw-sockets/

RAW' option in 'socket' system call

http://stevendanna.github.io/blog/2013/06/23/a-short-sock-raw-adventure/

Sockets.htm

EN

回答 1

Stack Overflow用户

发布于 2022-04-26 18:55:52

你更接近他们的真实解释了。我有件事要告诉你我觉得你错过了什么或者错了什么。

首先,对于s = socket(AF_INET, SOCK_RAW, 0);,当通过这样的套接字接收数据包时,它将始终包含一个IP报头。如果未启用IP_HDRINCL,则为了发送,数据包必须包含IP报头,则TCP/IP堆栈将不会为您生成此消息。所有其他上层可以通过这个插座接收。

其次,s = socket(AF_PACKET, SOCK_RAW, 0);

这是Linux系统中一种特殊的原始套接字,称为数据包套接字.这种类型的套接字允许在OSI第2层发送和接收数据包,这就是为什么用于这种套接字的API被称为链接层API。任何协议都可以通过这个套接字在物理层的顶部实现。有趣的是,我们还可以用这个套接字与数据包的预告片进行交互,尽管我们并不经常需要。

第三,如果是s = socket(AF_PACKET, SOCK_DGRAM, 0);,你的结论是正确的。在这种类型的数据包套接字中,不需要考虑以太网报头。这比以前的类型要高一些。

因此,我们可以说,这些类型的套接字的主要区别在于它们访问的可能性。概括地说:

  1. 原始套接字访问:

| Layer 3 header | Layer 4 header | Payload |

  1. 数据包-套接字访问:

| Layer 2 header | Layer 3 header | Layer 4 header | Payload | Layer 2 trailer |

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49309029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档