OFP_Sniffer 是一个用于故障排除和学习的 OpenFlow 嗅探器。
当前版本为 1.2,它能解析所有 OpenFlow 1.0 消息,并与 InfluxDB、Grafana 和 Slack 集成。 OpenFlow 1.3 将在 OFP_Sniffer 版本 1.3 中提供(即将发布)。
它直接在 Linux shell 上工作,并解析线缆上或来自 libpcap 文件的所有 OpenFlow 消息。使用 OFP_Sniffer,您可以轻松跟踪 OpenFlow 消息及其关联的错误(如果有),而无需打开 X11 或 Wireshark。OFP_Sniffer 使用 Python 3.6 编写,以支持 AmLight SDN 部署(www.sdn.amlight.net)。 AmLight SDN 使用 Internet2 FlowSpace Firewall、OESS 和 On.Lab ONOS,这些应用已经过测试并得到完全支持。
作为命令行界面工具,它有一些输入参数:
# ./ofp_sniffer.py -h
Usage:
./ofp_sniffer.py [-p min|full] [-f pcap_filter] [-F filter_file] [-i dev] [-r pcap_file]
-p : print all TCP/IP headers. Default: min
-f pcap_filter or --pcap-filter=pcap_filter: add a libpcap filter
-F filters_file.json or --filters-file=filters.json
-i interface or --interface=interface. Default: eth0
-r captured.pcap or --src-file=captured.pcap
-T topology.json or --topology-file=topology.json
-w file or --save-to-file=file: save output to file provided
-o or --print-ovs : print using ovs-ofctl format
-h or --help : prints this help
-c or --no-colors: removes colors
-v or --version : prints version
-O WARN:CRIT or --oess-fvd=WARN:CRIT: monitor OESS FVD status
-N or --notify-via-slack: send notifications via Slack. Param is the Slack channel
-S or --enable-statistics: creates statistics
从版本 1.0 开始,支持应用处理特定需求,例如跟踪 OESS FVD 消息或通过 REST 创建统计信息并集成到 NMS(例如 Zabbix)。
更多信息:https://amlight.net/wp-content/uploads/2015/03/wpeif-2016-ofpsniffer.pdf
##################### 安装 ######################
Requires Python 3.6
git clone https://github.com/amlight/ofp_sniffer.git
cd ofp_sniffer
pip3.6 install -r docs/requirements.txt
sudo ./ofp_sniffer.py
##################### 示例 #########################
示例如下:
---------------------- -------------------------
| Mininet | | OVS-OFCTL 2.3.0 |
| 192.168.56.101:6634| <-------> | eth1 - 192.168.56.102 |
---------------------- -------------------------
# ovs-ofctl dump-flows tcp:192.168.56.101:6634
cookie=0x0, duration=2183.377s, table=0, n_packets=0, n_bytes=0, idle_age=2183, in_port=1,dl_vlan=2 actions=output:2
# ./ofp_sniffer.py -i eth1 -f " or port 6634"
Sniffing device eth1
2015-09-13 11:47:38.655503 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 74
OpenFlow Version: 1.0(1) Type: Hello(0) Length: 8 XID: 1
1 OpenFlow Hello
2015-09-13 11:47:38.656964 192.168.56.101:6634 -> 192.168.56.102:37450 Size: 74
OpenFlow Version: 1.0(1) Type: Hello(0) Length: 8 XID: 174
174 OpenFlow Hello
2015-09-13 11:47:38.657638 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 86
OpenFlow Version: 1.0(1) Type: Vendor(4) Length: 20 XID: 2
2 OpenFlow Vendor : NICIRA(0x2320)
2 OpenFlow Vendor Data: 12 2
2015-09-13 11:47:38.657870 192.168.56.102:37450 -> 192.168.56.101:6634 Size: 74
OpenFlow Version: 1.0(1) Type: BarrierReq(18) Length: 8 XID: 3
3 OpenFlow Barrier Request
2015-09-13 11:47:38.659270 192.168.56.101:6634 -> 192.168.56.102:37450 Size: 74
OpenFlow Version: 1.0(1) Type: BarrierRes(19) Length: 8 XID: 3
3 OpenFlow Barrier Reply
# ovs-ofctl add-flow tcp:192.168.56.101:6634 "dl_dst=10:00:00:01:20:00,dl_type=0x88bc actions=mod_vlan_vid:14,output:2"
# ./ofp_sniffer.py -i eth1 -f " or port 6634"
2015-09-13 11:49:08.171463 192.168.56.102:37451 -> 192.168.56.101:6634 Size: 154
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 88 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Add(0) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
2 OpenFlow Action - Type: SetVLANID Length: 8 VLAN ID: 14 Pad: 0
2 OpenFlow Action - Type: OUTPUT Length: 8 Port: 2 Max Length: 0
# ovs-ofctl del-flows tcp:192.168.56.101:6634 "dl_type=0x88bc,dl_dst=10:00:00:01:20:00, "
2015-09-13 11:50:43.636925 192.168.56.102:37454 -> 192.168.56.101:6634 Size: 138
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 72 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Delete(3) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
# ovs-ofctl add-flow tcp:192.168.56.101:6634 "dl_dst=10:00:00:01:20:00,dl_type=0x88bc actions=mod_vlan_vid:14,output:2"
2015-09-13 11:52:58.563737 192.168.56.102:37455 -> 192.168.56.101:6634 Size: 154
OpenFlow Version: 1.0(1) Type: FlowMod(14) Length: 88 XID: 2
2 OpenFlow Match - wildcards: 3678439 dl_type: 0x88bc dl_dst: 10:00:00:01:20:00
2 OpenFlow Body - Cookie: 0x00 Command: Add(0) Idle/Hard Timeouts: 0/0 Priority: 32768 Buffer ID: 0xffffffff Out Port: 65535 Flags: Unknown Flag(0)
2 OpenFlow Action - Type: SetVLANID Length: 8 VLAN ID: 14 Pad: 0
2 OpenFlow Action - Type: OUTPUT Length: 8 Port: 2 Max Length: 0
使用过滤器:
当使用选项 -F ./filters.json 时,您将获得一些选项:
"rejected_of_types" : 用于选择您不想看到的 OpenFlow 消息类型。您可以根据 OpenFlow 版本定义不同的过滤器。
按 Ethertype 过滤:
如果您正在查找通过 PacketOut 或 PacketIn 消息传输的特定 Ethertype,您可以拒绝所有其他类型,从而轻松查看。
示例:
"filters":{
"ethertypes": {
"lldp" : 0,
"fvd" : 0,
"arp" : 1,
"others": [ "88b5" ]
},
"packetIn_filter": {
"switch_dpid": "any",
"in_port": "any"
},
"packetOut_filter": {
"switch_dpid": "any",
"out_port": "any"
}
}
}
在 ethertype 部分,1 表示过滤,0 表示打印。在提供的示例中,ARP 消息将不被看到,而 OESS FVD 和 LLDP 将被看到。您可以在 "others" 部分添加 Ethertype 十六进制数(不带 0x),只需添加逗号(",")。
"packetIn_filter": 用于定义您想要看到的 PacketIn + LLDP 消息。您可以按交换机和/或端口定义。对于交换机,您需要使用应用程序所见的 datapath_id。例如,某些应用将 c_id 字段填充为 of:dpid_id,其他应用填充为 dpid:dpid_id。对于端口,使用 OpenFlow port_id,而不是端口名称。例如,在 Brocade 上,eth1/1 == 1。因此使用 1 而不是 eth1/1。
"packetOut_filter": 用于定义您想要看到的 PacketOut + LLDP 消息。您可以按交换机和/或端口定义。对于交换机,您需要使用应用程序所见的 datapath_id。例如,某些应用将 c_id 字段填充为 of:dpid_id,其他应用填充为 dpid:dpid_id。对于端口,使用 OpenFlow port_id,而不是端口名称。例如,在 Brocade 上,eth1/1 == 1。因此使用 1 而不是 eth1/1。
支持 OpenFlow 代理:
当使用 OpenFlow 代理时,根据您选择的嗅探接口,您将看到以下两种可能性之一: IP_Controller <-> IP_Proxy IP_Proxy <-> IP_Switch
很难关联哪个控制器与哪个交换机通信。为了简化这种故障排除,OpenFlow 嗅探器会自动监控所有 PacketOut + LLDP 消息,以创建 {(IP, port): name_switch} 字典。如果您遇到这种情况,请修改 docs/topology.json 文件。下次运行嗅探器时,您将看到 IP 以及括号中代理后面的设备。示例:
2015-12-16 15:37:41.563621 200.0.207.79(andes1):7801 -> 190.103.184.135:6633 Size: 157 Bytes
OpenFlow Version: 1.0(1) Type: PacketIn(10) Length: 103 XID: 0
0 PacketIn: buffer_id: 0xffffffff total_len: 85 in_port: 49 reason: OFPR_NO_MATCH(0) pad: 0
0 Ethernet: Destination MAC: ff:ff:ff:ff:ff:ff Source MAC: de:ad:be:ef:ba:11 Protocol: 0x8100
0 Ethernet: Prio: 0 CFI: 0 VID: 3720
0 LLDP: Chassis Type(1) Length: 7 SubType: 4 ID: of:cc4e249102000000
0 LLDP: Port Type(2) Length: 5 SubType: 2 ID: 2
0 LLDP: TTL(3) Length: 2 Seconds: 120
0 LLDP: END(0) Length: 0
2015-12-16 15:37:41.564414 190.103.184.133(andes1):56132 -> 190.103.187.72:6633 Size: 165 Bytes
OpenFlow Version: 1.0(1) Type: PacketIn(10) Length: 99 XID: 0
0 PacketIn: buffer_id: 0xffffffff total_len: 81 in_port: 49 reason: OFPR_NO_MATCH(0) pad: 0
0 Ethernet: Destination MAC: ff:ff:ff:ff:ff:ff Source MAC: de:ad:be:ef:ba:11 Protocol: 0x8942
0 LLDP: Chassis Type(1) Length: 7 SubType: 4 ID: of:cc4e249102000000
0 LLDP: Port Type(2) Length: 5 SubType: 2 ID: 2
0 LLDP: TTL(3) Length: 2 Seconds: 120
0 LLDP: END(0) Length: 0
名称 (andes1) 代表一个名为 "andes1" 的交换机,其 DPID 为 cc4e249126000000。请注意,示例中显示的 DPID 并不相同,因为此处使用 PacketIn 消息作为示例。PacketIn 显示了 "andes1" 邻居的 DPID。
希望这些代码对您有帮助。
问题/建议:AmLight Dev Team [email protected]