INET 中加入自定义协议的方法

当 INET 原生不具备所需实验环境时,我们可能需要自己编写一些网络协议以实现预期功能。基于此,本文将对 INET 中加入自定义协议的方法进行调研和记录。

1 INET 基础架构

在 INET 环境中添加一个协议之前,首先需要对 INET 的基本框架有所了解。这样,我们才能知道自定义的协议应该放置在 INET 中的哪个位置。INET 的源码模块的组织依然遵循了 OSI 层次结构,即:

路径 内容
src/inet/applications/ 流量生成器和应用模型
src/inet/transportlayer/ 传输层协议
src/inet/networklayer/ 网络层协议
src/inet/linklayer/ 链路层协议
src/inet/physicallayer/ 物理层模型
src/inet/routing/ 路由协议
src/inet/mobility/ 移动模型
src/inet/power/ 能耗模型
src/inet/environment/ 物理环境模型
src/inet/node/ 预安装的网络节点模型
src/inet/visualizer/ 可视化组件(2D/3D)
src/inet/common/ 杂项实用组件

需要注意的是,上表中的第一行 src/inet/applications/ 不是指七层协议中的应用层,只是定义了发包行为的实例。

2 添加自定义协议

2.1 实验中的添加方式

以实验中的 PFRP(Probabilistic forwarding routing protocol)协议为例,我们可以借助现有的网络协议快速便捷地将自定义协议添加到 INET 环境。

首先,在 src/inet/applications/ 中编写用于控制收发包的应用模型 UdpPfrpApp,该模型由 3 个文件组成:

  • UdpPfrpApp.h:包含 UdpPfrpApp 类的声明

    1
    2
    3
    class INET_API UdpPfrpApp : public ApplicationBase, public UdpSocket::ICallback {
    ...
    }
  • UdpPfrpApp.cc:包含 UdpPfrpApp 类的具体实现

  • UdpPfrpApp.ned:定义 UdpPfrpApp 模块

在 UdpPfrpApp.cc 文件中,我们需要先将所使用的路由协议名(PFRP)添加到控制发包的 sendPacket() 函数中:

1
2
3
4
5
6
7
8
void UdpPfrpApp::sendPacket() {
...
string endlr = "-" + dn + "-" + routingProtocol + "-" + to_string(sendPacketId) + "-" + to_string(stepNum);
const char* endlre = endlr.c_str();
Packet *packet = new Packet(strcat(sender,endlre));
...
socket.sendTo(packet, destAddr, destPort);
}

其中,routingProtocol 为我们定义的路由协议名。将 routingProtocol 添加到字符串 endlr 后,再将其转换为 packet 发送到网络层。

发送到网络层后,我们就可以修改网络层协议 src/inet/networklayer/ipv4/Ipv4.cc 来进行下一步处理。对 Ipv4.cc 文件的 routeUnicastPacket() 函数进行修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Ipv4::routeUnicastPacket(Packet *packet) {
...
if (destIE) {
...
}
else {
// 若是 pfrp
if (strstr(packet->getFullName(), "pfrp")) {
... // 调用 pfrpTable 进行相应的操作
}
else {
... // 若不是 pfrp,则按原有设定操作
}
}
}

由上述代码可知,当判断使用的路由协议是 PFRP 后,该部分还引入了自定义的 pfrpTable 辅助操作。pfrpTable 包含 pfrpTable.h 、pfrpTable.cc两个文件,和 Ipv4.cc 位于同一目录。pfrpTable 实现了概率路由表的生成、处理工作,并承担与 Python 端的通信任务。需要注意的是,在之前所提到的 UdpPfrpApp 中也存在着大量对 pfrpTable 的调用,pfrpTable 是概率路由协议实现的基石。

2.2 OMNet 教程的添加方式

以网络层协议 ISIS 为例,首先,由于 ISIS 是网络层协议,需要将其源代码的实现放在 networkplayer 目录下。在该目录下创建一个 isis 文件夹来保存具体实现代码。

对于一个新的协议,至少需要包含以下 3 个文件:

  • ISIS.ned 文件

    NED 文件用来定义 ISIS 模块,使得其他的 NED 文件可以调用 ISIS 模块

  • ISIS.cc

    包含有 ISIS 类的具体实现

  • ISIS.h

    包含有 ISIS 类的声明

从 INET for Omnet++ 4 开始,完成上述工作后直接在 INET 根目录下执行 make 命令即可使用。

值得注意的是,在使用 ISIS 模块时需要在 NED 文件中加入声明:

1
package inet.networklayer.isis;

同时,编写代码的时候要注意模块中的结构体不要和已有协议中的名称一样,否则会无法链接。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 lgc0208@foxmail.com
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信