def SendRA(cls, netid, retranstimer=None, reachabletime=0): validity = 300 # seconds macaddr = cls.RouterMacAddress(netid) lladdr = cls._RouterAddress(netid, 6) if retranstimer is None: # If no retrans timer was specified, pick one that's as long as the # router lifetime. This ensures that no spurious ND retransmits # will interfere with test expectations. retranstimer = validity # We don't want any routes in the main table. If the kernel doesn't support # putting RA routes into per-interface tables, configure routing manually. routerlifetime = validity if HAVE_AUTOCONF_TABLE else 0 ra = (scapy.Ether(src=macaddr, dst="33:33:00:00:00:01") / scapy.IPv6(src=lladdr, hlim=255) / scapy.ICMPv6ND_RA(reachabletime=reachabletime, retranstimer=retranstimer, routerlifetime=routerlifetime) / scapy.ICMPv6NDOptSrcLLAddr(lladdr=macaddr) / scapy.ICMPv6NDOptPrefixInfo(prefix=cls.IPv6Prefix(netid), prefixlen=64, L=1, A=1, validlifetime=validity, preferredlifetime=validity)) posix.write(cls.tuns[netid].fileno(), str(ra))
def create_ra(dst=None): ether_head = scapy.Ether(src=router_mac, dst=dst) ipv6_head = scapy.IPv6() ipv6_head.dest = 'ff02::1' ipv6_head.src = mac2ipv6(router_mac) ipv6_ra = scapy.ICMPv6ND_RA() ipv6_nd_pref = scapy.ICMPv6NDOptPrefixInfo() ipv6_nd_pref.prefix = ipv6_nd_prefix ipv6_nd_pref.prefixlen = 64 # Valid-Lifetime 2h ipv6_nd_pref.validlifetime = 7200 # Preferred-Lifetime 30min ipv6_nd_pref.preferredlifetime = 1800 # ICMPv6-Option: Route Information o_route = scapy.ICMPv6NDOptRouteInfo() # Default Route o_route.prefix = '::' # Prefix length in bit o_route.plen = 0 # Same value as the Preferred-Lifetime of the Router o_route.rtlifetime = 1800 # ICMPv6-Option: Recursive DNS Server o_rdns = scapy.ICMPv6NDOptRDNSS() # List of DNS Server Addresses o_rdns.dns = router_dns # Same value as the Preferred-Lifetime of the Router o_rdns.lifetime = 1800 # ICMPv6-Option: Source Link Layer Address o_mac = scapy.ICMPv6NDOptSrcLLAddr() # MAC address o_mac.lladdr = router_mac ra = (ether_head / ipv6_head / ipv6_ra / ipv6_nd_pref / o_route / o_rdns / o_mac) return ra
def generate(self, lifetime, enableDNS=False, dns_lifetime=0, ip_dst=None, eth_dst=None): """Generates a Router Advertisement (RA) packet (ICMP over IPv6). Args: lifetime: RA lifetime enableDNS: Add RDNSS option to RA (Optional) dns_lifetime: Set DNS server lifetime (Optional) ip_dst: IPv6 destination address (Optional) eth_dst: Ethernet (layer 2) destination address (Optional) """ # Overwrite standard fields if desired ip6_dst = (ip_dst if ip_dst is not None else RA_IP) hw_dst = (eth_dst if eth_dst is not None else RA_MAC) # Create IPv6 layer base = scapy.IPv6(dst=ip6_dst, src=self.src_ipv6) router_solicitation = scapy.ICMPv6ND_RA(routerlifetime=lifetime) src_ll_addr = scapy.ICMPv6NDOptSrcLLAddr(lladdr=self.src_mac) prefix = scapy.ICMPv6NDOptPrefixInfo(prefixlen=RA_PREFIX_LEN, prefix=RA_PREFIX) if enableDNS: rndss = scapy.ICMPv6NDOptRDNSS(lifetime=dns_lifetime, dns=[self.src_ipv6], len=DNS_LEN) ip6 = base / router_solicitation / src_ll_addr / prefix / rndss else: ip6 = base / router_solicitation / src_ll_addr / prefix # Create Ethernet layer ethernet = scapy.Ether(src=self.src_mac, dst=hw_dst) self.packet = ethernet / ip6 return self.packet