实验3:OpenFlow协议分析实践
一、实验目的
- 能够运用 wireshark 对 OpenFlow 协议数据交互过程进行抓包;
- 能够借助包解析工具,分析与解释 OpenFlow协议的数据包交互过程与机制。
二、实验环境
Ubuntu 20.04 Desktop amd64
三、实验要求
(一)基本要求
- 搭建下图所示拓扑,完成相关 IP 配置,并实现主机与主机之间的 IP 通信。用抓包软件获取控制器与交换机之间的通信数据。
主机 | IP地址 |
---|---|
h1 | 192.168.0.101/24 |
h2 | 192.168.0.102/24 |
h3 | 192.168.0.103/24 |
h4 | 192.168.0.104/24 |
- 查看抓包结果,分析OpenFlow协议中交换机与控制器的消息交互过程,画出相关交互图或流程图。
- 回答问题:交换机与控制器建立通信时是使用TCP协议还是UDP协议?
#!/usr/bin/env python from mininet.net import Mininet from mininet.node import Controller, RemoteController, OVSController from mininet.node import CPULimitedHost, Host, Node from mininet.node import OVSKernelSwitch, UserSwitch from mininet.node import IVSSwitch from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Intf from subprocess import call def myNetwork(): net = Mininet( topo=None, build=False, ipBase='192.168.0.0/24') info( '*** Adding controller\n' ) c0=net.addController(name='c0', controller=Controller, protocol='tcp', port=6633) info( '*** Add switches\n') s1 = net.addSwitch('s1', cls=OVSKernelSwitch) s2 = net.addSwitch('s2', cls=OVSKernelSwitch) info( '*** Add hosts\n') h1 = net.addHost('h1', cls=Host, ip='192.168.0.101', defaultRoute=None) h2 = net.addHost('h2', cls=Host, ip='192.168.0.102', defaultRoute=None) h3 = net.addHost('h3', cls=Host, ip='192.168.0.103', defaultRoute=None) h4 = net.addHost('h4', cls=Host, ip='192.168.0.104', defaultRoute=None) info( '*** Add links\n') net.addLink(h1, s1) net.addLink(h2, s1) net.addLink(h3, s2) net.addLink(h4, s2) net.addLink(s1, s2) info( '*** Starting network\n') net.build() info( '*** Starting controllers\n') for controller in net.controllers: controller.start() info( '*** Starting switches\n') net.get('s1').start([c0]) net.get('s2').start([c0]) info( '*** Post configure switches and hosts\n') CLI(net) net.stop() if __name__ == '__main__': setLogLevel( 'info' ) myNetwork()
2.抓包结果
- hello
set_config
Port Staus
Features Reply
Packet_in
Flow_mod
Packet_out
set-config
交互图
3. 交换机与控制器建立通信时是使用TCP协议
进阶
hello
hello OpenFlow源码
struct ofp_hello {
struct ofp_header header;
};
Features Request
struct ofp_header {
uint8_t version; /* OFP_VERSION. /
uint8_t type; / One of the OFPT_ constants. /
uint16_t length; / Length including this ofp_header. /
uint32_t xid; / Transaction id associated with this packet.
Replies use the same id as was in the request
to facilitate pairing. */
};
OFP_ASSERT(sizeof(struct ofp_header) == 8);
/* OFPT_HELLO. This message has an empty body, but implementations must
ignore any data included in the body, to allow for future extensions. */
struct ofp_hello {
struct ofp_header header;
};
set_config OpenFlow源码
struct ofp_switch_config {
struct ofp_header header;
uint16_t flags; /* OFPC_* flags. /
uint16_t miss_send_len; / Max bytes of new flow that datapath should
send to the controller. */
};
Port Staus OpenFlow源码
struct ofp_port_status {
struct ofp_header header;
uint8_t reason; /* One of OFPPR_*. /
uint8_t pad[7]; / Align to 64-bits. */
struct ofp_phy_port desc;
};
OFP_ASSERT(sizeof(struct ofp_port_status) == 64);
Features Reply
struct ofp_phy_port {
uint16_t port_no;
uint8_t hw_addr[OFP_ETH_ALEN];
char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */
Features Reply OpenFlow源码
struct ofp_switch_features {
struct ofp_header header;
uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for
a MAC address, while the upper 16-bits are
implementer-defined. */
uint32_t n_buffers; /* Max packets buffered at once. */
uint8_t n_tables; /* Number of tables supported by datapath. */
uint8_t pad[3]; /* Align to 64-bits. */
/* Features. */
uint32_t capabilities; /* Bitmap of support "ofp_capabilities". */
uint32_t actions; /* Bitmap of supported "ofp_action_type"s. */
/* Port info.*/
struct ofp_phy_port ports[0]; /* Port definitions. The number of ports
is inferred from the length field in
the header. */
};
Packet_in OpenFlow源码
/* Why is this packet being sent to the controller? /
enum ofp_packet_in_reason {
OFPR_NO_MATCH, / No matching flow. /
OFPR_ACTION / Action explicitly output to controller. /
};
Flow_mod OpenFlow源码
struct ofp_match {
uint32_t wildcards; /* Wildcard fields. /
uint16_t in_port; / Input switch port. /
uint8_t dl_src[OFP_ETH_ALEN]; / Ethernet source address. /
uint8_t dl_dst[OFP_ETH_ALEN]; / Ethernet destination address. /
uint16_t dl_vlan; / Input VLAN id. /
uint8_t dl_vlan_pcp; / Input VLAN priority. /
uint8_t pad1[1]; / Align to 64-bits /
uint16_t dl_type; / Ethernet frame type. /
uint8_t nw_tos; / IP ToS (actually DSCP field, 6 bits). /
uint8_t nw_proto; / IP protocol or lower 8 bits of
* ARP opcode. /
uint8_t pad2[2]; / Align to 64-bits /
uint32_t nw_src; / IP source address. /
uint32_t nw_dst; / IP destination address. /
uint16_t tp_src; / TCP/UDP source port. /
uint16_t tp_dst; / TCP/UDP destination port. /
};
/ Flow setup and teardown (controller -> datapath). /
struct ofp_flow_mod {
struct ofp_header header;
struct ofp_match match; / Fields to match /
uint64_t cookie; / Opaque controller-issued identifier. */
Packet_out OpenFlow源码
/* Send packet (controller -> datapath). /
struct ofp_packet_out {
struct ofp_header header;
uint32_t buffer_id; / ID assigned by datapath (-1 if none). /
uint16_t in_port; / Packet's input port (OFPP_NONE if none). /
uint16_t actions_len; / Size of action array in bytes. /
struct ofp_action_header actions[0]; / Actions. /
/ uint8_t data[0]; / / Packet data. The length is inferred
from the length field in the header.
(Only meaningful if buffer_id == -1.) */
};
个人总结
实验这次抓包,主要是有什么类型就截什么,然后对照流程图查找是否有漏掉的包。然后进阶的也不难然后看一下源码,然后对比一下自己的截图就能完成了。进阶要自己尝试完成,人要有所追求,没有追求的人太捞了。实验遇到的困难是出现没找到的类型,然后自己找了很久才完成。代码也是之前的代码更改一下就可以用在现在的实验,之前的实验是为了现在的实验服务的,所以多做认真一点后面就会轻松。根本没什么的。然后这次我理论知识还是缺乏,我会多去理解一下德,sdn还是值得去学习一下的,毕竟sdn还在上升阶段,把软件核网络联系起来。
标签:struct,OpenFlow,实践,uint8,header,ofp,实验,net,port From: https://www.cnblogs.com/battlefield/p/16757222.html