我试图了解网络驱动程序在Linux下的工作原理. This Q&A显示Linux中的网络设备未由设备文件表示.它声明网络驱动程序使用套接字.
例如,this引用了如何通过ioctl调用设置网络设备. ioctl但是needs a file descriptor,鉴于网络驱动程序没有设备文件,唯一可以传递的文件描述符是套接字中的文件描述符.
这让我想到了问题.到目前为止,似乎网络接口,它将是物理网卡的软件表示,实际上是套接字的劣等对象.
>但是这个抽象意义上的套接字是什么,它只是支持推送通知的设备文件的另一个名称?我理解用户空间应用程序绑定到网络接口上的地址:端口对的连接点的TCP套接字.我不了解套接字是设置网络接口的先决条件.
> Linux上的网络接口(如ifconfig列出的eth0)是否可以在没有套接字的情况下存在?
> ifconfig或某个网络管理器守护程序是否保持套接字打开以允许我们设置网络接口选项?
解决方法:
让我们快速查看设备文件:在Linux中,应用程序通过文件描述符将rad和write操作传递给内核.这对文件非常有用,事实证明,相同的API可用于生成和使用字符流的字符设备,并阻止在随机访问地址读取和写入固定大小的块的设备,只需假装这些也是文件.
但是需要一种方法来配置这些设备(设置波特率等),为此,发明了ioctl调用.它只传递一个特定于设备的数据结构和用于内核的I / O控件的类型,并将结果返回到相同的数据结构中,因此它是一个非常通用的可扩展API,可以用于很多事情.
现在,网络运营如何适应?典型的网络服务器应用程序想要绑定到某个网络地址,侦听某个端口(例如,80表示HTTP,或22表示ssh),如果客户端连接,它希望向该客户端发送数据和从该客户端接收数据.以及客户的双重操作.
如何将其与文件操作相结合并不明显(尽管可以这样做,参见Plan 9),这就是UNIX设计者发明新API的原因:套接字.您可以在第2节手册页中找到有关socket,bind,listen,connect,send和recv的详细信息.请注意,虽然它与文件I / O API不同,但套接字调用仍会返回文件描述符.有很多关于如何在网络上使用套接字的教程,google.
到目前为止,这都是纯UNIX,在发明套接字时没有人谈论网络接口.并且因为这个API真的很旧,它被定义为除了Internet协议之外的各种网络协议(查看AF_ *常量),尽管Linux中只支持其中的一些.
但随着计算机开始获得多个网卡,需要对此进行一些抽象.在Linux中,即网络接口(NI).它不仅用于一个硬件,而且用于各种隧道,用作隧道服务器的用户应用程序端点,如OpenVPN等.如上所述,套接字API不是基于(特殊)文件而是独立于文件系统.同样,网络接口也不会出现在文件系统中.但是,NI在/ proc和/ sys文件系统(以及其他网络可调参数)中可用.
NI很简单,是网络数据包进入和离开内核的端点的内核抽象.另一方面,套接字用于与应用程序通信数据包.处理数据包时不需要套接字.例如,当启用转发时,数据包可以进入一个NI并留在另一个NI上.
从这个意义上讲,套接字和网络接口是完全独立的.
但必须有一种配置NI的方法,就像你需要一种配置块和字符设备的方法一样.由于套接字已经返回了文件描述符,因此仅允许在该文件描述符上使用ioctl是合乎逻辑的.这是你链接的netdevice接口.
以类似的方式存在相当多的其他系统调用滥用,例如用于包过滤,包捕获等.
所有这些都逐渐成长,在很多地方并不是特别合乎逻辑.如果它是一次性设计的,那么人们可能已经建立了一个更正交的API.