我知道在linux内核中,我们可以在传输层添加自己的协议,类似于TCP,UDP等。
是否有任何钩子在networking层注册一个新的协议,类似于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结构。 这个结构遵循在内核其他地方观察到的面向对象的模式 。 这个结构为开发者实现自己的socket接口定义了一个接口。
实现接口定义的函数,比如绑定,连接,监听,并将函数指针分配给结构入口。 定义ioctl的操作界面没有涵盖的功能。
你最终得到一个结构,以后你将嵌入到我们从create函数返回的套接字结构中 。
struct net_proto_family定义了一个新的协议族。 这个结构包括create函数,你的函数实现应该填充一个用proto_ops结构填充的套接字结构。
之后,注册与sock_register家庭,如果一切正常,你应该能够从用户空间创建一个合适的套接字。
协议内部应该使用skbuffs 1 , [2] , [3] (pdf)。 与网络设备进行通信。
skbuffs是在linux内核中处理网络数据包的通用方式。 数据包由网卡接收,放入一些skbuffs,然后传递到网络堆栈,一直使用skbuff。
这是在Linux内核中实现网络协议的基本数据结构和路径。
我不知道从头到尾描述这个过程的文档。 来源与你在这一个。
为了实现该协议,编写一个内核模块。
该模块应该在/dev
创建一个新的设备。 然后,应用程序可以使用ioctl()
与您的模块进行交谈,以指定目标主机,选项等。
有关如何在内核模块中实现ioctl()
详细信息, 请参阅“Linux内核模块编程指南”的第7章 。
这篇博文似乎也是对这个话题的一个很好的介绍。