"""Vulnerability mixin for LLMNR-related issues.

Detects vulnerable LLMNR behaviors from captured DNS-like traffic.
"""
from __future__ import annotations

from ptnetinspector.vulnerability.dns_helpers import contains_dns_qtype, contains_dns_type, dns_record_types_no_ptr


class LLMNRMixin:
    def store_llmnr_vulnerability(self) -> None:
        role_dict = self.read_role_dict(self.role_file)
        if not role_dict:
            return

        ipver_values = self._get_ipver_values()
        if not ipver_values:
            return

        non_ptr_types = dns_record_types_no_ptr()

        llmnr_std_query = (
            lambda p, m, sm: "dport = 5355" in p
            and "qr = 0" in p
            and m == sm
            and contains_dns_qtype(p, non_ptr_types)
        )
        llmnr_std_response = (
            lambda p, m: "dport = 5355" in p
            and "qr = 1" in p
            and (contains_dns_qtype(p, non_ptr_types) or contains_dns_type(p, non_ptr_types))
        )

        llmnr_ptr_query = (
            lambda p, m, sm: "dport = 5355" in p and "qr = 0" in p and m == sm and "qtype = PTR" in p
        )
        llmnr_ptr_response = lambda p, m: "dport = 5355" in p and "qr = 1" in p and "qtype = PTR" in p

        for ipver_value in ipver_values:
            if ipver_value == "4":
                std_device_code = "PTV-NET-IDENT-4-LLMNRDEV"
                std_device_desc = "Device responds to IPv4 LLMNR standard DNS record queries"
                std_net_code = "PTV-NET-IDENT-4-LLMNR"
                std_net_desc = "Network allows the delivery of IPv4 LLMNR standard DNS record queries"
            else:
                std_device_code = "PTV-NET-IDENT-6-LLMNRDEV"
                std_device_desc = "Device responds to IPv6 LLMNR standard DNS record queries"
                std_net_code = "PTV-NET-IDENT-6-LLMNR"
                std_net_desc = "Network allows the delivery of IPv6 LLMNR standard DNS record queries"

            self._process_query_response_vulnerability(
                llmnr_std_query,
                llmnr_std_response,
                role_dict,
                [ipver_value],
                std_device_code,
                std_device_desc,
                std_net_code,
                std_net_desc,
            )

            if ipver_value == "4":
                ptr_device_code = "PTV-NET-IDENT-4-LLMNR-PTRDEV"
                ptr_device_desc = "Device responds to IPv4 LLMNR PTR packets"
                ptr_net_code = "PTV-NET-IDENT-4-LLMNR-PTR"
                ptr_net_desc = "Network allows the delivery of IPv4 LLMNR PTR packets"
            else:
                ptr_device_code = "PTV-NET-IDENT-6-LLMNR-PTRDEV"
                ptr_device_desc = "Device responds to IPv6 LLMNR PTR packets"
                ptr_net_code = "PTV-NET-IDENT-6-LLMNR-PTR"
                ptr_net_desc = "Network allows the delivery of IPv6 LLMNR PTR packets"

            self._process_query_response_vulnerability(
                llmnr_ptr_query,
                llmnr_ptr_response,
                role_dict,
                [ipver_value],
                ptr_device_code,
                ptr_device_desc,
                ptr_net_code,
                ptr_net_desc,
            )
