1% Tests for OpenFlow v1.0 with Scapy 2 3+ Preparation 4= Be sure we have loaded OpenFlow v1 5load_contrib("openflow") 6 7+ Usual OFv1.0 messages 8 9= OFPTHello(), simple hello message 10ofm = OFPTHello() 11raw(ofm) == b'\x01\x00\x00\x08\x00\x00\x00\x00' 12 13= OFPTEchoRequest(), echo request 14ofm = OFPTEchoRequest() 15raw(ofm) == b'\x01\x02\x00\x08\x00\x00\x00\x00' 16 17= OFPMatch(), check wildcard completion 18ofm = OFPMatch(in_port=1, nw_tos=8) 19ofm = OFPMatch(raw(ofm)) 20assert ofm.wildcards1 == 0x1 21ofm.wildcards2 == 0xee 22 23= OpenFlow(), generic method test with OFPTEchoRequest() 24ofm = OFPTEchoRequest() 25s = raw(ofm) 26isinstance(OpenFlow(s), OFPTEchoRequest) 27 28= OFPTFlowMod(), check codes and defaults values 29ofm = OFPTFlowMod(cmd='OFPFC_DELETE', out_port='CONTROLLER', flags='CHECK_OVERLAP+EMERG') 30assert ofm.cmd == 3 31assert ofm.buffer_id == 0xffffffff 32assert ofm.out_port == 0xfffd 33ofm.flags == 6 34 35+ Complex OFv1.0 messages 36 37= OFPTFlowMod(), complex flow_mod 38mtc = OFPMatch(dl_vlan=10, nw_src='192.168.42.0', nw_src_mask=8) 39act1 = OFPATSetNwSrc(nw_addr='192.168.42.1') 40act2 = OFPATOutput(port='CONTROLLER') 41act3 = OFPATSetDlSrc(dl_addr='1a:d5:cb:4e:3c:64') 42ofm = OFPTFlowMod(priority=1000, match=mtc, flags='CHECK_OVERLAP', actions=[act1,act2,act3]) 43raw(ofm) 44s = b'\x01\x0e\x00h\x00\x00\x00\x00\x00?\xc8\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x08\x00\x00\x00\x00\x00\xc0\xa8*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xe8\xff\xff\xff\xff\xff\xff\x00\x02\x00\x06\x00\x08\xc0\xa8*\x01\x00\x00\x00\x08\xff\xfd\xff\xff\x00\x04\x00\x10\x1a\xd5\xcbN<d\x00\x00\x00\x00\x00\x00' 45raw(ofm) == s 46 47= OFPETBadRequest() containing a flow_mod with wrong table_id 48flowmod = OFPTFlowMod(actions=OFPATOutput(port='LOCAL')) 49ofm = OFPETBadRequest(errcode='OFPBRC_EPERM', data=raw(flowmod)) 50hexdump(ofm) 51s = b'\x01\x01\x00\\\x00\x00\x00\x00\x00\x01\x00\x05\x01\x0e\x00P\x00\x00\x00\x00\x00?\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x08\xff\xfe\xff\xff' 52raw(ofm) == s 53 54= OFPTPacketIn() containing an Ethernet frame 55ofm = OFPTPacketIn(data=Ether()/IP()/ICMP()) 56p = OFPTPacketIn(raw(ofm)) 57dat = p.data 58assert isinstance(dat, Ether) 59assert isinstance(dat.payload, IP) 60isinstance(dat.payload.payload, ICMP) 61 62= OFPTStatsReplyFlow() 63pkt = TCP()/OFPTStatsReplyFlow(flow_stats=[OFPFlowStats(actions=[OFPATSetTpSrc()])]) 64pkt = TCP(raw(pkt)) 65assert isinstance(pkt.flow_stats[0].actions[0], OFPATSetTpSrc) 66 67= OFPTQueueGetConfigReply() 68pkt = TCP()/OFPTQueueGetConfigReply(queues=[OFPPacketQueue(properties=[OFPQTMinRate(rate=123)])]) 69pkt = TCP(raw(pkt)) 70assert pkt.queues[0].properties[0].rate == 123 71 72= OFPETHelloFailed() 73pkt = OFPETHelloFailed(data=OFPTEchoRequest()) 74pkt = OFPETHelloFailed(raw(pkt)) 75assert isinstance(pkt.data, OFPTEchoRequest) 76 77+ Layer bindings 78 79= TCP()/OFPTStatsRequestDesc(), check default sport 80p = TCP()/OFPTStatsRequestDesc() 81p[TCP].sport == 6653 82 83= TCP()/OFPETHelloFailed(), check default dport 84p = TCP()/OFPETHelloFailed() 85p[TCP].dport == 6653 86 87= TCP()/OFPTHello() dissection, check new TCP.guess_payload_class 88o = TCP(dport=6653)/OFPTHello() 89p = TCP(raw(o)) 90p[TCP].sport == 6653 91isinstance(p[TCP].payload, OFPTHello) 92 93= complete Ether()/IP()/TCP()/OFPTFeaturesRequest() 94ofm = Ether(src='00:11:22:33:44:55',dst='01:23:45:67:89:ab')/IP(src='10.0.0.7',dst='192.168.0.42')/TCP(sport=6633, dport=6633)/OFPTFeaturesRequest(xid=23) 95s = b'\x01#Eg\x89\xab\x00\x11"3DU\x08\x00E\x00\x000\x00\x01\x00\x00@\x06\xaf\xee\n\x00\x00\x07\xc0\xa8\x00*\x19\xe9\x19\xe9\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x90\x0b\x00\x00\x01\x05\x00\x08\x00\x00\x00\x17' 96assert raw(ofm) == s 97e = Ether(s) 98e.show2() 99e[OFPTFeaturesRequest].xid == 23 100