def test_arp(self): """ ARP """ # # Generate some hosts on the LAN # self.pg1.generate_remote_hosts(11) # # Send IP traffic to one of these unresolved hosts. # expect the generation of an ARP request # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_req(rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4) # # And a dynamic ARP entry for host 1 # dyn_arp = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[1].mac, self.pg1.remote_hosts[1].ip4) dyn_arp.add_vpp_config() # # now we expect IP traffic forwarded # dyn_p = ( Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(dyn_p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_ip(rx[0], self.pg1.local_mac, self.pg1.remote_hosts[1].mac, self.pg0.remote_ip4, self.pg1._remote_hosts[1].ip4) # # And a Static ARP entry for host 2 # static_arp = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[2].mac, self.pg1.remote_hosts[2].ip4, is_static=1) static_arp.add_vpp_config() static_p = ( Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[2].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(static_p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_ip(rx[0], self.pg1.local_mac, self.pg1.remote_hosts[2].mac, self.pg0.remote_ip4, self.pg1._remote_hosts[2].ip4) # # flap the link. dynamic ARPs get flush, statics don't # self.pg1.admin_down() self.pg1.admin_up() self.pg0.add_stream(static_p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_ip(rx[0], self.pg1.local_mac, self.pg1.remote_hosts[2].mac, self.pg0.remote_ip4, self.pg1._remote_hosts[2].ip4) self.pg0.add_stream(dyn_p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_req(rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4) # # Send an ARP request from one of the so-far unlearned remote hosts # p = ( Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1._remote_hosts[3].mac) / ARP(op="who-has", hwsrc=self.pg1._remote_hosts[3].mac, pdst=self.pg1.local_ip4, psrc=self.pg1._remote_hosts[3].ip4)) self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_resp(rx[0], self.pg1.local_mac, self.pg1._remote_hosts[3].mac, self.pg1.local_ip4, self.pg1._remote_hosts[3].ip4) # # VPP should have learned the mapping for the remote host # self.assertTrue( find_nbr(self, self.pg1.sw_if_index, self.pg1._remote_hosts[3].ip4)) # # Fire in an ARP request before the interface becomes IP enabled # self.pg2.generate_remote_hosts(4) p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg2.remote_hosts[3].ip4)) pt = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / Dot1Q(vlan=0) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg2.remote_hosts[3].ip4)) self.send_and_assert_no_replies(self.pg2, p, "interface not IP enabled") # # Make pg2 un-numbered to pg1 # self.pg2.set_unnumbered(self.pg1.sw_if_index) # # We should respond to ARP requests for the unnumbered to address # once an attached route to the source is known # self.send_and_assert_no_replies( self.pg2, p, "ARP req for unnumbered address - no source") attached_host = VppIpRoute( self, self.pg2.remote_hosts[3].ip4, 32, [VppRoutePath("0.0.0.0", self.pg2.sw_if_index)]) attached_host.add_vpp_config() self.pg2.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_resp(rx[0], self.pg2.local_mac, self.pg2.remote_mac, self.pg1.local_ip4, self.pg2.remote_hosts[3].ip4) self.pg2.add_stream(pt) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_resp(rx[0], self.pg2.local_mac, self.pg2.remote_mac, self.pg1.local_ip4, self.pg2.remote_hosts[3].ip4) # # A neighbor entry that has no associated FIB-entry # arp_no_fib = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[4].mac, self.pg1.remote_hosts[4].ip4, is_no_fib_entry=1) arp_no_fib.add_vpp_config() # # check we have the neighbor, but no route # self.assertTrue( find_nbr(self, self.pg1.sw_if_index, self.pg1._remote_hosts[4].ip4)) self.assertFalse(find_route(self, self.pg1._remote_hosts[4].ip4, 32)) # # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2 # from within pg1's subnet # arp_unnum = VppNeighbor(self, self.pg2.sw_if_index, self.pg1.remote_hosts[5].mac, self.pg1.remote_hosts[5].ip4) arp_unnum.add_vpp_config() p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[5].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_ip(rx[0], self.pg2.local_mac, self.pg1.remote_hosts[5].mac, self.pg0.remote_ip4, self.pg1._remote_hosts[5].ip4) # # ARP requests from hosts in pg1's subnet sent on pg2 are replied to # with the unnumbered interface's address as the source # p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg1.remote_hosts[6].ip4)) self.pg2.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_resp(rx[0], self.pg2.local_mac, self.pg2.remote_mac, self.pg1.local_ip4, self.pg1.remote_hosts[6].ip4) # # An attached host route out of pg2 for an undiscovered hosts generates # an ARP request with the unnumbered address as the source # att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32, [VppRoutePath("0.0.0.0", self.pg2.sw_if_index)]) att_unnum.add_vpp_config() p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[7].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_req(rx[0], self.pg2.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[7].ip4) p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg1.remote_hosts[7].ip4)) self.pg2.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_resp(rx[0], self.pg2.local_mac, self.pg2.remote_mac, self.pg1.local_ip4, self.pg1.remote_hosts[7].ip4) # # An attached host route as yet unresolved out of pg2 for an # undiscovered host, an ARP requests begets a response. # att_unnum1 = VppIpRoute( self, self.pg1.remote_hosts[8].ip4, 32, [VppRoutePath("0.0.0.0", self.pg2.sw_if_index)]) att_unnum1.add_vpp_config() p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg1.remote_hosts[8].ip4)) self.pg2.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg2.get_capture(1) self.verify_arp_resp(rx[0], self.pg2.local_mac, self.pg2.remote_mac, self.pg1.local_ip4, self.pg1.remote_hosts[8].ip4) # # Send an ARP request from one of the so-far unlearned remote hosts # with a VLAN0 tag # p = ( Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1._remote_hosts[9].mac) / Dot1Q(vlan=0) / ARP(op="who-has", hwsrc=self.pg1._remote_hosts[9].mac, pdst=self.pg1.local_ip4, psrc=self.pg1._remote_hosts[9].ip4)) self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_resp(rx[0], self.pg1.local_mac, self.pg1._remote_hosts[9].mac, self.pg1.local_ip4, self.pg1._remote_hosts[9].ip4) # # Add a hierachy of routes for a host in the sub-net. # Should still get an ARP resp since the cover is attached # p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1.remote_mac) / ARP(op="who-has", hwsrc=self.pg1.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg1.remote_hosts[10].ip4)) r1 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 30, [ VppRoutePath(self.pg1.remote_hosts[10].ip4, self.pg1.sw_if_index) ]) r1.add_vpp_config() self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_resp(rx[0], self.pg1.local_mac, self.pg1.remote_mac, self.pg1.local_ip4, self.pg1.remote_hosts[10].ip4) r2 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 32, [ VppRoutePath(self.pg1.remote_hosts[10].ip4, self.pg1.sw_if_index) ]) r2.add_vpp_config() self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.verify_arp_resp(rx[0], self.pg1.local_mac, self.pg1.remote_mac, self.pg1.local_ip4, self.pg1.remote_hosts[10].ip4) # # add an ARP entry that's not on the sub-net and so whose # adj-fib fails the refinement check. then send an ARP request # from that source # a1 = VppNeighbor(self, self.pg0.sw_if_index, self.pg0.remote_mac, "100.100.100.50") a1.add_vpp_config() p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, psrc="100.100.100.50", pdst=self.pg0.remote_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for from failed adj-fib") # # ERROR Cases # 1 - don't respond to ARP request for address not within the # interface's sub-net # 1b - nor within the unnumbered subnet # 1c - nor within the subnet of a different interface # p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, pdst="10.10.10.3", psrc=self.pg0.remote_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for non-local destination") self.assertFalse(find_nbr(self, self.pg0.sw_if_index, "10.10.10.3")) p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, pdst="10.10.10.3", psrc=self.pg1.remote_hosts[7].ip4)) self.send_and_assert_no_replies( self.pg0, p, "ARP req for non-local destination - unnum") p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, pdst=self.pg1.local_ip4, psrc=self.pg1.remote_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req diff sub-net") self.assertFalse( find_nbr(self, self.pg0.sw_if_index, self.pg1.remote_ip4)) # # 2 - don't respond to ARP request from an address not within the # interface's sub-net # 2b - to a prxied address # 2c - not within a differents interface's sub-net p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, psrc="10.10.10.3", pdst=self.pg0.local_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for non-local source") p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) / ARP(op="who-has", hwsrc=self.pg2.remote_mac, psrc="10.10.10.3", pdst=self.pg0.local_ip4)) self.send_and_assert_no_replies( self.pg0, p, "ARP req for non-local source - unnum") p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, psrc=self.pg1.remote_ip4, pdst=self.pg0.local_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for non-local source 2c") # # 3 - don't respond to ARP request from an address that belongs to # the router # p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc=self.pg0.remote_mac, psrc=self.pg0.local_ip4, pdst=self.pg0.local_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for non-local source") # # 4 - don't respond to ARP requests that has mac source different # from ARP request HW source # the router # p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP(op="who-has", hwsrc="00:00:00:DE:AD:BE", psrc=self.pg0.remote_ip4, pdst=self.pg0.local_ip4)) self.send_and_assert_no_replies(self.pg0, p, "ARP req for non-local source") # # cleanup # dyn_arp.remove_vpp_config() static_arp.remove_vpp_config() self.pg2.unset_unnumbered(self.pg1.sw_if_index) # need this to flush the adj-fibs self.pg2.unset_unnumbered(self.pg1.sw_if_index) self.pg2.admin_down() self.pg1.admin_down()
def test_bier_head(self): """BIER head""" # # Add a BIER table for sub-domain 0, set 0, and BSL 256 # bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256) bt = VppBierTable(self, bti, 77) bt.add_vpp_config() # # 2 bit positions via two next hops # nh1 = "10.0.0.1" nh2 = "10.0.0.2" ip_route_1 = VppIpRoute(self, nh1, 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(2001)]) ]) ip_route_2 = VppIpRoute(self, nh2, 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(2002)]) ]) ip_route_1.add_vpp_config() ip_route_2.add_vpp_config() bier_route_1 = VppBierRoute( self, bti, 1, [VppRoutePath(nh1, 0xffffffff, labels=[VppMplsLabel(101)])]) bier_route_2 = VppBierRoute( self, bti, 2, [VppRoutePath(nh2, 0xffffffff, labels=[VppMplsLabel(102)])]) bier_route_1.add_vpp_config() bier_route_2.add_vpp_config() # # An imposition object with both bit-positions set # bi = VppBierImp(self, bti, 333, chr(0x3) * 32) bi.add_vpp_config() # # Add a multicast route that will forward into the BIER doamin # route_ing_232_1_1_1 = VppIpMRoute( self, "0.0.0.0", "232.1.1.1", 32, MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, paths=[ VppMRoutePath(self.pg0.sw_if_index, MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), VppMRoutePath(0xffffffff, MRouteItfFlags.MFIB_ITF_FLAG_FORWARD, proto=DpoProto.DPO_PROTO_BIER, bier_imp=bi.bi_index) ]) route_ing_232_1_1_1.add_vpp_config() # # inject an IP packet. We expect it to be BIER encapped and # replicated. # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234)) self.pg0.add_stream([p]) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(2) # # Encap Stack is; eth, MPLS, MPLS, BIER # igp_mpls = rx[0][MPLS] self.assertEqual(igp_mpls.label, 2001) self.assertEqual(igp_mpls.ttl, 64) self.assertEqual(igp_mpls.s, 0) bier_mpls = igp_mpls[MPLS].payload self.assertEqual(bier_mpls.label, 101) self.assertEqual(bier_mpls.ttl, 64) self.assertEqual(bier_mpls.s, 1) self.assertEqual(rx[0][BIER].length, 2) igp_mpls = rx[1][MPLS] self.assertEqual(igp_mpls.label, 2002) self.assertEqual(igp_mpls.ttl, 64) self.assertEqual(igp_mpls.s, 0) bier_mpls = igp_mpls[MPLS].payload self.assertEqual(bier_mpls.label, 102) self.assertEqual(bier_mpls.ttl, 64) self.assertEqual(bier_mpls.s, 1) self.assertEqual(rx[0][BIER].length, 2)
def test_ip_input(self): """ IP Input Exceptions """ # i can't find a way in scapy to construct an IP packet # with a length less than the IP header length # # Packet too short - this is forwarded # p_short = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, len=40) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_expect(self.pg0, p_short * 65, self.pg1) # # Packet too long - this is dropped # p_long = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, len=400) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_assert_no_replies(self.pg0, p_long * 65, "too long") # # bad chksum - this is dropped # p_chksum = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, chksum=400) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_assert_no_replies(self.pg0, p_chksum * 65, "bad checksum") # # bad version - this is dropped # p_ver = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, version=3) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_assert_no_replies(self.pg0, p_ver * 65, "funky version") # # fragment offset 1 - this is dropped # p_frag = ( Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, frag=1) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_assert_no_replies(self.pg0, p_frag * 65, "frag offset") # # TTL expired packet # p_ttl = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=1) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) rx = self.send_and_expect(self.pg0, p_ttl * 65, self.pg0) rx = rx[0] icmp = rx[ICMP] self.assertEqual(icmptypes[icmp.type], "time-exceeded") self.assertEqual(icmpcodes[icmp.type][icmp.code], "ttl-zero-during-transit") self.assertEqual(icmp.src, self.pg0.remote_ip4) self.assertEqual(icmp.dst, self.pg1.remote_ip4) # # MTU exceeded # p_mtu = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=10, flags='DF') / UDP(sport=1234, dport=1234) / Raw('\xa5' * 2000)) self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1500, 0, 0, 0]) rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg0) rx = rx[0] icmp = rx[ICMP] self.assertEqual(icmptypes[icmp.type], "dest-unreach") self.assertEqual(icmpcodes[icmp.type][icmp.code], "fragmentation-needed") self.assertEqual(icmp.src, self.pg0.remote_ip4) self.assertEqual(icmp.dst, self.pg1.remote_ip4) self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [2500, 0, 0, 0]) rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg1) # Reset MTU for subsequent tests self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
def test_ip_load_balance(self): """ IP Load-Balancing """ # # An array of packets that differ only in the destination port # port_ip_pkts = [] port_mpls_pkts = [] # # An array of packets that differ only in the source address # src_ip_pkts = [] src_mpls_pkts = [] for ii in range(65): port_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.1") / UDP(sport=1234, dport=1234 + ii) / Raw('\xa5' * 100)) port_ip_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / port_ip_hdr)) port_mpls_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / MPLS(label=66, ttl=2) / port_ip_hdr)) src_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.%d" % ii) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) src_ip_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / src_ip_hdr)) src_mpls_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / MPLS(label=66, ttl=2) / src_ip_hdr)) route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index), VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index) ]) route_10_0_0_1.add_vpp_config() binding = VppMplsIpBind(self, 66, "10.0.0.1", 32) binding.add_vpp_config() # # inject the packet on pg0 - expect load-balancing across the 2 paths # - since the default hash config is to use IP src,dst and port # src,dst # We are not going to ensure equal amounts of packets across each link, # since the hash algorithm is statistical and therefore this can never # be guaranteed. But wuth 64 different packets we do expect some # balancing. So instead just ensure there is traffic on each link. # self.send_and_expect_load_balancing(self.pg0, port_ip_pkts, [self.pg1, self.pg2]) self.send_and_expect_load_balancing(self.pg0, src_ip_pkts, [self.pg1, self.pg2]) self.send_and_expect_load_balancing(self.pg0, port_mpls_pkts, [self.pg1, self.pg2]) self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts, [self.pg1, self.pg2]) # # change the flow hash config so it's only IP src,dst # - now only the stream with differing source address will # load-balance # self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=0, dport=0) self.send_and_expect_load_balancing(self.pg0, src_ip_pkts, [self.pg1, self.pg2]) self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts, [self.pg1, self.pg2]) self.send_and_expect_one_itf(self.pg0, port_ip_pkts, self.pg2) # # change the flow hash config back to defaults # self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=1, dport=1) # # Recursive prefixes # - testing that 2 stages of load-balancing occurs and there is no # polarisation (i.e. only 2 of 4 paths are used) # port_pkts = [] src_pkts = [] for ii in range(257): port_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(dst="1.1.1.1", src="20.0.0.1") / UDP(sport=1234, dport=1234 + ii) / Raw('\xa5' * 100))) src_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(dst="1.1.1.1", src="20.0.0.%d" % ii) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))) route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32, [ VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index), VppRoutePath(self.pg4.remote_ip4, self.pg4.sw_if_index) ]) route_10_0_0_2.add_vpp_config() route_1_1_1_1 = VppIpRoute(self, "1.1.1.1", 32, [ VppRoutePath("10.0.0.2", 0xffffffff), VppRoutePath("10.0.0.1", 0xffffffff) ]) route_1_1_1_1.add_vpp_config() # # inject the packet on pg0 - expect load-balancing across all 4 paths # self.vapi.cli("clear trace") self.send_and_expect_load_balancing( self.pg0, port_pkts, [self.pg1, self.pg2, self.pg3, self.pg4]) self.send_and_expect_load_balancing( self.pg0, src_pkts, [self.pg1, self.pg2, self.pg3, self.pg4]) # # Recursive prefixes # - testing that 2 stages of load-balancing, no choices # port_pkts = [] for ii in range(257): port_pkts.append( (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(dst="1.1.1.2", src="20.0.0.2") / UDP(sport=1234, dport=1234 + ii) / Raw('\xa5' * 100))) route_10_0_0_3 = VppIpRoute( self, "10.0.0.3", 32, [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)]) route_10_0_0_3.add_vpp_config() route_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32, [VppRoutePath("10.0.0.3", 0xffffffff)]) route_1_1_1_2.add_vpp_config() # # inject the packet on pg0 - expect load-balancing across all 4 paths # self.vapi.cli("clear trace") self.send_and_expect_one_itf(self.pg0, port_pkts, self.pg3)
def test_flood(self): """ L2 Flood Tests """ # # Create a single bridge Domain # self.vapi.bridge_domain_add_del(bd_id=1) # # add each interface to the BD. 3 interfaces per split horizon group # for i in self.pg_interfaces[0:4]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0) for i in self.pg_interfaces[4:8]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=1) for i in self.pg_interfaces[8:12]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2) for i in self.bvi_interfaces: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2, port_type=L2_PORT_TYPE.BVI) p = (Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef") / IP(src="10.10.10.10", dst="1.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) # # input on pg0 expect copies on pg1->11 # this is in SHG=0 so its flooded to all, expect the pg0 since that's # the ingress link # self.pg0.add_stream(p * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:12]: rx0 = i.get_capture(65, timeout=1) # # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0) # and pg8->11 (SHG=2) # self.pg4.add_stream(p * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[:4]: rx0 = i.get_capture(65, timeout=1) for i in self.pg_interfaces[8:12]: rx0 = i.get_capture(65, timeout=1) for i in self.pg_interfaces[4:8]: i.assert_nothing_captured(remark="Different SH group") # # An IP route so the packet that hits the BVI is sent out of pg12 # ip_route = VppIpRoute( self, "1.1.1.1", 32, [VppRoutePath(self.pg12.remote_ip4, self.pg12.sw_if_index)]) ip_route.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) # # input on pg0 expect copies on pg1->12 # this is in SHG=0 so its flooded to all, expect the pg0 since that's # the ingress link # self.pg0.add_stream(p * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:]: rx0 = i.get_capture(65, timeout=1) # # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0) # and pg8->12 (SHG=2) # self.pg4.add_stream(p * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[:4]: rx0 = i.get_capture(65, timeout=1) for i in self.pg_interfaces[8:13]: rx0 = i.get_capture(65, timeout=1) for i in self.pg_interfaces[4:8]: i.assert_nothing_captured(remark="Different SH group") # # cleanup # for i in self.pg_interfaces[:12]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0) for i in self.bvi_interfaces: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2, port_type=L2_PORT_TYPE.BVI, enable=0) self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
def __init__(self): base_pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67,chksum=0) \ /BOOTP(chaddr=b'123456',xid=55555,yiaddr='1.2.3.4')/DHCP(options=[("message-type","discover"), ("server_id", '1.2.3.4'),"end"]) FastParser.__init__(self, base_pkt) self.add_field('Ethernet.dst', 'dstmac') self.add_field('Ethernet.src', 'srcmac') self.add_field('IP.ihl', 'ihl', fmt="!B") self.add_field('IP.dst', 'dstip') self.add_field('IP.src', 'srcip') self.add_field('IP.chksum', 'chksum') self.add_field('BOOTP.xid', 'xid') self.add_field('BOOTP.chaddr', 'chaddr') self.add_field('BOOTP.ciaddr', 'ciaddr') self.add_field('BOOTP.yiaddr', 'yiaddr') self.add_field('DHCP options.options', 'options', getter=self.get_options, setter=self.set_options) msg_types = [ { 'id': 1, 'name': 'discover' }, { 'id': 2, 'name': 'offer' }, { 'id': 3, 'name': 'request' }, ] self.msg_types = {} for t in msg_types: self.msg_types[t['id']] = t self.msg_types[t['name']] = t opts = [ { 'id': 53, 'name': 'message-type', 'type': 'byte' }, { 'id': 54, 'name': 'server_id', 'type': 'int' }, { 'id': 50, 'name': 'requested_addr', 'type': 'int' }, { 'id': 51, 'name': 'lease-time', 'type': 'int' }, { 'id': 58, 'name': 'renewal_time', 'type': 'int' }, { 'id': 59, 'name': 'rebinding_time', 'type': 'int' }, { 'id': 1, 'name': 'subnet_mask', 'type': 'int' }, { 'id': 15, 'name': 'domain', 'type': 'str' }, ] self.opts = {} for opt in opts: self.opts[opt['id']] = opt self.opts[opt['name']] = opt
def test_qos_ip(self): """ QoS Mark/Record IP """ # # for table 1 map the n=0xff possible values of input QoS mark, # n to 1-n # output = [scapy.compat.chb(0)] * 256 for i in range(0, 255): output[i] = scapy.compat.chb(255 - i) os = b''.join(output) rows = [{ 'outputs': os }, { 'outputs': os }, { 'outputs': os }, { 'outputs': os }] self.vapi.qos_egress_map_update(1, rows) # # For table 2 (and up) use the value n for everything # output = [scapy.compat.chb(2)] * 256 os = b''.join(output) rows = [{ 'outputs': os }, { 'outputs': os }, { 'outputs': os }, { 'outputs': os }] self.vapi.qos_egress_map_update(2, rows) output = [scapy.compat.chb(3)] * 256 os = b''.join(output) rows = [{ 'outputs': os }, { 'outputs': os }, { 'outputs': os }, { 'outputs': os }] self.vapi.qos_egress_map_update(3, rows) output = [scapy.compat.chb(4)] * 256 os = b''.join(output) rows = [{ 'outputs': os }, { 'outputs': os }, { 'outputs': os }, { 'outputs': os }] self.vapi.qos_egress_map_update(4, rows) self.vapi.qos_egress_map_update(5, rows) self.vapi.qos_egress_map_update(6, rows) self.vapi.qos_egress_map_update(7, rows) self.logger.info(self.vapi.cli("sh qos eg map")) # # Bind interface pgN to table n # self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 1) self.vapi.qos_mark_enable_disable(self.pg2.sw_if_index, QOS_SOURCE.IP, 2, 1) self.vapi.qos_mark_enable_disable(self.pg3.sw_if_index, QOS_SOURCE.IP, 3, 1) self.vapi.qos_mark_enable_disable(self.pg4.sw_if_index, QOS_SOURCE.IP, 4, 1) # # packets ingress on Pg0 # p_v4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) p_v6 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6, tc=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) # # Since we have not yet enabled the recording of the input QoS # from the input iP header, the egress packet's ToS will be unchanged # rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 1) rx = self.send_and_expect(self.pg0, p_v6 * 65, self.pg1) for p in rx: self.assertEqual(p[IPv6].tc, 1) # # Enable QoS recording on IP input for pg0 # self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.IP, 1) # # send the same packets, this time expect the input TOS of 1 # to be mapped to pg1's egress value of 254 # rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 254) rx = self.send_and_expect(self.pg0, p_v6 * 65, self.pg1) for p in rx: self.assertEqual(p[IPv6].tc, 254) # # different input ToS to test the mapping # p_v4[IP].tos = 127 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 128) p_v6[IPv6].tc = 127 rx = self.send_and_expect(self.pg0, p_v6 * 65, self.pg1) for p in rx: self.assertEqual(p[IPv6].tc, 128) p_v4[IP].tos = 254 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 1) p_v6[IPv6].tc = 254 rx = self.send_and_expect(self.pg0, p_v6 * 65, self.pg1) for p in rx: self.assertEqual(p[IPv6].tc, 1) # # send packets out the other interfaces to test the maps are # correctly applied # p_v4[IP].dst = self.pg2.remote_ip4 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg2) for p in rx: self.assertEqual(p[IP].tos, 2) p_v4[IP].dst = self.pg3.remote_ip4 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg3) for p in rx: self.assertEqual(p[IP].tos, 3) p_v6[IPv6].dst = self.pg3.remote_ip6 rx = self.send_and_expect(self.pg0, p_v6 * 65, self.pg3) for p in rx: self.assertEqual(p[IPv6].tc, 3) # # remove the map on pg2 and pg3, now expect an unchanged IP tos # self.vapi.qos_mark_enable_disable(self.pg2.sw_if_index, QOS_SOURCE.IP, 2, 0) self.vapi.qos_mark_enable_disable(self.pg3.sw_if_index, QOS_SOURCE.IP, 3, 0) self.logger.info(self.vapi.cli("sh int feat pg2")) p_v4[IP].dst = self.pg2.remote_ip4 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg2) for p in rx: self.assertEqual(p[IP].tos, 254) p_v4[IP].dst = self.pg3.remote_ip4 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg3) for p in rx: self.assertEqual(p[IP].tos, 254) # # still mapping out of pg1 # p_v4[IP].dst = self.pg1.remote_ip4 rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 1) # # disable the input recording on pg0 # self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.IP, 0) # # back to an unchanged TOS value # rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 254) # # disable the egress map on pg1 and pg4 # self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 0) self.vapi.qos_mark_enable_disable(self.pg4.sw_if_index, QOS_SOURCE.IP, 4, 0) # # unchanged Tos on pg1 # rx = self.send_and_expect(self.pg0, p_v4 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 254) # # clean-up the map # self.vapi.qos_egress_map_delete(1) self.vapi.qos_egress_map_delete(4) self.vapi.qos_egress_map_delete(2) self.vapi.qos_egress_map_delete(3) self.vapi.qos_egress_map_delete(5) self.vapi.qos_egress_map_delete(6) self.vapi.qos_egress_map_delete(7)
def getIPv6Flow(self, id): return (IPv6(dst="2001::%u" % (id), src="fd00:f00d:ffff::%u" % (id)) / UDP(sport=10000 + id, dport=20000 + id))
def test_qos_mpls(self): """ QoS Mark/Record MPLS """ # # 255 QoS for all input values # from_ext = 7 from_ip = 6 from_mpls = 5 from_vlan = 4 output = [scapy.compat.chb(from_ext)] * 256 os1 = b''.join(output) output = [scapy.compat.chb(from_vlan)] * 256 os2 = b''.join(output) output = [scapy.compat.chb(from_mpls)] * 256 os3 = b''.join(output) output = [scapy.compat.chb(from_ip)] * 256 os4 = b''.join(output) rows = [{ 'outputs': os1 }, { 'outputs': os2 }, { 'outputs': os3 }, { 'outputs': os4 }] self.vapi.qos_egress_map_update(1, rows) # # a route with 1 MPLS label # route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32, [ VppRoutePath( self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[32]) ]) route_10_0_0_1.add_vpp_config() # # a route with 3 MPLS labels # route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32, [ VppRoutePath( self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[63, 33, 34]) ]) route_10_0_0_3.add_vpp_config() # # enable IP QoS recording on the input Pg0 and MPLS egress marking # on Pg1 # self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.IP, 1) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.MPLS, 1, 1) # # packet that will get one label added and 3 labels added resp. # p_1 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) p_3 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst="10.0.0.3", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) rx = self.send_and_expect(self.pg0, p_1 * 65, self.pg1) # # only 3 bits of ToS value in MPLS make sure tos is correct # and the label and EOS bit have not been corrupted # for p in rx: self.assertEqual(p[MPLS].cos, from_ip) self.assertEqual(p[MPLS].label, 32) self.assertEqual(p[MPLS].s, 1) rx = self.send_and_expect(self.pg0, p_3 * 65, self.pg1) for p in rx: self.assertEqual(p[MPLS].cos, from_ip) self.assertEqual(p[MPLS].label, 63) self.assertEqual(p[MPLS].s, 0) h = p[MPLS].payload self.assertEqual(h[MPLS].cos, from_ip) self.assertEqual(h[MPLS].label, 33) self.assertEqual(h[MPLS].s, 0) h = h[MPLS].payload self.assertEqual(h[MPLS].cos, from_ip) self.assertEqual(h[MPLS].label, 34) self.assertEqual(h[MPLS].s, 1) # # enable MPLS QoS recording on the input Pg0 and IP egress marking # on Pg1 # self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.MPLS, 1) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 1) # # MPLS x-connect - COS according to pg1 map # route_32_eos = VppMplsRoute(self, 32, 1, [ VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(33)]) ]) route_32_eos.add_vpp_config() p_m1 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / MPLS(label=32, cos=3, ttl=2) / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) rx = self.send_and_expect(self.pg0, p_m1 * 65, self.pg1) for p in rx: self.assertEqual(p[MPLS].cos, from_mpls) self.assertEqual(p[MPLS].label, 33) self.assertEqual(p[MPLS].s, 1) # # MPLS deag - COS is copied from MPLS to IP # route_33_eos = VppMplsRoute( self, 33, 1, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=0)]) route_33_eos.add_vpp_config() route_10_0_0_4 = VppIpRoute( self, "10.0.0.4", 32, [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)]) route_10_0_0_4.add_vpp_config() p_m2 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / MPLS(label=33, ttl=2, cos=3) / IP(src=self.pg0.remote_ip4, dst="10.0.0.4", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) rx = self.send_and_expect(self.pg0, p_m2 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, from_mpls) # # cleanup # self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.IP, 0) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.MPLS, 1, 0) self.vapi.qos_record_enable_disable(self.pg0.sw_if_index, QOS_SOURCE.MPLS, 0) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 0) self.vapi.qos_egress_map_delete(1)
def test_qos_vlan(self): """QoS mark/record VLAN """ # # QoS for all input values # output = [scapy.compat.chb(0)] * 256 for i in range(0, 255): output[i] = scapy.compat.chb(255 - i) os = b''.join(output) rows = [{ 'outputs': os }, { 'outputs': os }, { 'outputs': os }, { 'outputs': os }] self.vapi.qos_egress_map_update(1, rows) sub_if = VppDot1QSubint(self, self.pg0, 11) sub_if.admin_up() sub_if.config_ip4() sub_if.resolve_arp() sub_if.config_ip6() sub_if.resolve_ndp() # # enable VLAN QoS recording/marking on the input Pg0 subinterface and # self.vapi.qos_record_enable_disable(sub_if.sw_if_index, QOS_SOURCE.VLAN, 1) self.vapi.qos_mark_enable_disable(sub_if.sw_if_index, QOS_SOURCE.VLAN, 1, 1) # # IP marking/recording on pg1 # self.vapi.qos_record_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 1) # # a routes to/from sub-interface # route_10_0_0_1 = VppIpRoute( self, "10.0.0.1", 32, [VppRoutePath(sub_if.remote_ip4, sub_if.sw_if_index)]) route_10_0_0_1.add_vpp_config() route_10_0_0_2 = VppIpRoute( self, "10.0.0.2", 32, [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)]) route_10_0_0_2.add_vpp_config() route_2001_1 = VppIpRoute( self, "2001::1", 128, [ VppRoutePath(sub_if.remote_ip6, sub_if.sw_if_index, proto=DpoProto.DPO_PROTO_IP6) ], is_ip6=1) route_2001_1.add_vpp_config() route_2001_2 = VppIpRoute( self, "2001::2", 128, [ VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index, proto=DpoProto.DPO_PROTO_IP6) ], is_ip6=1) route_2001_2.add_vpp_config() p_v1 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / Dot1Q(vlan=11, prio=1) / IP(src="1.1.1.1", dst="10.0.0.2", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) p_v2 = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(src="1.1.1.1", dst="10.0.0.1", tos=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) rx = self.send_and_expect(self.pg1, p_v2 * 65, self.pg0) for p in rx: self.assertEqual(p[Dot1Q].prio, 6) rx = self.send_and_expect(self.pg0, p_v1 * 65, self.pg1) for p in rx: self.assertEqual(p[IP].tos, 254) p_v1 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / Dot1Q(vlan=11, prio=2) / IPv6(src="2001::1", dst="2001::2", tc=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) p_v2 = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IPv6(src="3001::1", dst="2001::1", tc=1) / UDP(sport=1234, dport=1234) / Raw(scapy.compat.chb(100) * 65)) rx = self.send_and_expect(self.pg1, p_v2 * 65, self.pg0) for p in rx: self.assertEqual(p[Dot1Q].prio, 6) rx = self.send_and_expect(self.pg0, p_v1 * 65, self.pg1) for p in rx: self.assertEqual(p[IPv6].tc, 253) # # cleanup # sub_if.unconfig_ip4() sub_if.unconfig_ip6() self.vapi.qos_record_enable_disable(sub_if.sw_if_index, QOS_SOURCE.VLAN, 0) self.vapi.qos_mark_enable_disable(sub_if.sw_if_index, QOS_SOURCE.VLAN, 1, 0) self.vapi.qos_record_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 0) self.vapi.qos_mark_enable_disable(self.pg1.sw_if_index, QOS_SOURCE.IP, 1, 0)
def dhcp_request(iface=None,**kargs): if conf.checkIPaddr != 0: warning("conf.checkIPaddr is not 0, I may not be able to match the answer") if iface is None: iface = conf.iface fam,hw = get_if_raw_hwaddr(iface) return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67) /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
def main(): parser = OptionParser(usage="""%prog [options] <src> <dst> src : Source ethernet interface. Ex: eth0 dst : Destination ethernet interface. Ex: eth1 """) parser.add_option("-c", "--criteria", help=""" Load balance criteria: src-mac, dst-mac, src-dst-mac, src-ip, dst-ip, src-dst-ip, mpls-top-sec, mpls-top, mpls-sec, src-tcp, dst-tcp, src-dst-tcp, src-udp, dst-udp, src-dst-udp """, default="src-dst-mac", action="store", type="string", dest="criteria") parser.add_option("-i", "--interval", help="Define packet interval in milliseconds.", default=100, action="store", type="int", dest="interval") parser.add_option( "-n", "--num_packets", help="Send specified number of packets. Default: send indefinitely.", default=0, action="store", type="int", dest="num_packets") parser.add_option("-d", "--debug", help="Enable L2tester debuging.", default=False, action="store_true", dest="debug") (options, args) = parser.parse_args() if len(args) < 2: parser.error("must specify interfaces to use") if options.debug: l2tester.Logger.config_log_level(l2tester.Logger.L2T_LOG_DEBUG) if options.criteria not in [ "dst-ip", "dst-mac", "src-dst-ip", "src-dst-mac", "src-ip", "src-mac", "src-udp", "dst-udp", "src-dst-udp", "src-tcp", "dst-tcp", "src-dst-tcp", "mpls-top-sec", "mpls-top", "mpls-sec" ]: parser.error("invalid criteria '{0}'".format(options.criteria)) if_src = args[0] if_dst = args[1] try: if_src_action = l2tester.Action() if_src_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_action.seed = 10 if_src_filter = l2tester.EthernetFilter() if_dst_action = l2tester.Action() if_dst_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_action.seed = 10 if_dst_filter = l2tester.EthernetFilter() if 'udp' in options.criteria: if_src_action.mask = 0xFFFF000000000000 if_src_action.range_first = 1 if_src_action.range_last = 0x03FF # Port 1023 if_src_filter.dst_mac = '10:00:01:02:03:FF' if_src_filter.compile() if_src_packet = Ether( src='10:00:01:02:03:04', dst='10:00:01:02:03:FF') / IP( src='192.168.42.01', dst='192.168.42.02') / UDP( sport=18, dport=50) / Raw('\0' * 100) if_dst_action.mask = 0xFFFF000000000000 if_dst_action.range_first = 1 if_dst_action.range_last = 0x03FF # Port 1023 if_dst_filter.src_mac = '10:00:01:02:03:FF' if_dst_filter.compile() if_dst_packet = Ether( src='10:00:01:02:03:FF', dst='10:00:01:02:03:04') / IP( src='192.168.42.02', dst='192.168.42.01') / UDP( sport=50, dport=18) / Raw('\0' * 100) if options.criteria == 'src-dst-udp': # Source Interface generate random source and destination UDP port if_src_extra_action = l2tester.Action() if_src_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_extra_action.mask = 0xFFFF000000000000 if_src_extra_action.byte = 34 # Source UDP port if_src_extra_action.range_first = 1 if_src_extra_action.range_last = 0x03FF # Port 1023 if_src_action.byte = 36 # Destination UDP port if_src_action.chain_action(if_src_extra_action) # Destination Interface generate random source and destination UDP port (but seeds are inverted) if_dst_extra_action = l2tester.Action() if_dst_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_extra_action.mask = 0xFFFF000000000000 if_dst_extra_action.byte = 36 # Destination UDP port if_dst_extra_action.range_first = 1 if_dst_extra_action.range_last = 0x03FF # Port 1023 if_dst_action.byte = 34 # Source UDP port if_dst_action.chain_action(if_dst_extra_action) elif options.criteria == 'src-udp': if_src_action.byte = 34 if_dst_action.byte = 36 else: # options.criteria == 'dst-udp': if_src_action.byte = 36 if_dst_action.byte = 34 if 'tcp' in options.criteria: if_src_action.mask = 0xFFFF000000000000 if_src_action.range_first = 1 if_src_action.range_last = 0x03FF # Port 1023 if_src_filter.dst_mac = '10:00:01:02:03:FF' if_src_filter.compile() if_src_packet = Ether( src='10:00:01:02:03:04', dst='10:00:01:02:03:FF') / IP( src='192.168.42.01', dst='192.168.42.02') / TCP( sport=21, dport=57) / Raw('\0' * 100) if_dst_action.mask = 0xFFFF000000000000 if_dst_action.range_first = 1 if_dst_action.range_last = 0x03FF # Port 1023 if_dst_filter.src_mac = '10:00:01:02:03:FF' if_dst_filter.compile() if_dst_packet = Ether( src='10:00:01:02:03:FF', dst='10:00:01:02:03:04') / IP( src='192.168.42.02', dst='192.168.42.01') / TCP( sport=57, dport=21) / Raw('\0' * 100) if options.criteria == 'src-dst-tcp': # Source Interface generate random source and destination UDP port if_src_extra_action = l2tester.Action() if_src_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_extra_action.mask = 0xFFFF000000000000 if_src_extra_action.byte = 34 # Source TCP port if_src_extra_action.range_first = 1 if_src_extra_action.range_last = 0x03FF # Port 1023 if_src_action.byte = 36 # Destination TCP port if_src_action.chain_action(if_src_extra_action) # Destination Interface generate random source and destination TCP port (but seeds are inverted) if_dst_extra_action = l2tester.Action() if_dst_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_extra_action.mask = 0xFFFF000000000000 if_dst_extra_action.byte = 36 # Destination TCP port if_dst_extra_action.range_first = 1 if_dst_extra_action.range_last = 0x03FF # Port 1023 if_dst_action.byte = 34 # Source TCP port if_dst_action.chain_action(if_dst_extra_action) elif options.criteria == 'src-tcp': if_src_action.byte = 34 if_dst_action.byte = 36 else: # options.criteria == 'dst-tcp' if_src_action.byte = 36 if_dst_action.byte = 34 if 'ip' in options.criteria: checksum_action = l2tester.Action() checksum_action.byte = 24 checksum_action.type = l2tester.Action.ACTION_IPV4_CHECKSUM if_src_action.mask = 0xFFFFFFFF00000000 if_src_action.range_first = 1 if_src_action.range_last = 0xE0000000 # Create random IPs smaller than first multicast 224.0.0.0 if_src_filter.dst_mac = '10:00:01:02:03:FF' if_src_filter.compile() if_src_packet = Ether( src='10:00:01:02:03:04', dst='10:00:01:02:03:FF') / IP( src='192.168.42.01', dst='192.168.42.02') / Raw('\0' * 100) if_dst_action.mask = 0xFFFFFFFF00000000 if_dst_action.range_first = 1 if_dst_action.range_last = 0xE0000000 # Create random IPs smaller than first multicast 224.0.0.0 if_dst_filter.src_mac = '10:00:01:02:03:FF' if_dst_filter.compile() if_dst_packet = Ether( src='10:00:01:02:03:FF', dst='10:00:01:02:03:04') / IP( src='192.168.42.02', dst='192.168.42.01') / Raw('\0' * 100) if options.criteria == 'src-dst-ip': # Source Interface generate random source and destination IP if_src_extra_action = l2tester.Action() if_src_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_extra_action.mask = 0xFFFFFFFF00000000 if_src_extra_action.byte = 26 # Source IP if_src_extra_action.range_first = 1 if_src_extra_action.range_last = 0xE0000000 # Create random IPs smaller than first multicast 224.0.0.0 if_src_extra_action.chain_action(checksum_action) if_src_action.byte = 30 # Destination IP if_src_action.chain_action(if_src_extra_action) # Destination Interface generate random source and destination IP (but seeds are inverted) if_dst_extra_action = l2tester.Action() if_dst_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_extra_action.mask = 0xFFFFFFFF00000000 if_dst_extra_action.byte = 30 # Destination IP if_dst_extra_action.range_first = 1 if_dst_extra_action.range_last = 0xE0000000 # Create random IPs smaller than first multicast 224.0.0.0 if_dst_extra_action.chain_action(checksum_action) if_dst_action.byte = 26 # Source IP if_dst_action.chain_action(if_dst_extra_action) else: # For single IP, chain action directly to checksum. if_src_action.chain_action(checksum_action) if_dst_action.chain_action(checksum_action) if options.criteria == 'dst-ip': if_src_action.byte = 30 # Destination IP if_dst_action.byte = 26 # Source IP elif options.criteria == 'src-ip': if_src_action.byte = 26 # Source IP if_dst_action.byte = 30 # Destination IP if 'mpls' in options.criteria: if_src_action.mask = 0xFFFFF00000000000 if_src_action.range_first = 16 # Labels 0 to 15 are reserved. if_src_action.range_last = 0xFFFFF #Last valid label (2^20 - 1). if_src_filter.dst_mac = '10:00:01:02:03:FF' if_src_filter.compile() if_src_packet = Ether( src='10:00:01:02:03:04', dst='10:00:01:02:03:FF') / MPLS(s=0) / MPLS() / IP( src='192.168.42.01', dst='192.168.42.02') / ICMP() / Raw( '\0' * 100) if_dst_action.mask = 0xFFFFF00000000000 if_dst_action.range_first = 0x10 # Labels 0 to 15 are reserved. if_dst_action.range_last = 0xFFFFF # Last valid label (2^20 - 1). if_dst_filter.src_mac = '10:00:01:02:03:FF' if_dst_filter.compile() if_dst_packet = Ether( src='10:00:01:02:03:FF', dst='10:00:01:02:03:04') / MPLS(s=0) / MPLS() / IP( src='192.168.42.02', dst='192.168.42.01') / ICMP() / Raw( '\0' * 100) if options.criteria == 'mpls-top-sec': # Source Interface generates random MPLS top and second labels if_src_extra_action = l2tester.Action() if_src_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_extra_action.mask = 0xFFFFF00000000000 if_src_extra_action.byte = 14 # Top label if_src_extra_action.range_first = 0x10 # Labels 0 to 15 are reserved. if_src_extra_action.range_last = 0xFFFFF # Last valid label (2^20 - 1). if_src_action.byte = 18 # Second label if_src_action.chain_action(if_src_extra_action) # Destination Interface generates random MPLS top and second labels if_dst_extra_action = l2tester.Action() if_dst_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_extra_action.mask = 0xFFFFF00000000000 if_dst_extra_action.byte = 14 # Top label if_dst_extra_action.range_first = 0x10 # Labels 0 to 15 are reserved. if_dst_extra_action.range_last = 0xFFFFF # Last valid label (2^20 - 1). if_dst_action.byte = 18 # Second label if_dst_action.chain_action(if_dst_extra_action) elif options.criteria == 'mpls-top': if_src_action.byte = 14 if_dst_action.byte = 14 else: # options.criteria == 'mpls-sec': if_src_action.byte = 18 if_dst_action.byte = 18 if 'mac' in options.criteria: if_src_action.mask = 0xFEFFFFFFFFFF0000 if_src_filter.outer_tpid = 0x5010 if_src_filter.compile() if_src_packet = Ether(src='10:00:01:02:03:01', dst='10:00:01:02:03:02', type=0x5010) / Raw('\0' * 100) if_dst_action.mask = 0xFEFFFFFFFFFF0000 if_dst_filter.outer_tpid = 0x5011 if_dst_filter.compile() if_dst_packet = Ether(src='10:00:01:02:03:02', dst='10:00:01:02:03:01', type=0x5011) / Raw('\0' * 100) if options.criteria == 'src-dst-mac': # Source Interface generate random source and destination MAC if_src_extra_action = l2tester.Action() if_src_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_src_extra_action.mask = 0xFEFFFFFFFFFF0000 if_src_extra_action.byte = 6 # Source MAC if_src_action.byte = 0 # Destination MAC if_src_action.chain_action(if_src_extra_action) # Destination Interface generate random source and destination MAC (but seeds are inverted) if_dst_extra_action = l2tester.Action() if_dst_extra_action.type = l2tester.Action.ACTION_RANDOMIZE if_dst_extra_action.mask = 0xFEFFFFFFFFFF0000 if_dst_extra_action.byte = 0 # Destination MAC if_dst_action.byte = 6 # Source MAC if_dst_action.chain_action(if_dst_extra_action) elif options.criteria == 'dst-mac': if_src_action.byte = 0 # Destination MAC if_dst_action.byte = 6 # Source MAC else: # options.criteria == 'src-mac' if_src_action.byte = 6 # Destination MAC if_dst_action.byte = 0 # Source MAC src_to_dst_monitor = l2tester.TrafficFlow_Monitor( if_src, if_dst, str(if_src_packet), options.interval, if_src_action, if_src_filter) if options.num_packets: # Limited Mode try: sys.stdout.write("Learning MACs... ") dst_to_src_monitor = l2tester.TrafficFlow_Monitor( if_dst, if_src, str(if_dst_packet), options.interval, if_dst_action, if_dst_filter) dst_to_src_monitor.run( options.num_packets if 'mac' in options.criteria else 1 ) #Send more than one packet on the other direction only if criteria is by MAC check_monitor_errors(dst_to_src_monitor) sys.stdout.write("OK!\n") sys.stdout.write("Sending random stream... ") src_to_dst_monitor.run(options.num_packets) check_monitor_errors(src_to_dst_monitor) sys.stdout.write("OK!\n") except Exception as e: sys.stdout.write(str(e) + "\n") return else: # Unlimited Mode # Inverted stream is defined as simple sender (and not as monitor) because it will operate concurrently with monitored stream. dst_to_src_sender = l2tester.Sender(if_dst, str(if_dst_packet)) dst_to_src_sender.set_action(if_dst_action) dst_to_src_sender.manual_bandwidth(1, 1000000 * options.interval) dst_to_src_sender.start() print """ =============================================================================== Timestamp (ms) | Delta (ms) | Event -------------------------------------------------------------------------------""" last_event_ms = 0 src_to_dst_monitor.start() while True: try: event = src_to_dst_monitor.iterate_event(0, True, 1000) if event: print " {0:>16} | {1:>16} | {2}".format( event.timestamp_ms, event.timestamp_ms - last_event_ms, l2tester.TrafficFlow_Event.type_to_str(event.type)) last_event_ms = event.timestamp_ms if event.type == l2tester.TrafficFlow_Event.TEST_FINISHED: break except KeyboardInterrupt: src_to_dst_monitor.stop() dst_to_src_sender.stop() stats = l2tester.TrafficFlow_Statistics() src_to_dst_monitor.get_statistics(stats) print """ =============================================================================== Traffic Interruption Total : {0} ms Intervals : {1} Loop Detection Total : {2} ms Intervals : {3} Packets Sent : {4} Received : {5} Dropped : {6} {7} =============================================================================== """.format(stats.traffic_interruption_ms, stats.traffic_interruption_intervals, stats.loop_detected_ms, stats.loop_detected_intervals, stats.sent_packets, stats.received_packets, stats.dropped_packets, " ** MONITOR ABORTED **" if stats.error_detected else "") except Exception as e: print e
def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes, is_ip6, expect_blocked, expect_established, add_extension_header, icmp_stateful=False): pkts = [] rules = [] permit_rules = [] permit_and_reflect_rules = [] total_packet_count = 8 for i in range(0, total_packet_count): modulo = (i // 2) % 2 icmp_type_delta = i % 2 icmp_code = i is_udp_packet = (modulo == 0) if is_udp_packet and icmp_stateful: continue is_reflectable_icmp = (icmp_stateful and icmp_type_delta == 0 and not is_udp_packet) is_reflected_icmp = is_reflectable_icmp and expect_established can_reflect_this_packet = is_udp_packet or is_reflectable_icmp is_permit = i % 2 remote_dst_index = i % len(dst_ip_if.remote_hosts) remote_dst_host = dst_ip_if.remote_hosts[remote_dst_index] if is_permit == 1: info = self.create_packet_info(src_ip_if, dst_ip_if) payload = self.info_to_payload(info) else: to_be_blocked = False if (expect_blocked and not expect_established): to_be_blocked = True if (not can_reflect_this_packet): to_be_blocked = True if to_be_blocked: payload = "to be blocked" else: info = self.create_packet_info(src_ip_if, dst_ip_if) payload = self.info_to_payload(info) if reverse: dst_mac = 'de:ad:00:00:00:00' src_mac = remote_dst_host._mac dst_ip6 = src_ip_if.remote_ip6 src_ip6 = remote_dst_host.ip6 dst_ip4 = src_ip_if.remote_ip4 src_ip4 = remote_dst_host.ip4 dst_l4 = 1234 + i src_l4 = 4321 + i else: dst_mac = src_ip_if.local_mac src_mac = src_ip_if.remote_mac src_ip6 = src_ip_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 src_ip4 = src_ip_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 src_l4 = 1234 + i dst_l4 = 4321 + i if is_reflected_icmp: icmp_type_delta = 1 # default ULP should be something we do not use in tests ulp_l4 = TCP(sport=src_l4, dport=dst_l4) # potentially a chain of protocols leading to ULP ulp = ulp_l4 if is_udp_packet: if is_ip6: ulp_l4 = UDP(sport=src_l4, dport=dst_l4) if add_extension_header: # prepend some extension headers ulp = (IPv6ExtHdrRouting() / IPv6ExtHdrRouting() / IPv6ExtHdrFragment(offset=0, m=1) / ulp_l4) # uncomment below to test invalid ones # ulp = IPv6ExtHdrRouting(len = 200) / ulp_l4 else: ulp = ulp_l4 p = (Ether(dst=dst_mac, src=src_mac) / IPv6(src=src_ip6, dst=dst_ip6) / ulp / Raw(payload)) else: ulp_l4 = UDP(sport=src_l4, dport=dst_l4) # IPv4 does not allow extension headers, # but we rather make it a first fragment flags = 1 if add_extension_header else 0 ulp = ulp_l4 p = (Ether(dst=dst_mac, src=src_mac) / IP(src=src_ip4, dst=dst_ip4, frag=0, flags=flags) / ulp / Raw(payload)) elif modulo == 1: if is_ip6: ulp_l4 = ICMPv6Unknown(type=128 + icmp_type_delta, code=icmp_code) ulp = ulp_l4 p = (Ether(dst=dst_mac, src=src_mac) / IPv6(src=src_ip6, dst=dst_ip6) / ulp / Raw(payload)) else: ulp_l4 = ICMP(type=8 - 8 * icmp_type_delta, code=icmp_code) ulp = ulp_l4 p = (Ether(dst=dst_mac, src=src_mac) / IP(src=src_ip4, dst=dst_ip4) / ulp / Raw(payload)) if i % 2 == 1: info.data = p.copy() size = packet_sizes[(i // 2) % len(packet_sizes)] self.extend_packet(p, size) pkts.append(p) rule_family = AF_INET6 if p.haslayer(IPv6) else AF_INET rule_prefix_len = 128 if p.haslayer(IPv6) else 32 rule_l3_layer = IPv6 if p.haslayer(IPv6) else IP if p.haslayer(UDP): rule_l4_sport = p[UDP].sport rule_l4_dport = p[UDP].dport else: if p.haslayer(ICMP): rule_l4_sport = p[ICMP].type rule_l4_dport = p[ICMP].code else: rule_l4_sport = p[ICMPv6Unknown].type rule_l4_dport = p[ICMPv6Unknown].code if p.haslayer(IPv6): rule_l4_proto = ulp_l4.overload_fields[IPv6]['nh'] else: rule_l4_proto = p[IP].proto new_rule = { 'is_permit': is_permit, 'is_ipv6': p.haslayer(IPv6), 'src_ip_addr': inet_pton(rule_family, p[rule_l3_layer].src), 'src_ip_prefix_len': rule_prefix_len, 'dst_ip_addr': inet_pton(rule_family, p[rule_l3_layer].dst), 'dst_ip_prefix_len': rule_prefix_len, 'srcport_or_icmptype_first': rule_l4_sport, 'srcport_or_icmptype_last': rule_l4_sport, 'dstport_or_icmpcode_first': rule_l4_dport, 'dstport_or_icmpcode_last': rule_l4_dport, 'proto': rule_l4_proto, } rules.append(new_rule) new_rule_permit = new_rule.copy() new_rule_permit['is_permit'] = 1 permit_rules.append(new_rule_permit) new_rule_permit_and_reflect = new_rule.copy() if can_reflect_this_packet: new_rule_permit_and_reflect['is_permit'] = 2 else: new_rule_permit_and_reflect['is_permit'] = is_permit permit_and_reflect_rules.append(new_rule_permit_and_reflect) self.logger.info("create_stream pkt#%d: %s" % (i, payload)) return { 'stream': pkts, 'rules': rules, 'permit_rules': permit_rules, 'permit_and_reflect_rules': permit_and_reflect_rules }
def test_arp_incomplete(self): """ ARP Incomplete""" self.pg1.generate_remote_hosts(3) p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_hosts[1].ip4) / UDP(sport=1234, dport=1234) / Raw()) p1 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_hosts[2].ip4) / UDP(sport=1234, dport=1234) / Raw()) # # a packet to an unresolved destination generates an ARP request # rx = self.send_and_expect(self.pg0, [p0], self.pg1) self.verify_arp_req(rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4) # # add a neighbour for remote host 1 # static_arp = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[1].mac, self.pg1.remote_hosts[1].ip4, is_static=1) static_arp.add_vpp_config() # # change the interface's MAC # mac = [ chr(0x00), chr(0x00), chr(0x00), chr(0x33), chr(0x33), chr(0x33) ] mac_string = ''.join(mac) self.vapi.sw_interface_set_mac_address(self.pg1.sw_if_index, mac_string) # # now ARP requests come from the new source mac # rx = self.send_and_expect(self.pg0, [p1], self.pg1) self.verify_arp_req(rx[0], "00:00:00:33:33:33", self.pg1.local_ip4, self.pg1._remote_hosts[2].ip4) # # packets to the resolved host also have the new source mac # rx = self.send_and_expect(self.pg0, [p0], self.pg1) self.verify_ip(rx[0], "00:00:00:33:33:33", self.pg1.remote_hosts[1].mac, self.pg0.remote_ip4, self.pg1.remote_hosts[1].ip4) # # set the mac address on the inteface that does not have a # configured subnet and thus no glean # self.vapi.sw_interface_set_mac_address(self.pg2.sw_if_index, mac_string)
def post_dissect(self, data): """dissect the IPv6 package compressed into this IPHC packet. The packet payload needs to be decompressed and depending on the arguments, several conversions should be done. """ # uncompress payload packet = IPv6() packet.version = IPHC_DEFAULT_VERSION packet.tc, packet.fl = self._getTrafficClassAndFlowLabel() if not self.nh: packet.nh = self._nhField # HLIM: Hop Limit if self.hlim == 0: packet.hlim = self._hopLimit elif self.hlim == 0x1: packet.hlim = 1 elif self.hlim == 0x2: packet.hlim = 64 else: packet.hlim = 255 # TODO: Payload length can be inferred from lower layers from either the # noqa: E501 # 6LoWPAN Fragmentation header or the IEEE802.15.4 header packet.src = self.decompressSourceAddr(packet) packet.dst = self.decompressDestinyAddr(packet) if self.nh == 1: # The Next Header field is compressed and the next header is # encoded using LOWPAN_NHC packet.nh = 0x11 # UDP udp = UDP() if self.header_compression and \ self.header_compression & 0x4 == 0x0: udp.chksum = self.udpChecksum s, d = nhc_port(self) if s == 16: udp.sport = self.udpSourcePort elif s == 8: udp.sport = 0xF000 + s elif s == 4: udp.sport = 0xF0B0 + s if d == 16: udp.dport = self.udpDestinyPort elif d == 8: udp.dport = 0xF000 + d elif d == 4: udp.dport = 0xF0B0 + d packet.payload = udp / data data = raw(packet) # else self.nh == 0 not necessary elif self._nhField & 0xE0 == 0xE0: # IPv6 Extension Header Decompression # noqa: E501 warning('Unimplemented: IPv6 Extension Header decompression' ) # noqa: E501 packet.payload = conf.raw_layer(data) data = raw(packet) else: packet.payload = conf.raw_layer(data) data = raw(packet) return Packet.post_dissect(self, data)
def getIPv4Flow(self, id): return (IP(dst="90.0.%u.%u" % (id / 255, id % 255), src="40.0.%u.%u" % (id / 255, id % 255)) / UDP(sport=10000 + id, dport=20000 + id))
async def run_test_nic(dut): tb = TB(dut) await tb.init() tb.log.info("Init driver") await tb.driver.init_dev(tb.dev.functions[0].pcie_id) await tb.driver.interfaces[0].open() # enable queues tb.log.info("Enable queues") await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) for k in range(tb.driver.interfaces[0].tx_queue_count): await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) # wait for all writes to complete await tb.rc.mem_read(tb.driver.hw_addr, 4) tb.log.info("Init complete") tb.log.info("Send and receive single packet") data = bytearray([x % 256 for x in range(1024)]) await tb.driver.interfaces[0].start_xmit(data, 0) pkt = await tb.port_mac[0].tx.recv() tb.log.info("Packet: %s", pkt) await tb.port_mac[0].rx.send(pkt) pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.log.info("RX and TX checksum tests") payload = bytes([x % 256 for x in range(256)]) eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') ip = IP(src='192.168.1.100', dst='192.168.1.101') udp = UDP(sport=1, dport=2) test_pkt = eth / ip / udp / payload test_pkt2 = test_pkt.copy() test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) pkt = await tb.port_mac[0].tx.recv() tb.log.info("Packet: %s", pkt) await tb.port_mac[0].rx.send(pkt) pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff assert Ether(pkt.data).build() == test_pkt.build() tb.log.info("Multiple small packets") count = 64 pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.loopback_enable = False tb.log.info("Multiple large packets") count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.loopback_enable = False tb.log.info("Jumbo frames") count = 64 pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.loopback_enable = False await Timer(1000, 'ns') tb.log.info("TDMA") count = 16 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] tb.loopback_enable = True # configure TDMA scheduler await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) # enable queues with global enable off await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) for k in range(tb.driver.interfaces[0].tx_queue_count): await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) # configure slots await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) await tb.rc.mem_read(tb.driver.hw_addr, 4) # wait for all writes to complete # send packets for k in range(count): await tb.driver.interfaces[0].start_xmit(pkts[k], k % 4) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) # assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.loopback_enable = False tb.log.info("Read statistics counters") await Timer(2000, 'ns') lst = [] for k in range(64): lst.append(await tb.rc.mem_read_dword(tb.driver.hw_addr+0x010000+k*8)) print(lst) await RisingEdge(dut.clk) await RisingEdge(dut.clk)
def test_uu_fwd(self): """ UU Flood """ # # Create a single bridge Domain # self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1) # # add each interface to the BD. 3 interfaces per split horizon group # for i in self.pg_interfaces[0:4]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0) # # an unknown unicast and broadcast packets # p_uu = (Ether(dst="00:00:00:c1:5c:00", src="00:00:de:ad:be:ef") / IP(src="10.10.10.10", dst="1.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) p_bm = (Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef") / IP(src="10.10.10.10", dst="1.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) # # input on pg0, expected copies on pg1->4 # self.pg0.add_stream(p_uu * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:4]: rx0 = i.get_capture(65, timeout=1) self.pg0.add_stream(p_bm * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:4]: rx0 = i.get_capture(65, timeout=1) # # use pg8 as the uu-fwd interface # self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0, port_type=L2_PORT_TYPE.UU_FWD) # # expect the UU packet on the uu-fwd interface and not be flooded # self.pg0.add_stream(p_uu * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx0 = self.pg8.get_capture(65, timeout=1) for i in self.pg_interfaces[0:4]: i.assert_nothing_captured(remark="UU not flooded") self.pg0.add_stream(p_bm * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:4]: rx0 = i.get_capture(65, timeout=1) # # remove the uu-fwd interface and expect UU to be flooded again # self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0, port_type=L2_PORT_TYPE.UU_FWD, enable=0) self.pg0.add_stream(p_uu * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() for i in self.pg_interfaces[1:4]: rx0 = i.get_capture(65, timeout=1) # # change the BD config to not support UU-flood # self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD) self.send_and_assert_no_replies(self.pg0, p_uu) # # re-add the uu-fwd interface # self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0, port_type=L2_PORT_TYPE.UU_FWD) self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.pg0.add_stream(p_uu * 65) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx0 = self.pg8.get_capture(65, timeout=1) for i in self.pg_interfaces[0:4]: i.assert_nothing_captured(remark="UU not flooded") # # remove the uu-fwd interface # self.vapi.sw_interface_set_l2_bridge( rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0, port_type=L2_PORT_TYPE.UU_FWD, enable=0) self.send_and_assert_no_replies(self.pg0, p_uu) # # cleanup # for i in self.pg_interfaces[:4]: self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0) self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
def high_push(self, msg): from scapy.layers.inet import IP, UDP p = IP(dst=self.ip) / UDP(sport=1234, dport=self.port) / msg self._send(p)
async def run_test_nic(dut): tb = TB(dut) await tb.init() tb.log.info("Init driver") await tb.driver.init_dev(tb.dev.functions[0].pcie_id) await tb.driver.interfaces[0].open() # await driver.interfaces[1].open() # enable queues tb.log.info("Enable queues") await tb.rc.mem_write_dword( tb.driver.interfaces[0].ports[0].hw_addr + mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) for k in range(tb.driver.interfaces[0].tx_queue_count): await tb.rc.mem_write_dword( tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr + 4 * k, 0x00000003) # wait for all writes to complete await tb.rc.mem_read(tb.driver.hw_addr, 4) tb.log.info("Init complete") tb.log.info("Send and receive single packet") data = bytearray([x % 256 for x in range(1024)]) await tb.driver.interfaces[0].start_xmit(data, 0) pkt = await tb.qsfp0_mac.tx.recv() tb.log.info("Packet: %s", pkt) await tb.qsfp0_mac.rx.send(pkt) pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.rx_checksum == ~scapy.utils.checksum(bytes( pkt.data[14:])) & 0xffff # await tb.driver.interfaces[1].start_xmit(data, 0) # pkt = await tb.qsfp1_mac.tx.recv() # tb.log.info("Packet: %s", pkt) # await tb.qsfp1_mac.rx.send(pkt) # pkt = await tb.driver.interfaces[1].recv() # tb.log.info("Packet: %s", pkt) # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff tb.log.info("RX and TX checksum tests") payload = bytes([x % 256 for x in range(256)]) eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') ip = IP(src='192.168.1.100', dst='192.168.1.101') udp = UDP(sport=1, dport=2) test_pkt = eth / ip / udp / payload test_pkt2 = test_pkt.copy() test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) pkt = await tb.qsfp0_mac.tx.recv() tb.log.info("Packet: %s", pkt) await tb.qsfp0_mac.rx.send(pkt) pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.rx_checksum == ~scapy.utils.checksum(bytes( pkt.data[14:])) & 0xffff assert Ether(pkt.data).build() == test_pkt.build() tb.log.info("Multiple small packets") count = 64 pkts = [ bytearray([(x + k) % 256 for x in range(60)]) for k in range(count) ] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes( pkt.data[14:])) & 0xffff tb.loopback_enable = False tb.log.info("Multiple large packets") count = 64 pkts = [ bytearray([(x + k) % 256 for x in range(1514)]) for k in range(count) ] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes( pkt.data[14:])) & 0xffff tb.loopback_enable = False tb.log.info("Jumbo frames") count = 64 pkts = [ bytearray([(x + k) % 256 for x in range(9014)]) for k in range(count) ] tb.loopback_enable = True for p in pkts: await tb.driver.interfaces[0].start_xmit(p, 0) for k in range(count): pkt = await tb.driver.interfaces[0].recv() tb.log.info("Packet: %s", pkt) assert pkt.data == pkts[k] assert pkt.rx_checksum == ~scapy.utils.checksum(bytes( pkt.data[14:])) & 0xffff tb.loopback_enable = False await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz)
def test_pipe(self): """ Pipes """ pipes = [VppPipe(self), VppPipe(self, 10)] for p in pipes: p.add_vpp_config() p.admin_up() # # L2 cross-connect pipe0 east with pg0 and west with pg1 # self.vapi.sw_interface_set_l2_xconnect(self.pg0.sw_if_index, pipes[0].east, enable=1) self.vapi.sw_interface_set_l2_xconnect(pipes[0].east, self.pg0.sw_if_index, enable=1) self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index, pipes[0].west, enable=1) self.vapi.sw_interface_set_l2_xconnect(pipes[0].west, self.pg1.sw_if_index, enable=1) # test bi-directional L2 flow pg0<->pg1 p = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) / IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.send_and_expect(self.pg0, p * 65, self.pg1) self.send_and_expect(self.pg1, p * 65, self.pg0) # # Attach ACL to ensure features are run on the pipe # rule_1 = ({ 'is_permit': 0, 'is_ipv6': 0, 'proto': 17, 'srcport_or_icmptype_first': 1234, 'srcport_or_icmptype_last': 1234, 'src_ip_prefix_len': 32, 'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"), 'dstport_or_icmpcode_first': 1234, 'dstport_or_icmpcode_last': 1234, 'dst_ip_prefix_len': 32, 'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2") }) acl = self.vapi.acl_add_replace(acl_index=4294967295, r=[rule_1]) # Apply the ACL on the pipe on output self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [acl.acl_index]) self.send_and_assert_no_replies(self.pg0, p * 65) self.send_and_expect(self.pg1, p * 65, self.pg0) # remove from output and apply on input self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, []) self.vapi.acl_interface_set_acl_list(pipes[0].west, 1, [acl.acl_index]) self.send_and_assert_no_replies(self.pg0, p * 65) self.send_and_expect(self.pg1, p * 65, self.pg0) self.vapi.acl_interface_set_acl_list(pipes[0].west, 0, []) self.send_and_expect(self.pg0, p * 65, self.pg1) self.send_and_expect(self.pg1, p * 65, self.pg0) # # L3 routes in two separate tables so a pipe can be used to L3 # x-connect # tables = [] tables.append(VppIpTable(self, 1)) tables.append(VppIpTable(self, 2)) for t in tables: t.add_vpp_config() self.pg2.set_table_ip4(1) self.pg2.config_ip4() self.pg2.resolve_arp() self.pg3.set_table_ip4(2) self.pg3.config_ip4() self.pg3.resolve_arp() routes = [] routes.append( VppIpRoute( self, "1.1.1.1", 32, [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)], table_id=2)) routes.append( VppIpRoute(self, "1.1.1.1", 32, [VppRoutePath("0.0.0.0", pipes[1].east)], table_id=1)) routes.append( VppIpRoute(self, "1.1.1.2", 32, [VppRoutePath("0.0.0.0", pipes[1].west)], table_id=2)) routes.append( VppIpRoute( self, "1.1.1.2", 32, [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)], table_id=1)) for r in routes: r.add_vpp_config() p_east = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / IP(src="1.1.1.2", dst="1.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) # bind the pipe ends to the correct tables self.vapi.sw_interface_set_table(pipes[1].west, 0, 2) self.vapi.sw_interface_set_table(pipes[1].east, 0, 1) # IP is not enabled on the pipes at this point self.send_and_assert_no_replies(self.pg2, p_east * 65) # IP enable the Pipes by making them unnumbered pipes[0].set_unnumbered(self.pg2.sw_if_index) pipes[1].set_unnumbered(self.pg3.sw_if_index) self.send_and_expect(self.pg2, p_east * 65, self.pg3) # and the return path p_west = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) / IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # # Use ACLs to test features run on the Pipes # self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [acl.acl_index]) self.send_and_assert_no_replies(self.pg2, p_east * 65) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # remove from output and apply on input self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, []) self.vapi.acl_interface_set_acl_list(pipes[1].west, 1, [acl.acl_index]) self.send_and_assert_no_replies(self.pg2, p_east * 65) self.send_and_expect(self.pg3, p_west * 65, self.pg2) self.vapi.acl_interface_set_acl_list(pipes[1].west, 0, []) self.send_and_expect(self.pg2, p_east * 65, self.pg3) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # cleanup (so the tables delete) self.pg2.unconfig_ip4() self.pg2.set_table_ip4(0) self.pg3.unconfig_ip4() self.pg3.set_table_ip4(0) self.vapi.sw_interface_set_table(pipes[1].west, 0, 0) self.vapi.sw_interface_set_table(pipes[1].east, 0, 0)
def send_message(self, server, message): f = open('dns.json') data = json.load(f) f.close() message = handle.encrypt(message) self.threadSignal.emit(message) found_domain = False start_time = time.time() # RUMORE request_number = random.randint(5, 10) for i in range(0, request_number): number_random = random.randint(0, len(data) - 1) fake_domain = data[number_random]["dominio"] ip = data[number_random]["ip"] answer = sr1(IP(dst=server) / UDP(sport=RandShort(), dport=53) / DNS(id=random.randint(0, 65535), rd=1, qd=DNSQR(qname=fake_domain), an=DNSRR(rrname=fake_domain, rdata=ip)), verbose=0) self.threadSignal.emit(repr(answer[DNS])) # time.sleep(random.randint(2, 10)) while not found_domain: number_random = random.randint(0, len(data) - 1) fake_domain = data[number_random]["dominio"] ip = data[number_random]["ip"] if handle_glob.countConsonantsandVolwes(fake_domain)[ 0] % 2 == 0 and handle_glob.countConsonantsandVolwes( fake_domain)[1] >= 4: found_domain = True ttl = random.randint(2468, 10468) ttl_binary = bin(ttl)[2:].zfill(16) len_binary = bin(len(message))[2:].zfill(8) # pattern = random.randint(0, 15) # pattern_bin = bin(pattern)[2:].zfill(4) pattern_bin = config.get('CONFIG', 'pattern') binary = '' j = 0 k = 0 for i in range(0, len(ttl_binary)): if i % 2 != 0: binary += len_binary[j] j += 1 elif i < 8 and i % 2 == 0: binary += pattern_bin[k] k += 1 else: binary += ttl_binary[i] answer = sr1( IP(dst=server) / UDP(sport=RandShort(), dport=53) / DNS(id=random.randint(0, 65535), rd=1, qd=DNSQR(qname=fake_domain), an=DNSRR(ttl=int(binary, 2), rrname=fake_domain, rdata=ip)), verbose=0) self.threadSignal.emit(repr(answer[DNS])) # time.sleep(random.randint(2, 10)) chunks = list(self.chunkstring(message, 16)) for message in chunks: for i in range(0, len(message)): found_domain = False while not found_domain: number_random = random.randint(0, len(data) - 1) fake_domain = data[number_random]["dominio"] if handle_glob.countConsonantsandVolwes( fake_domain )[0] % 2 == 0 and handle_glob.countConsonantsandVolwes( fake_domain)[1] >= 4: found_domain = True dns_id = random.randint(0, 65535) binary_temp = bin(dns_id)[2:].zfill(16) binary = '' message_binary = bin(ord(message[i]))[2:].zfill(8) sequence_number = bin(i)[2:].zfill(4) j = 0 k = 0 z = 0 for i in range(0, len(binary_temp)): if i % 2 == 0: binary += message_binary[j] j += 1 elif i < 8 and i % 2 != 0: binary += sequence_number[k] k += 1 else: binary += pattern_bin[z] z += 1 new_dns_id = int(binary, 2) answer = sr1( IP(dst=server) / UDP(sport=RandShort(), dport=53) / DNS(id=new_dns_id, rd=1, qd=DNSQR(qname=fake_domain)), verbose=0) self.threadSignal.emit(repr(answer[DNS])) # time.sleep(random.randint(2, 10)) # RUMORE request_number = random.randint(1, 3) for i in range(0, request_number): number_random = random.randint(0, len(data) - 1) fake_domain = data[number_random]["dominio"] answer = sr1(IP(dst=server) / UDP(sport=RandShort(), dport=53) / DNS(id=random.randint(0, 65535), rd=1, qd=DNSQR(qname=fake_domain)), verbose=0) self.threadSignal.emit(repr(answer[DNS])) # time.sleep(random.randint(2, 10)) end_time = (time.time() - start_time) self.threadSignal.emit("END in " + str(end_time) + " seconds")
def ikescan(ip): return sr( IP(dst=ip) / UDP() / ISAKMP(init_cookie=RandString(8), exch_type=2) / ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
def test_ip_sub_nets(self): """ IP Sub Nets """ # # Configure a covering route to forward so we know # when we are dropping # cover_route = VppIpRoute( self, "10.0.0.0", 8, [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)]) cover_route.add_vpp_config() p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(dst="10.10.10.10", src=self.pg0.local_ip4) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.pg1.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) # # Configure some non-/24 subnets on an IP interface # ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10") self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n, 16) pn = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(dst="10.10.0.0", src=self.pg0.local_ip4) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) pb = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(dst="10.10.255.255", src=self.pg0.local_ip4) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.send_and_assert_no_replies(self.pg1, pn, "IP Network address") self.send_and_assert_no_replies(self.pg1, pb, "IP Broadcast address") # remove the sub-net and we are forwarding via the cover again self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n, 16, is_add=0) self.pg1.add_stream(pn) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) self.pg1.add_stream(pb) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1) # # A /31 is a special case where the 'other-side' is an attached host # packets to that peer generate ARP requests # ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10") self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n, 31) pn = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / IP(dst="10.10.10.11", src=self.pg0.local_ip4) / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.pg1.add_stream(pn) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg0.get_capture(1) rx[ARP] # remove the sub-net and we are forwarding via the cover again self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n, 31, is_add=0) self.pg1.add_stream(pn) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx = self.pg1.get_capture(1)
class scapy(object): SCAPY_LAYERS = { 'ether': Ether(dst="ff:ff:ff:ff:ff:ff"), 'vlan': Dot1Q(), 'etag': Dot1BR(), '1588': Ether(type=0x88f7), 'arp': ARP(), 'ipv4': IP(), 'ipv4ihl': IP(ihl=10), 'ipv4_ext': IP(frag=5), 'ipv6': IPv6(src="::1"), 'ipv6_ext': IPv6(src="::1", nh=43) / IPv6ExtHdrRouting(), 'ipv6_ext2': IPv6() / IPv6ExtHdrRouting(), 'udp': UDP(), 'tcp': TCP(), 'sctp': SCTP(), 'icmp': ICMP(), 'gre': GRE(), 'raw': Raw(), 'vxlan': Vxlan(), 'inner_mac': Ether(), 'inner_vlan': Dot1Q(), 'inner_ipv4': IP(), 'inner_ipv4_ext': IP(), 'inner_ipv6': IPv6(src="::1"), 'inner_ipv6_ext': IPv6(src="::1"), 'inner_tcp': TCP(), 'inner_udp': UDP(), 'inner_sctp': SCTP(), 'inner_icmp': ICMP(), 'lldp': LLDP() / LLDPManagementAddress(), 'ip_frag': IP(frag=5), 'ipv6_frag': IPv6(src="::1") / IPv6ExtHdrFragment(), 'ip_in_ip': IP() / IP(), 'ip_in_ip_frag': IP() / IP(frag=5), 'ipv6_in_ip': IP() / IPv6(src="::1"), 'ipv6_frag_in_ip': IP() / IPv6(src="::1", nh=44) / IPv6ExtHdrFragment(), 'nvgre': NVGRE(), 'geneve': "Not Implement", } def __init__(self): self.pkt = None pass def assign_pkt(self, pkt): self.pkt = pkt def add_layers(self, layers): self.pkt = None for layer in layers: if self.pkt is not None: self.pkt = self.pkt / self.SCAPY_LAYERS[layer] else: self.pkt = self.SCAPY_LAYERS[layer] def ether(self, pkt_layer, dst="ff:ff:ff:ff:ff:ff", src="00:00:20:00:00:00", type=None): if pkt_layer.name != "Ethernet": return pkt_layer.dst = dst pkt_layer.src = src if type is not None: pkt_layer.type = type def vlan(self, pkt_layer, vlan, prio=0, type=None): if pkt_layer.name != "802.1Q": return pkt_layer.vlan = int(vlan) pkt_layer.prio = prio if type is not None: pkt_layer.type = type def strip_vlan(self, element): value = None if self.pkt.haslayer('Dot1Q') is 0: return None if element == 'vlan': value = int(str(self.pkt[Dot1Q].vlan)) return value def etag(self, pkt_layer, ECIDbase=0, prio=0, type=None): if pkt_layer.name != "802.1BR": return pkt_layer.ECIDbase = int(ECIDbase) pkt_layer.prio = prio if type is not None: pkt_layer.type = type def strip_etag(self, element): value = None if self.pkt.haslayer('Dot1BR') is 0: return None if element == 'ECIDbase': value = int(str(self.pkt[Dot1BR].ECIDbase)) return value def strip_layer2(self, element): value = None layer = self.pkt.getlayer(0) if layer is None: return None if element == 'src': value = layer.src elif element == 'dst': value = layer.dst elif element == 'type': value = layer.type return value def strip_layer3(self, element): value = None layer = self.pkt.getlayer(1) if layer is None: return None if element == 'src': value = layer.src elif element == 'dst': value = layer.dst else: value = layer.getfieldval(element) return value def strip_layer4(self, element): value = None layer = self.pkt.getlayer(2) if layer is None: return None if element == 'src': value = layer.sport elif element == 'dst': value = layer.dport else: value = layer.getfieldval(element) return value def ipv4(self, pkt_layer, frag=0, src="127.0.0.1", proto=None, tos=0, dst="127.0.0.1", chksum=None, len=None, version=4, flags=None, ihl=None, ttl=64, id=1, options=None): pkt_layer.frag = frag pkt_layer.src = src if proto is not None: pkt_layer.proto = proto pkt_layer.tos = tos pkt_layer.dst = dst if chksum is not None: pkt_layer.chksum = chksum if len is not None: pkt_layer.len = len pkt_layer.version = version if flags is not None: pkt_layer.flags = flags if ihl is not None: pkt_layer.ihl = ihl pkt_layer.ttl = ttl pkt_layer.id = id if options is not None: pkt_layer.options = options def ipv6(self, pkt_layer, version=6, tc=0, fl=0, plen=0, nh=0, hlim=64, src="::1", dst="::1"): """ Configure IPv6 protocal. """ pkt_layer.version = version pkt_layer.tc = tc pkt_layer.fl = fl if plen: pkt_layer.plen = plen if nh: pkt_layer.nh = nh pkt_layer.src = src pkt_layer.dst = dst def tcp(self, pkt_layer, src=53, dst=53, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def udp(self, pkt_layer, src=53, dst=53, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def sctp(self, pkt_layer, src=53, dst=53, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def raw(self, pkt_layer, payload=None): if payload is not None: pkt_layer.load = '' for hex1, hex2 in payload: pkt_layer.load += struct.pack("=B", int('%s%s' % (hex1, hex2), 16)) def gre(self, pkt_layer, proto=None): if proto is not None: pkt_layer.proto = proto def vxlan(self, pkt_layer, vni=0): pkt_layer.vni = vni def read_pcap(self, file): pcap_pkts = [] try: pcap_pkts = rdpcap(file) except: pass return pcap_pkts def write_pcap(self, file): try: wrpcap(file, self.pkt) except: pass def send_pcap_pkt(self, crb=None, file='', intf='', count=1): if intf == '' or file == '' or crb is None: print "Invalid option for send packet by scapy" return content = 'pkts=rdpcap(\"%s\");sendp(pkts, iface=\"%s\", count=\"%s\" );exit()' % (file, intf, count) cmd_file = '/tmp/scapy_%s.cmd' % intf crb.create_file(content, cmd_file) crb.send_expect("scapy -c scapy_%s.cmd &" % intf, "# ") def print_summary(self): print "Send out pkt %s" % self.pkt.summary() def send_pkt(self, intf='', count=1): self.print_summary() if intf != '': # wait few seconds for link ready countdown = 600 while countdown: link_st = subprocess.check_output("ip link show %s" % intf, stderr=subprocess.STDOUT, shell=True) if "LOWER_UP" in link_st: break else: time.sleep(0.01) countdown -= 1 continue # fix fortville can't receive packets with 00:00:00:00:00:00 if self.pkt.getlayer(0).src == "00:00:00:00:00:00": self.pkt.getlayer(0).src = get_if_hwaddr(intf) sendp(self.pkt, iface=intf, count=count)
async def run_test(dut): tb = TB(dut) await tb.init() tb.log.info("test UDP RX packet") payload = bytes([x % 256 for x in range(256)]) eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00') ip = IP(src='192.168.1.100', dst='192.168.1.128') udp = UDP(sport=5678, dport=1234) test_pkt = eth / ip / udp / payload test_frame = XgmiiFrame.from_payload(test_pkt.build()) await tb.qsfp_1_source.send(test_frame) tb.log.info("receive ARP request") rx_frame = await tb.qsfp_1_sink.recv() rx_pkt = Ether(bytes(rx_frame.get_payload())) tb.log.info("RX packet: %s", repr(rx_pkt)) assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff' assert rx_pkt.src == test_pkt.dst assert rx_pkt[ARP].hwtype == 1 assert rx_pkt[ARP].ptype == 0x0800 assert rx_pkt[ARP].hwlen == 6 assert rx_pkt[ARP].plen == 4 assert rx_pkt[ARP].op == 1 assert rx_pkt[ARP].hwsrc == test_pkt.dst assert rx_pkt[ARP].psrc == test_pkt[IP].dst assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00' assert rx_pkt[ARP].pdst == test_pkt[IP].src tb.log.info("send ARP response") eth = Ether(src=test_pkt.src, dst=test_pkt.dst) arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2, hwsrc=test_pkt.src, psrc=test_pkt[IP].src, hwdst=test_pkt.dst, pdst=test_pkt[IP].dst) resp_pkt = eth / arp resp_frame = XgmiiFrame.from_payload(resp_pkt.build()) await tb.qsfp_1_source.send(resp_frame) tb.log.info("receive UDP packet") rx_frame = await tb.qsfp_1_sink.recv() rx_pkt = Ether(bytes(rx_frame.get_payload())) tb.log.info("RX packet: %s", repr(rx_pkt)) assert rx_pkt.dst == test_pkt.src assert rx_pkt.src == test_pkt.dst assert rx_pkt[IP].dst == test_pkt[IP].src assert rx_pkt[IP].src == test_pkt[IP].dst assert rx_pkt[UDP].dport == test_pkt[UDP].sport assert rx_pkt[UDP].sport == test_pkt[UDP].dport assert rx_pkt[UDP].payload == test_pkt[UDP].payload await RisingEdge(dut.clk) await RisingEdge(dut.clk)
def send_dhcp_packet( self, mac: MacAddress, vlan: str, state: DHCPState, dhcp_desc: DHCPDescriptor = None, ): """ Send DHCP packet and record state in dhcp_client_state. Args: mac: MAC address of interface state: state of DHCP packet dhcp_desc: DHCP protocol state. Returns: """ ciaddr = None # generate DHCP request packet if state == DHCPState.DISCOVER: dhcp_opts = [("message-type", "discover")] dhcp_desc = DHCPDescriptor( mac=mac, ip="", vlan=vlan, state_requested=DHCPState.DISCOVER, ) self._msg_xid = self._msg_xid + 1 pkt_xid = self._msg_xid elif state == DHCPState.REQUEST: dhcp_opts = [ ("message-type", "request"), ("requested_addr", dhcp_desc.ip), ("server_id", dhcp_desc.server_ip), ] dhcp_desc.state_requested = DHCPState.REQUEST pkt_xid = dhcp_desc.xid ciaddr = dhcp_desc.ip elif state == DHCPState.RELEASE: dhcp_opts = [ ("message-type", "release"), ("server_id", dhcp_desc.server_ip), ] dhcp_desc.state_requested = DHCPState.RELEASE self._msg_xid = self._msg_xid + 1 pkt_xid = self._msg_xid ciaddr = dhcp_desc.ip else: LOG.warning( "Unknown egress request mac %s state %s", str(mac), state, ) return dhcp_opts.append("end") dhcp_desc.xid = pkt_xid with self._dhcp_notify: self.dhcp_client_state[mac.as_redis_key(vlan)] = dhcp_desc pkt = Ether(src=str(mac), dst="ff:ff:ff:ff:ff:ff") if vlan and vlan != "0": pkt /= Dot1Q(vlan=int(vlan)) pkt /= IP(src="0.0.0.0", dst="255.255.255.255") pkt /= UDP(sport=68, dport=67) pkt /= BOOTP(op=1, chaddr=mac.as_hex(), xid=pkt_xid, ciaddr=ciaddr) pkt /= DHCP(options=dhcp_opts) LOG.debug("DHCP pkt xmit %s", pkt.show(dump=True)) sendp(pkt, iface=self._dhcp_interface, verbose=0)
def test_arp_duplicates(self): """ ARP Duplicates""" # # Generate some hosts on the LAN # self.pg1.generate_remote_hosts(3) # # Add host 1 on pg1 and pg2 # arp_pg1 = VppNeighbor(self, self.pg1.sw_if_index, self.pg1.remote_hosts[1].mac, self.pg1.remote_hosts[1].ip4) arp_pg1.add_vpp_config() arp_pg2 = VppNeighbor(self, self.pg2.sw_if_index, self.pg2.remote_mac, self.pg1.remote_hosts[1].ip4) arp_pg2.add_vpp_config() # # IP packet destined for pg1 remote host arrives on pg1 again. # p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_hosts[1].ip4) / UDP(sport=1234, dport=1234) / Raw()) self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx1 = self.pg1.get_capture(1) self.verify_ip(rx1[0], self.pg1.local_mac, self.pg1.remote_hosts[1].mac, self.pg0.remote_ip4, self.pg1.remote_hosts[1].ip4) # # remove the duplicate on pg1 # packet stream shoud generate ARPs out of pg1 # arp_pg1.remove_vpp_config() self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx1 = self.pg1.get_capture(1) self.verify_arp_req(rx1[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1.remote_hosts[1].ip4) # # Add it back # arp_pg1.add_vpp_config() self.pg0.add_stream(p) self.pg_enable_capture(self.pg_interfaces) self.pg_start() rx1 = self.pg1.get_capture(1) self.verify_ip(rx1[0], self.pg1.local_mac, self.pg1.remote_hosts[1].mac, self.pg0.remote_ip4, self.pg1.remote_hosts[1].ip4)
def create_stream(self, mac_type, ip_type, packet_count, src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS): # exact MAC and exact IP # exact MAC and subnet of IPs # exact MAC and wildcard IP # wildcard MAC and exact IP # wildcard MAC and subnet of IPs # wildcard MAC and wildcard IP # OUI restricted MAC and exact IP # OUI restricted MAC and subnet of IPs # OUI restricted MAC and wildcard IP packets = [] macip_rules = [] acl_rules = [] ip_permit = "" mac_permit = "" dst_mac = "" mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" for p in range(0, packet_count): remote_dst_index = p % len(dst_if.remote_hosts) remote_dst_host = dst_if.remote_hosts[remote_dst_index] dst_port = 1234 + p src_port = 4321 + p is_permit = self.PERMIT if p % 3 == 0 else self.DENY denyMAC = True if not is_permit and p % 3 == 1 else False denyIP = True if not is_permit and p % 3 == 2 else False if not is_permit and ip_type == self.WILD_IP: denyMAC = True if not is_permit and mac_type == self.WILD_MAC: denyIP = True if traffic == self.BRIDGED: if is_permit: src_mac = remote_dst_host._mac dst_mac = 'de:ad:00:00:00:00' src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16)+1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 else: if is_permit: src_mac = remote_dst_host._mac dst_mac = src_if.local_mac src_ip4 = src_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 src_ip6 = src_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: src_mac = remote_dst_host._mac if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 if is_permit: info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(info) else: payload = "to be blocked" if mac_type == self.WILD_MAC: mac = src_mac.split(':') for i in range(1, 5): mac[i] = format(random.randint(0, 255), "02x") src_mac = ":".join(mac) # create packet packet = Ether(src=src_mac, dst=dst_mac) ip_rule = src_ip6 if is_ip6 else src_ip4 if is_ip6: if ip_type != self.EXACT_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip_rule))) if ip_type == self.WILD_IP: sub_ip[0] = random.randint(240, 254) sub_ip[1] = random.randint(230, 239) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[2] = str(int(sub_ip[2]) + 1) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) src_ip6 = inet_ntop(AF_INET6, str(bytearray(sub_ip))) packet /= IPv6(src=src_ip6, dst=dst_ip6) else: if ip_type != self.EXACT_IP: sub_ip = ip_rule.split('.') if ip_type == self.WILD_IP: sub_ip[0] = str(random.randint(1, 49)) sub_ip[1] = str(random.randint(50, 99)) sub_ip[2] = str(random.randint(100, 199)) sub_ip[3] = str(random.randint(200, 255)) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[1] = str(int(sub_ip[1])+1) sub_ip[2] = str(random.randint(100, 199)) sub_ip[3] = str(random.randint(200, 255)) src_ip4 = ".".join(sub_ip) packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0) packet /= UDP(sport=src_port, dport=dst_port)/Raw(payload) packet[Raw].load += " mac:"+src_mac size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)] if isinstance(src_if, VppSubInterface): size = size + 4 if isinstance(src_if, VppDot1QSubint): if src_if is self.subifs[0]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 10) else: packet = src_if.add_dot1q_layer(packet, 11) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 30) else: packet = src_if.add_dot1q_layer(packet, 33) elif isinstance(src_if, VppDot1ADSubint): if src_if is self.subifs[1]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 300, 400) else: packet = src_if.add_dot1ad_layer(packet, 333, 444) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 600, 700) else: packet = src_if.add_dot1ad_layer(packet, 666, 777) self.extend_packet(packet, size) packets.append(packet) # create suitable MACIP rule if mac_type == self.EXACT_MAC: mac_rule = src_mac mac_mask = "ff:ff:ff:ff:ff:ff" elif mac_type == self.WILD_MAC: mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mac = src_mac.split(':') mac[3] = mac[4] = mac[5] = '00' mac_rule = ":".join(mac) mac_mask = "ff:ff:ff:00:00:00" if is_ip6: if ip_type == self.WILD_IP: ip = "0::0" else: ip = src_ip6 if ip_type == self.SUBNET_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip))) for i in range(8, 16): sub_ip[i] = 0 ip = inet_ntop(AF_INET6, str(bytearray(sub_ip))) else: if ip_type == self.WILD_IP: ip = "0.0.0.0" else: ip = src_ip4 if ip_type == self.SUBNET_IP: sub_ip = ip.split('.') sub_ip[2] = sub_ip[3] = '0' ip = ".".join(sub_ip) prefix_len = 128 if is_ip6 else 32 if ip_type == self.WILD_IP: prefix_len = 0 elif ip_type == self.SUBNET_IP: prefix_len = 64 if is_ip6 else 16 ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip) # create suitable ACL rule if is_permit: rule_l4_sport = packet[UDP].sport rule_l4_dport = packet[UDP].dport rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET rule_prefix_len = 128 if packet.haslayer(IPv6) else 32 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP if packet.haslayer(IPv6): rule_l4_proto = packet[UDP].overload_fields[IPv6]['nh'] else: rule_l4_proto = packet[IP].proto acl_rule = { 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].src), 'src_ip_prefix_len': rule_prefix_len, 'dst_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].dst), 'dst_ip_prefix_len': rule_prefix_len, 'srcport_or_icmptype_first': rule_l4_sport, 'srcport_or_icmptype_last': rule_l4_sport, 'dstport_or_icmpcode_first': rule_l4_dport, 'dstport_or_icmpcode_last': rule_l4_dport, 'proto': rule_l4_proto} acl_rules.append(acl_rule) if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0: continue if is_permit: macip_rule = ({ 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': ip_rule, 'src_ip_prefix_len': prefix_len, 'src_mac': mac_rule.replace(':', '').decode('hex'), 'src_mac_mask': mac_mask.replace(':', '').decode('hex')}) macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): macip_rule = ({'is_permit': 0, 'is_ipv6': is_ip6, 'src_ip_addr': "", 'src_ip_prefix_len': 0, 'src_mac': "", 'src_mac_mask': ""}) macip_rules.append(macip_rule) acl_rule = {'is_permit': 0, 'is_ipv6': is_ip6} acl_rules.append(acl_rule) return {'stream': packets, 'macip_rules': macip_rules, 'acl_rules': acl_rules}
def post_dissect(self, data): """dissect the IPv6 package compressed into this IPHC packet. The packet payload needs to be decompressed and depending on the arguments, several conversions should be done. """ # uncompress payload packet = IPv6() packet.version = IPHC_DEFAULT_VERSION packet.tc, packet.fl = self._getTrafficClassAndFlowLabel() if not self.nh: packet.nh = self._nhField # HLIM: Hop Limit if self.hlim == 0: packet.hlim = self._hopLimit elif self.hlim == 0x1: packet.hlim = 1 elif self.hlim == 0x2: packet.hlim = 64 else: packet.hlim = 255 # TODO: Payload length can be inferred from lower layers from either the # noqa: E501 # 6LoWPAN Fragmentation header or the IEEE802.15.4 header packet.src = self.decompressSourceAddr(packet) packet.dst = self.decompressDestinyAddr(packet) if self.nh == 1: # The Next Header field is compressed and the next header is # encoded using LOWPAN_NHC udp = UDP() if self.header_compression and \ self.header_compression & 0x4 == 0x0: udp.chksum = self.udpChecksum s, d = nhc_port(self) if s == 16: udp.sport = self.udpSourcePort elif s == 8: udp.sport = 0xF000 + s elif s == 4: udp.sport = 0xF0B0 + s if d == 16: udp.dport = self.udpDestinyPort elif d == 8: udp.dport = 0xF000 + d elif d == 4: udp.dport = 0xF0B0 + d packet.payload = udp / data data = raw(packet) # else self.nh == 0 not necessary elif self._nhField & 0xE0 == 0xE0: # IPv6 Extension Header Decompression # noqa: E501 warning('Unimplemented: IPv6 Extension Header decompression') # noqa: E501 packet.payload = conf.raw_layer(data) data = raw(packet) else: packet.payload = conf.raw_layer(data) data = raw(packet) return Packet.post_dissect(self, data)
import argparse from socket import inet_pton import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) from scapy.all import * from scapy.layers.inet import IP from scapy.layers.inet6 import IPv6 from scapy.layers.inet import UDP from random import shuffle src_mac = "00:00:00:00:de:ad" dst_mac = "00:00:de:ad:be:ef" eth_hdr_len = len(Ether()) ip_hdr_len = len(IP()) ipv6_hdr_len = len(IPv6()) udp_hdr_len = len(UDP()) udpv4_hdr_len = eth_hdr_len + ip_hdr_len + udp_hdr_len udpv6_hdr_len = eth_hdr_len + ipv6_hdr_len + udp_hdr_len def write_pkts(pkts, pcap_path): try: pktdump = PcapWriter(pcap_path, append=False, sync=True) if len(pkts) > 0: pktdump.write(pkts) except IOError: pass def read_pkts(pcap_path): try: