我知道在 linux 内核中我们可以在传输层添加我们自己的协议,类似于 TCP、UDP 等。
是否有任何钩子可以在网络层注册新协议,类似于 IP,ARP,可以将数据包传输到应用程序以及如何在 linux 内核中添加该协议?
我知道在 linux 内核中我们可以在传输层添加我们自己的协议,类似于 TCP、UDP 等。
是否有任何钩子可以在网络层注册新协议,类似于 IP,ARP,可以将数据包传输到应用程序以及如何在 linux 内核中添加该协议?
要处理从用户空间到您的协议的通信,请使用内核套接字 API注册您的协议。这允许您从用户空间创建一个普通的套接字。
查看相关代码示例的蓝牙/RFCOM 套接字实现。
static const struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.bind = rfcomm_sock_bind,
.connect = rfcomm_sock_connect,
.listen = rfcomm_sock_listen,
.
.
.
.accept = rfcomm_sock_accept,
};
static const struct net_proto_family rfcomm_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = rfcomm_sock_create
};
要注册协议,您必须填写proto_ops结构。这种结构遵循内核内部其他地方观察到的面向对象模式。该结构定义了一个接口,供开发人员实现自己的套接字接口时遵循。
实现接口定义的函数,如绑定、连接、监听,并将函数指针分配给结构入口。为操作接口未涵盖的功能定义 ioctl。
您最终会得到一个结构,稍后您将嵌入到我们从 create 函数返回的套接字结构中。
结构 net_proto_family定义了一个新的协议族。这个结构包括 create 函数,你的函数实现应该填充一个用 proto_ops 结构填充的套接字结构。
之后使用sock_register注册家庭,如果一切正常,您应该能够从用户空间创建适当的套接字。
在内部,该协议可能应该使用 skbuffs(参见此处和此处)与网络设备进行通信。
skbuffs 是 linux 内核中处理网络数据包的通用方式。数据包被网卡接收,放入一些skbuffs,然后传递到网络堆栈,网络堆栈一直使用skbuff。
这是在 linux 内核中实现网络协议的基本数据结构和 io 路径。
我不知道从头到尾描述此过程的文档。来源与您同在。
要实现该协议,请编写一个内核模块。
该模块应在/dev
. 然后,应用程序可以ioctl()
用来与您的模块对话,以指定目标主机、选项等内容。
有关如何在内核模块中实现的详细信息,请参阅 The Linux Kernel Module Programming Guide 的第 7 章ioctl()
。
这篇博文似乎也是对该主题的一个很好的介绍。