internal static void ProcessMDNSRequest(byte[] data, string clientIP, int clientPort, string sourceIP, int sourcePort)
        {
            MDNSPacket   packet        = new MDNSPacket(data);
            MDNSListener listener      = new MDNSListener();
            string       destinationIP = clientIP;

            if (packet.Header.IsQuery())
            {
                if (listener.Check(packet.Question.Name, packet.Question.QuestionType, packet.Question.Type, clientIP, out string message))
                {
                    if (packet.Question.QuestionType.Equals("QM") && !Program.enabledMDNSUnicast && string.Equals(IPAddress.Parse(clientIP).AddressFamily.ToString(), "InterNetwork"))
                    {
                        destinationIP = "224.0.0.251";
                    }
                    else if (packet.Question.QuestionType.Equals("QM") && !Program.enabledMDNSUnicast && string.Equals(IPAddress.Parse(clientIP).AddressFamily.ToString(), "InterNetworkV6"))
                    {
                        destinationIP = "ff02::fb";
                    }

                    byte[] buffer = packet.GetBytes(uint.Parse(Program.argMDNSTTL), Program.argSpooferIP, Program.argSpooferIPv6);

                    if (!Utilities.ArrayIsNullOrEmpty(buffer))
                    {
                        UDPSocket.SendTo(destinationIP, clientPort, sourceIP, sourcePort, buffer, false);
                    }
                }

                string type = string.Concat(packet.Question.QuestionType, ")(", packet.Question.Type);
                Output.SpooferOutput("mDNS", type, packet.Question.Name, clientIP, message);
            }
        }
        public static void StartThreads()
        {
            if (Program.enabledSniffer)
            {
                if (Program.enabledIPv4)
                {
                    if (Program.enabledDNS || Program.enabledMDNS || Program.enabledLLMNR || Program.enabledNBNS || Program.enabledSMB)
                    {
                        Thread snifferSpooferThread = new Thread(() => Sniffer.Start("IP", Program.argSnifferIP, false));
                        snifferSpooferThread.Start();
                    }
                }

                if (Program.enabledIPv6)
                {
                    if (Program.enabledDHCPv6 || Program.enabledDNS || Program.enabledLLMNR || Program.enabledMDNS)
                    {
                        Thread snifferSpooferIPv6Thread = new Thread(() => Sniffer.Start("UDP", Program.argSnifferIPv6, true));
                        snifferSpooferIPv6Thread.Start();
                    }

                    if (Program.enabledSMB)
                    {
                        Thread snifferSpooferIPv6TCPThread = new Thread(() => Sniffer.Start("TCP", Program.argSnifferIPv6, true));
                        snifferSpooferIPv6TCPThread.Start();
                    }
                }
            }
            else
            {
                if (Program.enabledIPv4)
                {
                    if (Program.enabledDNS)
                    {
                        DNSListener dnsListener       = new DNSListener(uint.Parse(Program.argDNSTTL), Program.argDNSHost);
                        Thread      dnsListenerThread = new Thread(() => dnsListener.Start(IPAddress.Parse(Program.argListenerIP), Program.argSpooferIP, Program.argSpooferIPv6));
                        dnsListenerThread.Start();
                    }

                    if (Program.enabledLLMNR)
                    {
                        LLMNRListener llmnrListener       = new LLMNRListener(uint.Parse(Program.argLLMNRTTL));
                        Thread        llmnrListenerThread = new Thread(() => llmnrListener.Start(IPAddress.Parse(Program.argListenerIP), Program.argSpooferIP, Program.argSpooferIPv6));
                        llmnrListenerThread.Start();
                    }

                    if (Program.enabledMDNS)
                    {
                        MDNSListener mdnsListener       = new MDNSListener(uint.Parse(Program.argMDNSTTL), Program.enabledMDNSUnicast);
                        Thread       mdnsListenerThread = new Thread(() => mdnsListener.Start(IPAddress.Parse(Program.argListenerIP), Program.argSpooferIP, Program.argSpooferIPv6));
                        mdnsListenerThread.Start();
                    }

                    if (Program.enabledNBNS)
                    {
                        NBNSListener nbnsListener       = new NBNSListener(uint.Parse(Program.argNBNSTTL));
                        Thread       nbnsListenerThread = new Thread(() => nbnsListener.Start(IPAddress.Parse(Program.argListenerIP), Program.argSpooferIP, Program.argSpooferIPv6));
                        nbnsListenerThread.Start();
                    }

                    if (Program.enabledSMB)
                    {
                        foreach (string port in Program.argSMBPorts)
                        {
                            SMBListener smbListener = new SMBListener
                            {
                                Challenge     = Program.argChallenge,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread smbListenerThread = new Thread(() => smbListener.Start(IPAddress.Parse(Program.argListenerIP), Int32.Parse(port)));
                            smbListenerThread.Start();
                        }
                    }
                }

                if (Program.enabledIPv6)
                {
                    if (Program.enabledDHCPv6)
                    {
                        DHCPv6Listener dhcpV6Listener       = new DHCPv6Listener(uint.Parse(Program.argDHCPv6TTL), Program.argDNSSuffix);
                        Thread         dhcpv6ListenerThread = new Thread(() => dhcpV6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Program.argMAC, Program.argSpooferIPv6));
                        dhcpv6ListenerThread.Start();
                    }

                    if (Program.enabledDNS)
                    {
                        DNSListener dnsV6Listener       = new DNSListener(uint.Parse(Program.argDNSTTL), Program.argDNSHost);
                        Thread      dnsV6ListenerThread = new Thread(() => dnsV6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Program.argSpooferIP, Program.argSpooferIPv6));
                        dnsV6ListenerThread.Start();
                    }

                    if (Program.enabledLLMNR)
                    {
                        LLMNRListener llmnrV6Listener       = new LLMNRListener(uint.Parse(Program.argLLMNRTTL));
                        Thread        llmnrV6ListenerThread = new Thread(() => llmnrV6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Program.argSpooferIP, Program.argSpooferIPv6));
                        llmnrV6ListenerThread.Start();
                    }

                    if (Program.enabledMDNS)
                    {
                        MDNSListener mdnsV6Listener       = new MDNSListener(uint.Parse(Program.argMDNSTTL), Program.enabledMDNSUnicast);
                        Thread       mdnsV6ListenerThread = new Thread(() => mdnsV6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Program.argSpooferIP, Program.argSpooferIPv6));
                        mdnsV6ListenerThread.Start();
                    }

                    if (Program.enabledSMB)
                    {
                        foreach (string port in Program.argSMBPorts)
                        {
                            SMBListener smbv6Listener = new SMBListener
                            {
                                Challenge     = Program.argChallenge,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread smbv6ListenerThread = new Thread(() => smbv6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Int32.Parse(port)));
                            smbv6ListenerThread.Start();
                        }
                    }
                }
            }

            if (!Program.enabledInspect)
            {
                if (Program.enabledIPv4)
                {
                    if (Program.enabledHTTP)
                    {
                        foreach (string port in Program.argHTTPPorts)
                        {
                            HTTPListener httpListener = new HTTPListener
                            {
                                Challenge     = Program.argChallenge,
                                EnabledWebDAV = true,
                                IgnoreAgents  = Program.argIgnoreAgents,
                                HTTPAuth      = Program.argHTTPAuth,
                                WebDAVAuth    = Program.argWebDAVAuth,
                                WPADAuth      = Program.argWPADAuth,
                                HTTPRealm     = Program.argHTTPRealm,
                                HTTPResponse  = Program.argHTTPResponse,
                                WPADResponse  = Program.argWPADResponse,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread httpListenerThread = new Thread(() => httpListener.Start(IPAddress.Parse(Program.argListenerIP), Int32.Parse(port), "HTTP"));
                            httpListenerThread.Start();
                        }
                    }

                    if (Program.enabledHTTPS)
                    {
                        foreach (string port in Program.argHTTPSPorts)
                        {
                            HTTPListener httpsListener = new HTTPListener
                            {
                                Challenge     = Program.argChallenge,
                                Cert          = Program.argCert,
                                CertPassword  = Program.argCertPassword,
                                EnabledWebDAV = true,
                                IgnoreAgents  = Program.argIgnoreAgents,
                                HTTPAuth      = Program.argHTTPAuth,
                                WebDAVAuth    = Program.argWebDAVAuth,
                                WPADAuth      = Program.argWPADAuth,
                                HTTPRealm     = Program.argHTTPRealm,
                                HTTPResponse  = Program.argHTTPResponse,
                                WPADResponse  = Program.argWPADResponse,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread httpsListenerThread = new Thread(() => httpsListener.Start(IPAddress.Parse(Program.argListenerIP), Int32.Parse(port), "HTTPS"));
                            httpsListenerThread.Start();
                        }
                    }

                    if (Program.enabledLDAP)
                    {
                        foreach (string port in Program.argLDAPPorts)
                        {
                            LDAPListener ldapListener = new LDAPListener
                            {
                                Challenge     = Program.argChallenge,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread ldapListenerThread = new Thread(() => ldapListener.Start(IPAddress.Parse(Program.argListenerIP), Int32.Parse(port)));
                            ldapListenerThread.Start();
                        }
                    }

                    if (Program.enabledProxy)
                    {
                        HTTPListener proxyListener = new HTTPListener
                        {
                            Challenge     = Program.argChallenge,
                            EnabledWebDAV = false,
                            IgnoreAgents  = Program.argIgnoreAgents,
                            HTTPAuth      = Program.argHTTPAuth,
                            WebDAVAuth    = Program.argWebDAVAuth,
                            WPADAuth      = Program.argWPADAuth,
                            HTTPRealm     = Program.argHTTPRealm,
                            HTTPResponse  = Program.argHTTPResponse,
                            WPADResponse  = Program.argWPADResponse,
                            NetbiosDomain = Program.netbiosDomain,
                            ComputerName  = Program.computerName,
                            DNSDomain     = Program.dnsDomain
                        };

                        Thread proxyListenerThread = new Thread(() => proxyListener.Start(IPAddress.Parse(Program.argListenerIP), Int32.Parse(Program.argProxyPort), "Proxy"));
                        proxyListenerThread.Start();
                    }
                }

                if (Program.enabledIPv6)
                {
                    if (Program.enabledLDAP)
                    {
                        foreach (string port in Program.argLDAPPorts)
                        {
                            LDAPListener ldapv6Listener = new LDAPListener
                            {
                                Challenge     = Program.argChallenge,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread ldapv6ListenerThread = new Thread(() => ldapv6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Int32.Parse(port)));
                            ldapv6ListenerThread.Start();
                        }
                    }

                    if (Program.enabledHTTP)
                    {
                        foreach (string port in Program.argHTTPPorts)
                        {
                            HTTPListener httpv6Listener = new HTTPListener
                            {
                                Challenge     = Program.argChallenge,
                                EnabledWebDAV = true,
                                IgnoreAgents  = Program.argIgnoreAgents,
                                HTTPAuth      = Program.argHTTPAuth,
                                WebDAVAuth    = Program.argWebDAVAuth,
                                WPADAuth      = Program.argWPADAuth,
                                HTTPRealm     = Program.argHTTPRealm,
                                HTTPResponse  = Program.argHTTPResponse,
                                WPADResponse  = Program.argWPADResponse,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread httpv6ListenerThread = new Thread(() => httpv6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Int32.Parse(port), "HTTPv6"));
                            httpv6ListenerThread.Start();
                        }
                    }

                    if (Program.enabledHTTPS)
                    {
                        foreach (string port in Program.argHTTPPorts)
                        {
                            HTTPListener httpsv6Listener = new HTTPListener
                            {
                                Challenge     = Program.argChallenge,
                                Cert          = Program.argCert,
                                CertPassword  = Program.argCertPassword,
                                EnabledWebDAV = true,
                                IgnoreAgents  = Program.argIgnoreAgents,
                                HTTPAuth      = Program.argHTTPAuth,
                                WebDAVAuth    = Program.argWebDAVAuth,
                                WPADAuth      = Program.argWPADAuth,
                                HTTPRealm     = Program.argHTTPRealm,
                                HTTPResponse  = Program.argHTTPResponse,
                                WPADResponse  = Program.argWPADResponse,
                                NetbiosDomain = Program.netbiosDomain,
                                ComputerName  = Program.computerName,
                                DNSDomain     = Program.dnsDomain
                            };

                            Thread httpsv6ListenerThread = new Thread(() => httpsv6Listener.Start(IPAddress.Parse(Program.argListenerIPv6), Int32.Parse(port), "HTTPSv6"));
                            httpsv6ListenerThread.Start();
                        }
                    }

                    if (Program.enabledICMPv6) // todo check linux
                    {
                        ICMPv6Socket icmpV6Socket = new ICMPv6Socket();
                        Thread       icmpv6Thread = new Thread(() => icmpV6Socket.Start());
                        icmpv6Thread.Start();
                    }
                }
            }

            Thread controlThread = new Thread(() => ControlLoop(Program.argConsole, Program.consoleQueueLimit, Program.consoleStatus, Program.runCount, Program.runTime));

            controlThread.Start();

            if (Program.enabledFileOutput)
            {
                Thread fileOutputThread = new Thread(() => Output.FileOutput());
                fileOutputThread.Start();
            }
        }