def SendRA(cls, netid, retranstimer=None, reachabletime=0, options=()): validity = cls.RA_VALIDITY # 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 * 1000 # Lifetime is in s, retrans timer in ms. # 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.OnlinkPrefix(6, netid), prefixlen=cls.OnlinkPrefixLen(6), L=1, A=1, validlifetime=validity, preferredlifetime=validity)) for option in options: ra /= option posix.write(cls.tuns[netid].fileno(), str(ra))
def send(dstmac, interval, count, lifetime, iface): """Generate IPv6 Router Advertisement and send to destination. @param dstmac: string HWAddr of the destination ipv6 node. @param interval: int Time to sleep between consecutive packets. @param count: int Number of packets to be sent. @param lifetime: Router lifetime value for the original RA. @param iface: string Router's WiFi interface to send packets over. """ while count: ra = (scapy.Ether(dst=dstmac) / scapy.IPv6() / scapy.ICMPv6ND_RA(routerlifetime=lifetime)) scapy.sendp(ra, iface=iface) count = count - 1 time.sleep(interval) lifetime = lifetime - interval
def send(dstmac, interval, count, lifetime, iface, rtt): """Generate IPv6 Router Advertisement and send to destination. Args: 1. dstmac: string HWAddr of the destination ipv6 node. 2. interval: int Time to sleep between consecutive packets. 3. count: int Number of packets to be sent. 4. lifetime: Router lifetime value for the original RA. 5. iface: string Router's WiFi interface to send packets over. 6. rtt: retrans timer in the RA packet """ while count: ra = (scapy.Ether(dst=dstmac) / scapy.IPv6() / scapy.ICMPv6ND_RA(routerlifetime=lifetime, retranstimer=rtt)) scapy.sendp(ra, iface=iface) count = count - 1 time.sleep(interval) lifetime = lifetime - interval
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