def generate(self, ip_dst=None, eth_dst=None): """Generates a Neighbor Solicitation (NS) packet (ICMP over IPv6). Args: ip_dst: NS ipv6 destination (Optional) eth_dst: Ethernet (layer 2) destination address (Optional) """ # Compute IP addresses target_ip6 = ip_dst if ip_dst is not None else self.dst_ipv6 ndst_ip = socket.inet_pton(socket.AF_INET6, target_ip6) nnode_mcast = scapy.in6_getnsma(ndst_ip) node_mcast = socket.inet_ntop(socket.AF_INET6, nnode_mcast) # Compute MAC addresses hw_dst = (eth_dst if eth_dst is not None else scapy.in6_getnsmac(nnode_mcast)) # Create IPv6 layer base = scapy.IPv6(dst=node_mcast, src=self.src_ipv6) neighbor_solicitation = scapy.ICMPv6ND_NS(tgt=target_ip6) src_ll_addr = scapy.ICMPv6NDOptSrcLLAddr(lladdr=self.src_mac) ip6 = base / neighbor_solicitation / src_ll_addr # Create Ethernet layer ethernet = scapy.Ether(src=self.src_mac, dst=hw_dst) self.packet = ethernet / ip6 return self.packet
def packets_for_test(request, ptfadapter, duthost, config_facts, tbinfo, ip_and_intf_info): ip_version = request.param src_addr_v4, src_addr_v6, ptf_intf = ip_and_intf_info ptf_intf_index = int(ptf_intf.replace('eth', '')) ptf_intf_mac = ptfadapter.dataplane.get_mac(0, ptf_intf_index) vlans = config_facts['VLAN'] topology = tbinfo['topo']['name'] dut_mac = '' for vlan_details in vlans.values(): if 'dualtor' in topology: dut_mac = vlan_details['mac'].lower() else: dut_mac = duthost.shell( 'sonic-cfggen -d -v \'DEVICE_METADATA.localhost.mac\'' )["stdout_lines"][0].decode("utf-8") break if ip_version == 'v4': tgt_addr = increment_ipv4_addr(src_addr_v4) out_pkt = testutils.simple_arp_packet(eth_dst='ff:ff:ff:ff:ff:ff', eth_src=ptf_intf_mac, ip_snd=src_addr_v4, ip_tgt=tgt_addr, arp_op=1, hw_snd=ptf_intf_mac) exp_pkt = testutils.simple_arp_packet(eth_dst=ptf_intf_mac, eth_src=dut_mac, ip_snd=tgt_addr, ip_tgt=src_addr_v4, arp_op=2, hw_snd=dut_mac, hw_tgt=ptf_intf_mac) elif ip_version == 'v6': tgt_addr = increment_ipv6_addr(src_addr_v6) ll_src_addr = generate_link_local_addr(ptf_intf_mac) multicast_tgt_addr = in6_getnsma(inet_pton(socket.AF_INET6, tgt_addr)) multicast_tgt_mac = in6_getnsmac(multicast_tgt_addr) out_pkt = Ether(src=ptf_intf_mac, dst=multicast_tgt_mac) out_pkt /= IPv6(dst=inet_ntop(socket.AF_INET6, multicast_tgt_addr), src=ll_src_addr) out_pkt /= ICMPv6ND_NS(tgt=tgt_addr) out_pkt /= ICMPv6NDOptSrcLLAddr(lladdr=ptf_intf_mac) exp_pkt = Ether(src=dut_mac, dst=ptf_intf_mac) exp_pkt /= IPv6(dst=ll_src_addr, src=generate_link_local_addr(dut_mac)) exp_pkt /= ICMPv6ND_NA(tgt=tgt_addr, S=1, R=1, O=0) exp_pkt /= ICMPv6NDOptSrcLLAddr(type=2, lladdr=dut_mac) exp_pkt = mask.Mask(exp_pkt) exp_pkt.set_do_not_care_scapy(packet.IPv6, 'fl') return ip_version, out_pkt, exp_pkt
def build_arp_ns_pkt(family, smac, src_ip, dst_ip): if family == 'IPv4': eth = Ether(src=smac, dst='ff:ff:ff:ff:ff:ff') pkt = eth/ARP(op='who-has', pdst=dst_ip) elif family == 'IPv6': nsma = in6_getnsma(inet_pton(AF_INET6, dst_ip)) mcast_dst_ip = inet_ntop(AF_INET6, nsma) dmac = in6_getnsmac(nsma) eth = Ether(src=smac,dst=dmac) ipv6 = IPv6(src=src_ip, dst=mcast_dst_ip) ns = ICMPv6ND_NS(tgt=dst_ip) ns_opt = ICMPv6NDOptSrcLLAddr(lladdr=smac) pkt = eth/ipv6/ns/ns_opt return pkt
def build_arp_ns_pkt(family, smac, src_ip, dst_ip): if family == 'IPv4': eth = Ether(src=smac, dst='ff:ff:ff:ff:ff:ff') pkt = eth/ARP(op=ARP.who_has, pdst=dst_ip) elif family == 'IPv6': nsma = in6_getnsma(inet_pton(AF_INET6, dst_ip)) mcast_dst_ip = inet_ntop(AF_INET6, nsma) dmac = in6_getnsmac(nsma) eth = Ether(src=smac,dst=dmac) ipv6 = IPv6(src=src_ip, dst=mcast_dst_ip) ns = ICMPv6ND_NS(tgt=dst_ip) ns_opt = ICMPv6NDOptSrcLLAddr(lladdr=smac) pkt = eth/ipv6/ns/ns_opt return pkt
def ipv6_packets_for_test(ip_and_intf_info, fake_src_mac, fake_src_addr): _, _, src_addr_v6, _, _ = ip_and_intf_info fake_src_mac = fake_src_mac tgt_addr = increment_ipv6_addr(src_addr_v6) multicast_tgt_addr = in6_getnsma(inet_pton(socket.AF_INET6, tgt_addr)) multicast_tgt_mac = in6_getnsmac(multicast_tgt_addr) ns_pkt = Ether(src=fake_src_mac, dst=multicast_tgt_mac) ns_pkt /= IPv6(dst=inet_ntop(socket.AF_INET6, multicast_tgt_addr), src=fake_src_addr) ns_pkt /= ICMPv6ND_NS(tgt=tgt_addr) ns_pkt /= ICMPv6NDOptSrcLLAddr(lladdr=fake_src_mac) logging.info(repr(ns_pkt)) return ns_pkt