Open flow 协议分析实验
实验难度:适中实验过程遇到的困难及解决办法:第一次建立拓扑后,因为操作错误想重新做一次,结果再次运行py文件,提示说文件已存在,一时有点不知所措。查询资料后发现可以用sudo mn -c删除一下,然后重新启动虚拟机再重新运行就可以了。打开wireshark后创建拓扑,过滤出Openflow数据包,发现没有找到Flow_Mod的数据包。重新看了老师给的pdf,并上网搜索资料后发现要先pingall一
前言
在当今网络架构中,OpenFlow技术作为SDN(软件定义网络)的关键支持技术之一,为网络流量控制提供了更加灵活和智能的解决方案。Wireshark作为一个优秀的网络协议分析工具,可以帮助我们深入了解OpenFlow协议背后的数据交换过程。在本文中,我们将通过Wireshark工具来分析OpenFlow协议,探索其工作原理和数据交换过程。
1. OpenFlow简介
OpenFlow是一种通信协议,用于在网络设备之间进行通信,并 能够实现控制数据流的灵活性和集中管理。OpenFlow协议通过控制器来管理网络设备,并根据网络流量的需求对网络设备进行动态配置和管理。
2. Wireshark简介
Wireshark是一款开源的网络协议分析工具,可以帮助用户捕获和分析网络数据包。通过Wireshark工具,我们可以深入了解数据包的传输过程,进而解决网络问题和优化网络性能。
3.实验步骤
文献参考https://www.cnblogs.com/eleven955/p/15328388.html
3.1实验前置任务
1.首先在ubuntu系统中启动mininet可视化界面
mininet/examples/miniedit.py
然后按照下图所示,搭建拓扑图
2.点击左上角的Exit里的Preferences,并按照下图进行设置
3.将修改好的拓扑图保存为*.py的格式,如下图所示
使用vim打开文件,编辑每个终端的IP地址,当然,您也可以提前在拓扑图中编辑IP地址。
vim name.top
保存好之后,主要任务的前置任务就算完成了
3.2基础实验
首先再打开一个终端,用来启动Wireshark进程
wireshark
如果您使用的账户非root模式,请在指令前加上sudo
之后 ,使用第一个终端运行 保存好的拓扑图py文件
python {name}.py
pingall
打开Wireshark开始分析数据包
当控制器和交换机建立连接时,它们会通过发送 "OFPT_HELLO" 消息进行握手。这个握手过程用于确保双方都理解彼此的通信协议版本,并为后续的通信建立基础。,其中包含了源端口号(6633)与目的端口号(59784)
并且可以看到使用的传输协议是TCP协议
查看openflow_v6的数据包
查看openflow_v1的数据包的OFPT_FEATURES_REQUEST,OFPT_FEATURES_REQUEST用于控制器向交换机请求交换机的特性和能力。当控制器与交换机建立连接后,通常会发送此类消息以获取关于交换机的信息,以便控制器可以了解交换机的功能和配置。
查看openflow_v1的数据包的OPTF_SET_CONFIG,OPTF_SET_CONFIG可以确保控制器和交换机之间的行为一致,并能够对交换机的行为进行精细的控制。
查看openflow_v1的数据包的OPTF_PACKET_IN,OPTF_PACKET_IN用于将从交换机收到的数据包传送给控制器。当交换机无法根据当前的流表项处理接收到的数据包时,会生成一个 "OFPT_PACKET_IN" 消息,并将数据包及相关信息发送到控制器。
查看openflow_v1的数据包的OPTF_PACKET_OUT, 通过“OFPT_PACKET_OUT”消息,控制器可以实现对数据包的编程式控制,用于实现特定的网络行为、策略或功能。
查看openflow_v1的数据包的OPTF_PACKET_MOD, 通过发送 "OFPT_FLOW_MOD" 消息,控制器可以向交换机添加、修改或删除流表项,从而控制数据包的处理方式。
3.3进阶实验
在OpenFlow的安装目录中,通过对比抓包结果和源代码,可以了解OpenFlow主要消息类型所对应的数据结构定义。相关的数据结构定义可以在openflow/include/openflow/openflow.h头文件中找到。
接下来我们将对openflow.h对比抓包结果进行分析
3.3.1 HELLO
以上四个为一一对应,分别是ofp版本、OFPT类型,长度与xid,xid为随机生成的一段字符串,两个数据包拥有相同的xid说明他们属于同一次会话
struct ofp_header {
uint8_t version; /* OFP版本。 */
uint8_t type; /* OFPT_常数之一。 */
uint16_t length; /* 长度,包括标头的长度。 */
uint32_t xid; /* 与此数据包关联的事务id。
回复使用与请求中相同的id
以便于配对。 */
};
struct ofp_hello {
struct ofp_header header;
};
3.3.2 FEATURES_REQUEST
内容与HELLO的结构是相同的,所以这里就不举例子了
3.3.3 SET_CONFIG
/* Switch configuration. */
struct ofp_switch_config {
struct ofp_header header;
uint16_t flags; /* OFPC_*标志。 */
uint16_t miss_send_len; /*数据路径应具有的新流的最大字节数
发送到控制器。 */
};
3.3.4PORT_STATUS
/* A physical port has changed in the datapath */
struct ofp_port_status {
struct ofp_header header;
uint8_t reason; /* OFPPR_*之一。 */
uint8_t pad[7]; /* 对齐到64位。 */
struct ofp_phy_port desc;
};
3.3.5FEATURES_REPLY
struct ofp_switch_features {
struct ofp_header header;
uint64_t datapath_id; /* 数据路径唯一ID。较低的48位用于
MAC地址,而高16位是
实现者定义的。 */
uint32_t n_buffers; /* 一次缓冲的最大数据包数。 */
uint8_t n_tables; /* 数据路径支持的表数。 */
uint8_t pad[3]; /* 对齐到64位。 */
/* Features. */
uint32_t capabilities; /* 支持“ofp_capabilities”的位图。 */
uint32_t actions; /* 支持的“ofp_action_type”s的位图。 */
/* Port info.*/
struct ofp_phy_port ports[0]; /* 端口定义。端口数
根据中的长度字段推断
标头。 */
};
/* Description of a physical port */
struct ofp_phy_port {
uint16_t port_no;
uint8_t hw_addr[OFP_ETH_ALEN];
char name[OFP_MAX_PORT_NAME_LEN]; /* 空字符结尾 */
uint32_t config; /* OFPPC_*标志的位图。 */
uint32_t state; /* OFPPC_*标志的位图。 */
/* Bitmaps of OFPPF_* that describe features. All bits zeroed if
* unsupported or unavailable. */
uint32_t curr; /* 当前功能。 */
uint32_t advertised; /* 端口正在播发的功能。 */
uint32_t supported; /* 端口支持的功能。 */
uint32_t peer; /* 同行宣传的功能。 */
};
3.3.6PACKET_IN
有两种情况
交换机查找流表,发现没有匹配条目
enum ofp_packet_in_reason {
OFPR_NO_MATCH, /* 没有匹配的流。*/
OFPR_ACTION /* 动作明确输出到控制器。 */
};
有匹配条目,对应的action是OUTPUT=CONTROLLER,固定收到向控制器发送包
struct ofp_packet_in {
struct ofp_header header;
uint32_t buffer_id; /* 数据路径分配的ID。 */
uint16_t total_len; /* 框架的全长。 */
uint16_t in_port; /* 接收帧的端口。 */
uint8_t reason; /* 发送数据包的原因(OFPR_*之一) */
uint8_t pad;
uint8_t data[0]; /* 以太网帧,32位字的中途,
因此IP报头是32位对齐的。这个
根据长度推断出数据量
字段。由于填充,
offsetof(结构of_packet_in,数据)==
sizeof(struct-ofp_packet_in)-2。 */
};
3.3.7PACKET_OUT
struct ofp_packet_out {
struct ofp_header header;
uint32_t buffer_id; /* 由数据路径分配的ID(如果没有,则为-1)。 */
uint16_t in_port; /* 数据包的输入端口(如果没有,则为OFPP_NONE)。 */
uint16_t actions_len; /* 操作数组的大小(以字节为单位)*/
结构of_action_header actions[0];/*行动。 */
/* uint8_t data[0]; */ /* 数据包数据。推断长度
来自标头中的长度字段。
(只有当buffer_id==-1时才有意义。) */
};
3.3.8FLOW_MOD
struct ofp_flow_mod {
struct ofp_header header;
struct ofp_match match; /* 要匹配的字段 */
uint64_t cookie; /* 不透明控制器发布的标识符。 */
/* Flow actions. */
uint16_t command; /* OFPFC_*之一。 */
uint16_t idle_timeout; /* 丢弃前的空闲时间(秒)。 */
uint16_t hard_timeout; /* 丢弃前的最长时间(秒)。 */
uint16_t priority; /* 流输入的优先级。 */
uint32_t buffer_id; /* 要应用到的缓冲数据包(或-1)。
对OFPFC_DELETE*没有意义。 */
uint16_t out_port; /* 对于OFPFC_DELETE*命令,需要
匹配条目以将其作为
输出端口。OFPP_NONE的值
表示没有限制。 */
uint16_t flags; /* OFPFF_*之一。 */
struct ofp_action_header actions[0]; /* 推断动作长度
中的长度字段
头 */
};
struct ofp_action_header {
uint16_t type; /* OFPAT_*之一。 */
uint16_t len; /* 行动时间长度,包括
头这是动作的长度,
包括任何填充物
64位对齐。 */
uint8_t pad[4];
};
4.总结
- 实验难度:适中
- 实验过程遇到的困难及解决办法:
- 第一次建立拓扑后,因为操作错误想重新做一次,结果再次运行py文件,提示说文件已存在,一时有点不知所措。查询资料后发现可以用sudo mn -c删除一下,然后重新启动虚拟机再重新运行就可以了。
- 打开wireshark后创建拓扑,过滤出Openflow数据包,发现没有找到Flow_Mod的数据包。重新看了老师给的pdf,并上网搜索资料后发现要先pingall一下,才能找到Flow_mod数据包。
- 个人感想:
这次实验是验证性实验,实验难度相对会容易些,只需要建立拓扑后在wireshark中操作,就是找包的时候数据比较多,看起来比较累眼睛。通过阅读openflow的源码,能理清楚其中的数据结构,并和实际抓到的包的详细信息对应起来,从而理解openflow协议的数据包交互过程。除此之外,对wireshark中过滤器的使用也有了更深刻的了解,对openflow协议有了更深刻的认识。
更多推荐
所有评论(0)