internal static void ProcessDHCPv6Request(byte[] data, string clientIP, int clientPort, string sourceIP, int sourcePort)
        {
            DHCPv6Packet   packet   = new DHCPv6Packet(data);
            DHCPv6Listener listener = new DHCPv6Listener();

            if (packet.Message?.MsgType == 1 || packet.Message?.MsgType == 3 || packet.Message?.MsgType == 5)
            {
                bool isMicrosoft = false;

                if (packet.Option16?.EnterpriseNumber == 311)
                {
                    isMicrosoft = true;
                }

                byte   msgType = 0;
                string leaseIP = "";

                switch (packet.Message.MsgType)
                {
                case 1:
                    msgType = 2;
                    break;

                case 3:
                {
                    byte[] renewIP = new DHCPv6Option5(packet.Option3.IANAOptions).IPv6Address;
                    leaseIP = new IPAddress(renewIP).ToString();
                    msgType = 7;
                }
                break;

                case 5:
                {
                    byte[] renewIP = new DHCPv6Option5(packet.Option3.IANAOptions).IPv6Address;
                    leaseIP = new IPAddress(renewIP).ToString();
                    msgType = 7;
                }
                break;
                }

                DHCPv6DUIDLL duid          = new DHCPv6DUIDLL(packet.Option1.DUID);
                byte[]       clientMACData = new DHCPv6DUIDLL(packet.Option1.DUID).LinkLayerAddress;

                if (duid.DUIDType == 1)
                {
                    clientMACData = new DHCPv6DUIDLLT(packet.Option1.DUID).LinkLayerAddress;
                }

                string clientMAC      = BitConverter.ToString(clientMACData).Replace("-", ":");
                string clientHostName = "";

                if (!String.IsNullOrEmpty(packet.Option39?.DomainName))
                {
                    clientHostName = packet.Option39.DomainName;
                }

                if (listener.Check(clientMAC, clientHostName, Program.argMAC, isMicrosoft, out string message))
                {
                    if (msgType == 2)
                    {
                        leaseIP = "fe80::" + Program.dhcpv6Random + ":" + Program.dhcpv6IPIndex;
                        Program.dhcpv6IPIndex++;
                    }

                    byte[] buffer = new DHCPv6Packet().GetBytes(msgType, leaseIP, Program.argMAC, Program.argSpooferIPv6, Program.argDNSSuffix, uint.Parse(Program.argDHCPv6TTL), packet);

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

                Output.DHCPv6Output(packet.Message.MsgType, leaseIP, clientIP, clientMAC, clientHostName, 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();
            }
        }