internal static void ProcessDNSRequest(byte[] data, string clientIP, int clientPort, string sourceIP, int sourcePort)
        {
            DNSPacket packet = new DNSPacket(data)
            {
                Host = Program.argDNSHost,
                TTL  = uint.Parse(Program.argDNSTTL)
            };

            DNSListener listener = new DNSListener(UInt32.Parse(Program.argDNSTTL));

            if (!packet.Header.IsDynamicUpdateRequest())
            {
                if (packet.Header.IsQuery())
                {
                    if (listener.Check(packet.Question.Name, packet.Question.Type, clientIP, out string message))
                    {
                        byte[] buffer = packet.GetBytes(UInt32.Parse(Program.argDNSTTL), Program.dnsSerial, Program.argSpooferIP, Program.argSpooferIPv6);

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

                    Output.SpooferOutput("DNS", packet.Question.Type, packet.Question.Name, clientIP, message);
                }
            }
            else
            {
                byte[] flags = new byte[2] {
                    0xa8, 0x05
                };
                byte[] dnsPayload = new byte[data.Length - 2];
                System.Buffer.BlockCopy(data, 2, dnsPayload, 0, dnsPayload.Length);
                MemoryStream dnsMemoryStream = new MemoryStream();
                dnsMemoryStream.Write(data, 0, data.Length);
                dnsMemoryStream.Position = 2;
                dnsMemoryStream.Write(flags, 0, 2);
                UDPSocket.SendTo(clientIP, clientPort, sourceIP, sourcePort, dnsMemoryStream.ToArray(), false);
            }
        }
        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();
            }
        }