Example #1
0
        /// <summary>
        /// Main entry point of the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest   = Log.Destinations.EventLog;
            Log.Level  = EventLogEntryType.Information;

            int    i          = 0;
            string command    = null;
            string user       = null;
            ulong  maxmem     = 0;
            string address    = null;
            long   expiration = 0;
            UInt64 weight     = 0;
            bool   permit     = false;
            bool   persistent = false;
            UInt64 filterId   = 0;

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper())
                        {
                        case "INFORMATION":
                        case "INFO":
                            Log.Level = EventLogEntryType.Information;
                            break;

                        case "WARNING":
                        case "WARN":
                            Log.Level = EventLogEntryType.Warning;
                            break;

                        case "ERROR":
                            Log.Level = EventLogEntryType.Error;
                            break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
                else if (param == "-a" || param == "-address" || param == "--address")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        address = args[i];
                    }
                }
                else if (param == "-e" || param == "-expiration" || param == "--expiration")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        expiration = long.Parse(args[i]);
                    }
                }
                else if (param == "-w" || param == "-weight" || param == "--weight")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        weight = UInt64.Parse(args[i]);
                    }
                }
                else if (param == "-t" || param == "-permit" || param == "--permit")
                {
                    permit = true;
                }
                else if (param == "-s" || param == "-persistent" || param == "--persistent")
                {
                    persistent = true;
                }
                else if (param == "-f" || param == "-filter-id" || param == "--filter-id")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        filterId = UInt64.Parse(args[i]);
                    }
                }
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BFwCmd in interactive mode executing command: " + command);
            }

            if (true)
            {
                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "list-wfp")
                {
                    Log.Info("Dump F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.DumpWFP();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-wfp")
                {
                    Log.Info("Adding F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.Install();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-wfp")
                {
                    Log.Info("Removing F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.Uninstall();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "list-privileges")
                {
                    Log.Info("List F2B WFP privileges");
                    try
                    {
                        F2B.Firewall.Instance.DumpPrivileges();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-privileges")
                {
                    if (user != null)
                    {
                        Log.Info("Adding privileges to modify F2B firewall rules to account " + user);
                        try
                        {
                            F2B.Firewall.Instance.AddPrivileges(F2B.Sid.Get(user));
                        }
                        catch (FirewallException ex)
                        {
                            Log.Error(ex.Message);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        Console.WriteLine("ERROR: missing user argument");
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-privileges")
                {
                    if (user != null)
                    {
                        Log.Info("Removing privileges to modify F2B firewall rules from account " + user);
                        try
                        {
                            F2B.Firewall.Instance.RemovePrivileges(F2B.Sid.Get(user));
                        }
                        catch (FirewallException ex)
                        {
                            Log.Error(ex.Message);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        Console.WriteLine("ERROR: missing user argument");
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "list-filters")
                {
                    try
                    {
                        var details = F2B.Firewall.Instance.List(true);
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple <long, byte[]> fwname = FwData.DecodeName(item.Value);
                                string tmp = Convert.ToString(fwname.Item1);
                                try
                                {
                                    DateTime tmpExp = new DateTime(fwname.Item1, DateTimeKind.Utc);
                                    tmp = tmpExp.ToLocalTime().ToString();
                                }
                                catch (Exception)
                                {
                                }
                                Console.WriteLine("{0}: {1} (expiration={2}, md5={3}) ... {4}",
                                                  item.Key, item.Value, tmp,
                                                  BitConverter.ToString(fwname.Item2).Replace("-", ":"),
                                                  details.ContainsKey(item.Key) ? details[item.Key] : "");
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Console.WriteLine("{0}: {1}", item.Key, item.Value);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to list firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-filters")
                {
                    try
                    {
                        F2B.Firewall.Instance.Cleanup();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove all firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-expired-filters")
                {
                    long currTime = DateTime.UtcNow.Ticks;

                    try
                    {
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple <long, byte[]> fwname = FwData.DecodeName(item.Value);
                                if (currTime > fwname.Item1)
                                {
                                    Log.Info("Remove expired filter #" + item.Key
                                             + " (expiration=" + fwname.Item1 + ", md5="
                                             + BitConverter.ToString(fwname.Item2).Replace("-", ":")
                                             + ")");
                                    F2B.Firewall.Instance.Remove(item.Key);
                                }
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Log.Info("Unable to parse expiration time from filter #" + item.Key);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove expired firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-unknown-filters")
                {
                    try
                    {
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple <long, byte[]> fwname = FwData.DecodeName(item.Value);
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Log.Info("Remove filter #" + item.Key + " with unparsable filter name: " + item.Value);
                                F2B.Firewall.Instance.Remove(item.Key);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove unknown firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-filter")
                {
                    if (address == null)
                    {
                        Console.WriteLine("ERROR: missing address argument");
                        Environment.Exit(1);
                    }

                    IPAddress addr;
                    int       prefix = 128;
                    if (address.IndexOf('/') > 0)
                    {
                        if (!IPAddress.TryParse(address.Substring(0, address.IndexOf('/')), out addr) || !int.TryParse(address.Substring(address.IndexOf('/') + 1), out prefix))
                        {
                            Console.WriteLine("ERROR: unable to parse address " + address);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        if (!IPAddress.TryParse(address, out addr))
                        {
                            Console.WriteLine("ERROR: unable to parse address " + address);
                            Environment.Exit(1);
                        }
                    }

                    try
                    {
                        if (expiration == 0)
                        {
                            string filterName  = "F2B " + (permit ? "permit " : "block ") + address + " with no expiration" + (persistent ? " (persistent rule)" : "");
                            UInt64 filterIdNew = F2B.Firewall.Instance.Add(filterName, addr, prefix, weight, permit, persistent);
                            Log.Info("Added new filter #" + filterIdNew + " with name: " + filterName);
                        }
                        else
                        {
                            FwData fwdata = new FwData(expiration, addr, prefix);

                            // This code doesn't enumerate and check existing F2B firewall rules,
                            // but it must be updated together with changes in FwManager ... so
                            // to get consistent behavior in future it is better to use directly
                            // less optimal function from FwManager
                            //
                            //byte[] hash = fwdata.Hash;
                            //FirewallConditions conds = fwdata.Conditions();
                            //
                            //// IPv4 filter layer
                            //if (conds.HasIPv4() || (!conds.HasIPv4() && !conds.HasIPv6()))
                            //{
                            //    byte[] hash4 = new byte[hash.Length];
                            //    hash.CopyTo(hash4, 0);
                            //    hash4[hash4.Length - 1] &= 0xfe;
                            //    string filterName = FwData.EncodeName(expiration, hash4);
                            //    UInt64 filterIdNew = F2B.Firewall.Instance.AddIPv4(filterName, conds);
                            //    Log.Info("Added new IPv4 filter #" + filterIdNew + " for " + addr + "/" + prefix + " with encoded name: " + filterName);
                            //}
                            //
                            //// IPv6 filter layer
                            //if (conds.HasIPv6() || (!conds.HasIPv4() && !conds.HasIPv6()))
                            //{
                            //    byte[] hash6 = new byte[hash.Length];
                            //    hash.CopyTo(hash6, 0);
                            //    hash6[hash6.Length - 1] |= 0x01;
                            //    string filterName = FwData.EncodeName(expiration, hash6);
                            //    UInt64 filterIdNew = F2B.Firewall.Instance.AddIPv4(filterName, conds);
                            //    Log.Info("Added new IPv6 filter #" + filterIdNew + " for " + addr + "/" + prefix + " with encoded name: " + filterName);
                            //}

                            FwManager.Instance.Add(fwdata, weight, permit, persistent);
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to add firewall filter: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-filter")
                {
                    if (filterId == 0)
                    {
                        Console.WriteLine("ERROR: missing filterId argument");
                        Environment.Exit(1);
                    }
                    try
                    {
                        F2B.Firewall.Instance.Remove(filterId);
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove firewall filter: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BFwCmd command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }

            Log.Info("F2BFwCmd main finished");
        }
Example #2
0
File: Program.cs Project: vokac/F2B
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest = Log.Destinations.EventLog;
            Log.Level = EventLogEntryType.Information;

            int i = 0;
            string command = null;
            string user = null;
            ulong maxmem = 0;
            #if DEBUG
            string dumpFile = @"c:\F2B\dump.txt";
            #endif

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper()) {
                            case "INFORMATION":
                            case "INFO":
                                Log.Level = EventLogEntryType.Information;
                                break;
                            case "WARNING":
                            case "WARN":
                                Log.Level = EventLogEntryType.Warning;
                                break;
                            case "ERROR":
                                Log.Level = EventLogEntryType.Error;
                                break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
            #if DEBUG
                else if (param == "-dump-file" || param == "--dump-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        dumpFile = args[i];
                    }
                }
            #endif
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            // Initialize the service to start
            ServiceBase[] servicesToRun;
            servicesToRun = new ServiceBase[]
            {
                new Service()
            };

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BLogAnalyzer in interactive mode executing command: " + command);

                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "run")
                {
                    // Get the method to invoke on each service to start it
                    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Start services loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Starting " + service.ServiceName + " ...");
                        onStartMethod.Invoke(service, new object[] { new string[] { } });
                    }

            #if DEBUG
                    Utils.DumpProcessInfo();
            #endif

                    // Waiting the end
                    string help = "Interactive help\n"
                        + "  press 'h' key for this help\n"
                        + "  press 'q' key to quit\n"
            #if DEBUG
                        + "  press 'd' key to write debug info\n"
            #endif
                        ;
                    Console.Write(help);
                    while (true)
                    {
                        ConsoleKeyInfo key = Console.ReadKey();
                        if (key.KeyChar == 'q')
                        {
                            Log.Info("Quit key pressed");
                            break;
                        }
                        else if (key.KeyChar == 'h')
                        {
                            Log.Info("Interactive help");
                            Console.Write(help);
                        }
            #if DEBUG
                        else if (key.KeyChar == 'd')
                        {
                            Log.Info("Debug key pressed");
                            Utils.DumpProcessInfo();
                            ((Service)servicesToRun[0]).Dump(dumpFile);
                        }
            #endif
                        else
                        {
                            Console.WriteLine("Unsupported key " + key.KeyChar);
                        }
                    }

                    // Get the method to invoke on each service to stop it
                    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Stop loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Stopping " + service.ServiceName + " ...");
                        onStopMethod.Invoke(service, null);
                    }

            #if DEBUG
                    Utils.DumpProcessInfo();
            #endif

                    Log.Info("Debug F2B service finished");
                }
                else if (command.ToLower() == "install" || command.ToLower() == "uninstall")
                {
                    List<string> l = new List<string>();
                    if ((Log.Dest & Log.Destinations.EventLog) != 0)
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                    }
                    if ((Log.Dest & Log.Destinations.File) != 0 && !string.IsNullOrEmpty(Log.File))
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                        l.Add(string.Format("f2bLogFile={0}", Log.File));
                    }
                    if (user != null)
                    {
                        l.Add(string.Format("f2bUser={0}", user));
                    }
                    if (ConfigFile != null)
                    {
                        l.Add(string.Format("f2bConfig={0}", ConfigFile));
                    }

                    if (command.ToLower() == "install") // Install
                    {
                        Log.Info("Installing " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { typeof(Program).Assembly.Location });
                        Install(false, l.ToArray());
                    }
                    else // Uninstall
                    {
                        //ManagedInstallerClass.InstallHelper(new String[] { "/u", typeof(Program).Assembly.Location });
                        Install(true, l.ToArray());
                    }
                }
                else if (command.ToLower() == "start")
                {
                    try
                    {
                        foreach (var service in servicesToRun)
                        {
                            ServiceController sc = new ServiceController(service.ServiceName);
                            if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not stopped, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "stop")
                {
                    try
                    {
                        foreach (var service in servicesToRun)
                        {
                            ServiceController sc = new ServiceController(service.ServiceName);
                            if (sc.Status == ServiceControllerStatus.Running)
                            {
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not running, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BLogAnalyzer command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }
            else
            {
                ServiceBase.Run(servicesToRun);
            }

            Log.Info("F2BLogAnalyzer main finished");
        }
Example #3
0
        /// <summary>
        /// Main entry point of the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest   = Log.Destinations.EventLog;
            Log.Level  = EventLogEntryType.Information;

            int    i                      = 0;
            string command                = null;
            string StateFile              = null;
            string user                   = null;
            ulong  maxmem                 = 0;
            string host                   = null;
            string producerQueue          = null;
            string registrationQueue      = null;
            int    unsubscribeInterval    = 150;
            int    cleanupExpiredInterval = 300;
            int    maxQueueSize           = 0;

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper())
                        {
                        case "INFORMATION":
                        case "INFO":
                            Log.Level = EventLogEntryType.Information;
                            break;

                        case "WARNING":
                        case "WARN":
                            Log.Level = EventLogEntryType.Warning;
                            break;

                        case "ERROR":
                            Log.Level = EventLogEntryType.Error;
                            break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-s" || param == "-state" || param == "--state")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        StateFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
                else if (param == "-H" || param == "-host" || param == "--host")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        host = args[i];
                    }
                }
                else if (param == "-p" || param == "-producer-queue" || param == "--producer-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        producerQueue = args[i];
                    }
                }
                else if (param == "-r" || param == "-registration-queue" || param == "--registration-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        registrationQueue = args[i];
                    }
                }
                else if (param == "-i" || param == "-registration-interval" || param == "--registration-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        unsubscribeInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-n" || param == "-cleanup-interval" || param == "--cleanup-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        cleanupExpiredInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-m" || param == "-max-size" || param == "--max-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxQueueSize = int.Parse(args[i]);
                    }
                }
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            string[] serviceNamesToRun = new string[]
            {
                Service.NAME,
            };

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BFirewall in interactive mode executing command: " + command);
            }

            if (Environment.UserInteractive && command.ToLower() != "run")
            {
                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "install" || command.ToLower() == "uninstall")
                {
                    List <string> l = new List <string>();
                    if ((Log.Dest & Log.Destinations.EventLog) != 0)
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                    }
                    if ((Log.Dest & Log.Destinations.File) != 0 && !string.IsNullOrEmpty(Log.File))
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                        l.Add(string.Format("f2bLogFile={0}", Log.File));
                    }
                    if (StateFile != null)
                    {
                        l.Add(string.Format("f2bState={0}", StateFile));
                    }
                    if (user != null)
                    {
                        l.Add(string.Format("f2bUser={0}", user));
                    }
                    if (host != null)
                    {
                        l.Add(string.Format("f2bHost={0}", host));
                    }
                    if (producerQueue != null)
                    {
                        l.Add(string.Format("f2bProducerQueue={0}", producerQueue));
                    }
                    if (registrationQueue != null)
                    {
                        l.Add(string.Format("f2bRegistrationQueue={0}", registrationQueue));
                    }
                    if (unsubscribeInterval != 0)
                    {
                        l.Add(string.Format("f2bRegistrationInterval={0}", unsubscribeInterval));
                    }
                    if (cleanupExpiredInterval != 0)
                    {
                        l.Add(string.Format("f2bCleanupExpiredInterval={0}", cleanupExpiredInterval));
                    }

                    if (command.ToLower() == "install") // Install
                    {
                        Log.Info("Installing " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { typeof(Program).Assembly.Location });
                        Install(false, l.ToArray());
                    }
                    else // Uninstall
                    {
                        //ManagedInstallerClass.InstallHelper(new String[] { "/u", typeof(Program).Assembly.Location });
                        Install(true, l.ToArray());
                    }
                }
                else if (command.ToLower() == "start")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not stopped, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "stop")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Running)
                            {
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not running, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BQueue command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }
            else
            {
                if (string.IsNullOrEmpty(host))
                {
                    Log.Error("Missing host command line argument");
                    //Usage();
                    Environment.Exit(1);
                }

                if (string.IsNullOrEmpty(producerQueue) || string.IsNullOrEmpty(registrationQueue))
                {
                    Log.Error("Both production and registration queue must be defined");
                    //Usage();
                    Environment.Exit(1);
                }

                if (!(unsubscribeInterval > 0))
                {
                    Log.Warn("Using application without unregistration interval is not optimal");
                }

                if (!(cleanupExpiredInterval > 0))
                {
                    Log.Warn("Running without specifying cleanup interval doesn't make too much sense");
                }

                // Initialize the service to start
                ServiceBase[] servicesToRun = new ServiceBase[]
                {
                    new Service(host, producerQueue, registrationQueue, unsubscribeInterval, cleanupExpiredInterval, maxQueueSize, StateFile),
                };

                if (!Environment.UserInteractive)
                {
                    // Start windows service
                    ServiceBase.Run(servicesToRun);
                }
                else // command.ToLower() == "run"
                {
                    // Get the method to invoke on each service to start it
                    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Start services loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Starting " + service.ServiceName + " ...");
                        onStartMethod.Invoke(service, new object[] { new string[] { } });
                    }

                    // Waiting the end
                    string help = "Interactive help\n"
                                  + "  press 'h' key for this help\n"
                                  + "  press 'q' key to quit\n"
#if DEBUG
                                  + "  press 'd' key to write debug info\n"
#endif
                    ;
                    Console.Write(help);
                    while (true)
                    {
                        ConsoleKeyInfo key = Console.ReadKey();
                        if (key.KeyChar == 'q')
                        {
                            Log.Info("Quit key pressed");
                            break;
                        }
                        else if (key.KeyChar == 'h')
                        {
                            Log.Info("Interactive help");
                            Console.Write(help);
                        }
#if DEBUG
                        else if (key.KeyChar == 'd')
                        {
                            Log.Info("Debug key pressed");
                            ((Service)servicesToRun[0]).Dump();
                        }
#endif
                        else
                        {
                            Console.WriteLine("Unsupported key " + key.KeyChar);
                        }
                    }

                    // Get the method to invoke on each service to stop it
                    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Stop loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Stopping " + service.ServiceName + " ...");
                        onStopMethod.Invoke(service, null);
                    }

                    Log.Info("Debug F2B service finished");
                }
            }

            Log.Info("F2BQueue main finished");
        }
Example #4
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest   = Log.Destinations.EventLog;
            Log.Level  = EventLogEntryType.Information;

            int    i       = 0;
            string command = null;
            string user    = null;
            ulong  maxmem  = 0;

#if DEBUG
            string dumpFile = @"c:\F2B\dump.txt";
#endif

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper())
                        {
                        case "INFORMATION":
                        case "INFO":
                            Log.Level = EventLogEntryType.Information;
                            break;

                        case "WARNING":
                        case "WARN":
                            Log.Level = EventLogEntryType.Warning;
                            break;

                        case "ERROR":
                            Log.Level = EventLogEntryType.Error;
                            break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
#if DEBUG
                else if (param == "-dump-file" || param == "--dump-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        dumpFile = args[i];
                    }
                }
#endif
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            // Initialize the service to start
            ServiceBase[] servicesToRun;
            servicesToRun = new ServiceBase[]
            {
                new Service()
            };

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BLogAnalyzer in interactive mode executing command: " + command);

                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "run")
                {
                    // Get the method to invoke on each service to start it
                    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Start services loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Starting " + service.ServiceName + " ...");
                        onStartMethod.Invoke(service, new object[] { new string[] { } });
                    }

#if DEBUG
                    Utils.DumpProcessInfo();
#endif

                    // Waiting the end
                    string help = "Interactive help\n"
                                  + "  press 'h' key for this help\n"
                                  + "  press 'q' key to quit\n"
#if DEBUG
                                  + "  press 'd' key to write debug info\n"
#endif
                    ;
                    Console.Write(help);
                    while (true)
                    {
                        ConsoleKeyInfo key = Console.ReadKey();
                        if (key.KeyChar == 'q')
                        {
                            Log.Info("Quit key pressed");
                            break;
                        }
                        else if (key.KeyChar == 'h')
                        {
                            Log.Info("Interactive help");
                            Console.Write(help);
                        }
#if DEBUG
                        else if (key.KeyChar == 'd')
                        {
                            Log.Info("Debug key pressed");
                            Utils.DumpProcessInfo();
                            ((Service)servicesToRun[0]).Dump(dumpFile);
                        }
#endif
                        else
                        {
                            Console.WriteLine("Unsupported key " + key.KeyChar);
                        }
                    }

                    // Get the method to invoke on each service to stop it
                    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Stop loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Stopping " + service.ServiceName + " ...");
                        onStopMethod.Invoke(service, null);
                    }

#if DEBUG
                    Utils.DumpProcessInfo();
#endif

                    Log.Info("Debug F2B service finished");
                }
                else if (command.ToLower() == "install" || command.ToLower() == "uninstall")
                {
                    List <string> l = new List <string>();
                    if ((Log.Dest & Log.Destinations.EventLog) != 0)
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                    }
                    if ((Log.Dest & Log.Destinations.File) != 0 && !string.IsNullOrEmpty(Log.File))
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                        l.Add(string.Format("f2bLogFile={0}", Log.File));
                    }
                    if (user != null)
                    {
                        l.Add(string.Format("f2bUser={0}", user));
                    }
                    if (ConfigFile != null)
                    {
                        l.Add(string.Format("f2bConfig={0}", ConfigFile));
                    }

                    if (command.ToLower() == "install") // Install
                    {
                        Log.Info("Installing " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { typeof(Program).Assembly.Location });
                        Install(false, l.ToArray());
                    }
                    else // Uninstall
                    {
                        //ManagedInstallerClass.InstallHelper(new String[] { "/u", typeof(Program).Assembly.Location });
                        Install(true, l.ToArray());
                    }
                }
                else if (command.ToLower() == "start")
                {
                    try
                    {
                        foreach (var service in servicesToRun)
                        {
                            ServiceController sc = new ServiceController(service.ServiceName);
                            if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not stopped, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "stop")
                {
                    try
                    {
                        foreach (var service in servicesToRun)
                        {
                            ServiceController sc = new ServiceController(service.ServiceName);
                            if (sc.Status == ServiceControllerStatus.Running)
                            {
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not running, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BLogAnalyzer command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }
            else
            {
                ServiceBase.Run(servicesToRun);
            }

            Log.Info("F2BLogAnalyzer main finished");
        }
Example #5
0
File: Program.cs Project: vokac/F2B
        /// <summary>
        /// Main entry point of the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest = Log.Destinations.EventLog;
            Log.Level = EventLogEntryType.Information;

            int i = 0;
            string command = null;
            string StateFile = null;
            string user = null;
            ulong maxmem = 0;
            string host = null;
            string producerQueue = null;
            string registrationQueue = null;
            int unsubscribeInterval = 150;
            int cleanupExpiredInterval = 300;
            int maxQueueSize = 0;

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper())
                        {
                            case "INFORMATION":
                            case "INFO":
                                Log.Level = EventLogEntryType.Information;
                                break;
                            case "WARNING":
                            case "WARN":
                                Log.Level = EventLogEntryType.Warning;
                                break;
                            case "ERROR":
                                Log.Level = EventLogEntryType.Error;
                                break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-s" || param == "-state" || param == "--state")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        StateFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
                else if (param == "-H" || param == "-host" || param == "--host")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        host = args[i];
                    }
                }
                else if (param == "-p" || param == "-producer-queue" || param == "--producer-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        producerQueue = args[i];
                    }
                }
                else if (param == "-r" || param == "-registration-queue" || param == "--registration-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        registrationQueue = args[i];
                    }
                }
                else if (param == "-i" || param == "-registration-interval" || param == "--registration-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        unsubscribeInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-n" || param == "-cleanup-interval" || param == "--cleanup-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        cleanupExpiredInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-m" || param == "-max-size" || param == "--max-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxQueueSize = int.Parse(args[i]);
                    }
                }
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            string[] serviceNamesToRun = new string[]
            {
                Service.NAME,
            };

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BFirewall in interactive mode executing command: " + command);
            }

            if (Environment.UserInteractive && command.ToLower() != "run")
            {
                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "install" || command.ToLower() == "uninstall")
                {
                    List<string> l = new List<string>();
                    if ((Log.Dest & Log.Destinations.EventLog) != 0)
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                    }
                    if ((Log.Dest & Log.Destinations.File) != 0 && !string.IsNullOrEmpty(Log.File))
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                        l.Add(string.Format("f2bLogFile={0}", Log.File));
                    }
                    if (StateFile != null)
                    {
                        l.Add(string.Format("f2bState={0}", StateFile));
                    }
                    if (user != null)
                    {
                        l.Add(string.Format("f2bUser={0}", user));
                    }
                    if (host != null)
                    {
                        l.Add(string.Format("f2bHost={0}", host));
                    }
                    if (producerQueue != null)
                    {
                        l.Add(string.Format("f2bProducerQueue={0}", producerQueue));
                    }
                    if (registrationQueue != null)
                    {
                        l.Add(string.Format("f2bRegistrationQueue={0}", registrationQueue));
                    }
                    if (unsubscribeInterval != 0)
                    {
                        l.Add(string.Format("f2bRegistrationInterval={0}", unsubscribeInterval));
                    }
                    if (cleanupExpiredInterval != 0)
                    {
                        l.Add(string.Format("f2bCleanupExpiredInterval={0}", cleanupExpiredInterval));
                    }

                    if (command.ToLower() == "install") // Install
                    {
                        Log.Info("Installing " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { typeof(Program).Assembly.Location });
                        Install(false, l.ToArray());
                    }
                    else // Uninstall
                    {
                        //ManagedInstallerClass.InstallHelper(new String[] { "/u", typeof(Program).Assembly.Location });
                        Install(true, l.ToArray());
                    }
                }
                else if (command.ToLower() == "start")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not stopped, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "stop")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Running)
                            {
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not running, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BQueue command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }
            else
            {
                if (string.IsNullOrEmpty(host))
                {
                    Log.Error("Missing host command line argument");
                    //Usage();
                    Environment.Exit(1);
                }

                if (string.IsNullOrEmpty(producerQueue) || string.IsNullOrEmpty(registrationQueue))
                {
                    Log.Error("Both production and registration queue must be defined");
                    //Usage();
                    Environment.Exit(1);
                }

                if (!(unsubscribeInterval > 0))
                {
                    Log.Warn("Using application without unregistration interval is not optimal");
                }

                if (!(cleanupExpiredInterval > 0))
                {
                    Log.Warn("Running without specifying cleanup interval doesn't make too much sense");
                }

                // Initialize the service to start
                ServiceBase[] servicesToRun = new ServiceBase[]
                {
                    new Service(host, producerQueue, registrationQueue, unsubscribeInterval, cleanupExpiredInterval, maxQueueSize, StateFile),
                };

                if (!Environment.UserInteractive)
                {
                    // Start windows service
                    ServiceBase.Run(servicesToRun);
                }
                else // command.ToLower() == "run"
                {
                    // Get the method to invoke on each service to start it
                    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Start services loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Starting " + service.ServiceName + " ...");
                        onStartMethod.Invoke(service, new object[] { new string[] { } });
                    }

                    // Waiting the end
                    string help = "Interactive help\n"
                        + "  press 'h' key for this help\n"
                        + "  press 'q' key to quit\n"
            #if DEBUG
                        + "  press 'd' key to write debug info\n"
            #endif
                        ;
                    Console.Write(help);
                    while (true)
                    {
                        ConsoleKeyInfo key = Console.ReadKey();
                        if (key.KeyChar == 'q')
                        {
                            Log.Info("Quit key pressed");
                            break;
                        }
                        else if (key.KeyChar == 'h')
                        {
                            Log.Info("Interactive help");
                            Console.Write(help);
                        }
            #if DEBUG
                        else if (key.KeyChar == 'd')
                        {
                            Log.Info("Debug key pressed");
                            ((Service)servicesToRun[0]).Dump();
                        }
            #endif
                        else
                        {
                            Console.WriteLine("Unsupported key " + key.KeyChar);
                        }
                    }

                    // Get the method to invoke on each service to stop it
                    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Stop loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Stopping " + service.ServiceName + " ...");
                        onStopMethod.Invoke(service, null);
                    }

                    Log.Info("Debug F2B service finished");
                }
            }

            Log.Info("F2BQueue main finished");
        }
Example #6
0
File: Program.cs Project: vokac/F2B
        /// <summary>
        /// Main entry point of the application.
        /// </summary>
        public static void Main(string[] args)
        {
            ConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Log.Dest = Log.Destinations.EventLog;
            Log.Level = EventLogEntryType.Information;

            int i = 0;
            string command = null;
            string user = null;
            ulong maxmem = 0;
            string host = null;
            string producerQueue = null;
            string registrationQueue = null;
            int registrationInterval = 60;
            int cleanupExpiredInterval = 30;
            int maxFilterRules = 0;
            string address = null;
            long expiration = 0;
            UInt64 weight = 0;
            bool permit = false;
            bool persistent = false;
            UInt64 filterId = 0;

            while (i < args.Length)
            {
                string param = args[i];
                if (args[i][0] == '/')
                {
                    param = "-" + param.Substring(1);
                }

                if (param == "-h" || param == "-help" || param == "--help")
                {
                    Usage();
                    return;
                }
                else if (param == "-l" || param == "-log-level" || param == "--log-level")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        switch (args[i].ToUpper())
                        {
                            case "INFORMATION":
                            case "INFO":
                                Log.Level = EventLogEntryType.Information;
                                break;
                            case "WARNING":
                            case "WARN":
                                Log.Level = EventLogEntryType.Warning;
                                break;
                            case "ERROR":
                                Log.Level = EventLogEntryType.Error;
                                break;
                        }
                    }
                }
                else if (param == "-g" || param == "-log-file" || param == "--log-file")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.File = args[i];
                        Log.Dest = Log.Destinations.File;
                    }
                }
                else if (param == "-log-size" || param == "--log-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileSize = long.Parse(args[i]);
                    }
                }
                else if (param == "-log-history" || param == "--log-history")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        Log.FileRotate = int.Parse(args[i]);
                    }
                }
                else if (param == "-c" || param == "-config" || param == "--config")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        ConfigFile = args[i];
                    }
                }
                else if (param == "-u" || param == "-user" || param == "--user")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        user = args[i];
                    }
                }
                else if (param == "-x" || param == "-max-mem" || param == "--max-mem")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxmem = ulong.Parse(args[i]);
                    }
                }
                else if (param == "-H" || param == "-host" || param == "--host")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        host = args[i];
                    }
                }
                else if (param == "-p" || param == "-producer-queue" || param == "--producer-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        producerQueue = args[i];
                    }
                }
                else if (param == "-r" || param == "-registration-queue" || param == "--registration-queue")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        registrationQueue = args[i];
                    }
                }
                else if (param == "-i" || param == "-registration-interval" || param == "--registration-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        registrationInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-n" || param == "-cleanup-interval" || param == "--cleanup-interval")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        cleanupExpiredInterval = int.Parse(args[i]);
                    }
                }
                else if (param == "-m" || param == "-max-size" || param == "--max-size")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        maxFilterRules = int.Parse(args[i]);
                    }
                }
                else if (param == "-a" || param == "-address" || param == "--address")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        address = args[i];
                    }
                }
                else if (param == "-e" || param == "-expiration" || param == "--expiration")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        expiration = long.Parse(args[i]);
                    }
                }
                else if (param == "-w" || param == "-weight" || param == "--weight")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        weight = UInt64.Parse(args[i]);
                    }
                }
                else if (param == "-t" || param == "-permit" || param == "--permit")
                {
                    permit = true;
                }
                else if (param == "-s" || param == "-persistent" || param == "--persistent")
                {
                    persistent = true;
                }
                else if (param == "-f" || param == "-filter-id" || param == "--filter-id")
                {
                    if (i + 1 < args.Length)
                    {
                        i++;
                        filterId = UInt64.Parse(args[i]);
                    }
                }
                else if (param.Length > 0 && param[0] == '-')
                {
                    Log.Error("Unknown argument #" + i + " (" + args[i] + ")");
                    if (Environment.UserInteractive)
                    {
                        Usage();
                    }
                    return;
                }
                else
                {
                    command = args[i];
                }
                i++;
            }

            // Set memory limit for this process
            if (maxmem > 0)
            {
                Limit limitMemory = new Limit(maxmem * 1024 * 1024, maxmem * 1024 * 1024);
                limitMemory.AddProcess(Process.GetCurrentProcess().Handle);
                limitMemory.Dispose();
            }

            string[] serviceNamesToRun = new string[]
            {
                Service.NAME,
            };

            if (Environment.UserInteractive)
            {
                if (command == null)
                {
                    command = "help";
                }

                if ((Log.Dest & Log.Destinations.File) == 0)
                {
                    Log.Dest = Log.Destinations.Console;
                }
                Log.Info("F2BFirewall in interactive mode executing command: " + command);
            }

            if (Environment.UserInteractive && command.ToLower() != "run")
            {
                if (command.ToLower() == "help")
                {
                    Usage();
                }
                else if (command.ToLower() == "examples")
                {
                    Examples();
                }
                else if (command.ToLower() == "install" || command.ToLower() == "uninstall")
                {
                    List<string> l = new List<string>();
                    if ((Log.Dest & Log.Destinations.EventLog) != 0)
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                    }
                    if ((Log.Dest & Log.Destinations.File) != 0 && !string.IsNullOrEmpty(Log.File))
                    {
                        l.Add(string.Format("f2bLogLevel={0}", Log.Level));
                        l.Add(string.Format("f2bLogFile={0}", Log.File));
                    }
                    if (user != null)
                    {
                        l.Add(string.Format("f2bUser={0}", user));
                    }
                    if (host != null)
                    {
                        l.Add(string.Format("f2bHost={0}", host));
                    }
                    if (producerQueue != null)
                    {
                        l.Add(string.Format("f2bProducerQueue={0}", producerQueue));
                    }
                    if (registrationQueue != null)
                    {
                        l.Add(string.Format("f2bRegistrationQueue={0}", registrationQueue));
                    }
                    if (registrationInterval != 0)
                    {
                        l.Add(string.Format("f2bRegistrationInterval={0}", registrationInterval));
                    }
                    if (cleanupExpiredInterval != 0)
                    {
                        l.Add(string.Format("f2bCleanupExpiredInterval={0}", cleanupExpiredInterval));
                    }

                    if (command.ToLower() == "install") // Install
                    {
                        Log.Info("Installing " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { typeof(Program).Assembly.Location });
                        Install(false, l.ToArray());

                        Log.Info("Adding F2B WFP provider and sublyer");
                        try
                        {
                            F2B.Firewall.Instance.Install();
                        }
                        catch (Exception ex)
                        {
                            Log.Error(ex.Message);
                            throw;
                        }

                        if (user != null)
                        {
                            Log.Info("Adding privileges to modify F2B firewall rules to account " + user);
                            F2B.Firewall.Instance.AddPrivileges(F2B.Sid.Get(user));
                        }
                    }
                    else // Uninstall
                    {
                        if (user != null)
                        {
                            Log.Info("Removing privileges to modify F2B firewall rules from account " + user);
                            F2B.Firewall.Instance.RemovePrivileges(F2B.Sid.Get(user));
                        }

                        Log.Info("Removing F2B WFP provider, sublyer and all filter rules");
                        try
                        {
                            F2B.Firewall.Instance.Uninstall();
                        }
                        catch (Exception ex)
                        {
                            Log.Error(ex.Message);
                            throw;
                        }

                        Log.Info("Uninstalling " + Service.NAME + " (" + Service.DISPLAY + ")");

                        //ManagedInstallerClass.InstallHelper(new String[] { "/u", typeof(Program).Assembly.Location });
                        Install(true, l.ToArray());
                    }
                }
                else if (command.ToLower() == "start")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Stopped)
                            {
                                sc.Start();
                                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not stopped, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "stop")
                {
                    try
                    {
                        foreach (var serviceName in serviceNamesToRun)
                        {
                            ServiceController sc = new ServiceController(serviceName);
                            if (sc.Status == ServiceControllerStatus.Running)
                            {
                                sc.Stop();
                                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is now in " + sc.Status + " state");
                            }
                            else
                            {
                                Log.Info("Service " + sc.ServiceName + " (" + sc.DisplayName + ") is not running, state = " + sc.Status);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "list-wfp")
                {
                    Log.Info("Dump F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.DumpWFP();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-wfp")
                {
                    Log.Info("Adding F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.Install();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-wfp")
                {
                    Log.Info("Removing F2B WFP provider and sublyer");
                    try
                    {
                        F2B.Firewall.Instance.Uninstall();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "list-privileges")
                {
                    Log.Info("List F2B WFP privileges");
                    try
                    {
                        F2B.Firewall.Instance.DumpPrivileges();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error(ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-privileges")
                {
                    if (user != null)
                    {
                        Log.Info("Adding privileges to modify F2B firewall rules to account " + user);
                        try
                        {
                            F2B.Firewall.Instance.AddPrivileges(F2B.Sid.Get(user));
                        }
                        catch (FirewallException ex)
                        {
                            Log.Error(ex.Message);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        Console.WriteLine("ERROR: missing user argument");
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-privileges")
                {
                    if (user != null)
                    {
                        Log.Info("Removing privileges to modify F2B firewall rules from account " + user);
                        try
                        {
                            F2B.Firewall.Instance.RemovePrivileges(F2B.Sid.Get(user));
                        }
                        catch (FirewallException ex)
                        {
                            Log.Error(ex.Message);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        Console.WriteLine("ERROR: missing user argument");
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "list-filters")
                {
                    try
                    {
                        var details = F2B.Firewall.Instance.List(true);
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple<long, byte[]> fwname = FwData.DecodeName(item.Value);
                                string tmp = Convert.ToString(fwname.Item1);
                                try
                                {
                                    DateTime tmpExp = new DateTime(fwname.Item1, DateTimeKind.Utc);
                                    tmp = tmpExp.ToLocalTime().ToString();
                                }
                                catch (Exception)
                                {
                                }
                                Console.WriteLine("{0}: {1} (expiration={2}, md5={3}) ... {4}",
                                    item.Key, item.Value, tmp,
                                    BitConverter.ToString(fwname.Item2).Replace("-", ":"),
                                    details.ContainsKey(item.Key) ? details[item.Key] : "");
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Console.WriteLine("{0}: {1}", item.Key, item.Value);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to list firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-filters")
                {
                    try
                    {
                        F2B.Firewall.Instance.Cleanup();
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove all firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-expired-filters")
                {
                    long currTime = DateTime.UtcNow.Ticks;

                    try
                    {
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple<long, byte[]> fwname = FwData.DecodeName(item.Value);
                                if (currTime > fwname.Item1)
                                {
                                    Log.Info("Remove expired filter #" + item.Key
                                        + " (expiration=" + fwname.Item1 + ", md5="
                                        + BitConverter.ToString(fwname.Item2).Replace("-", ":")
                                        + ")");
                                    F2B.Firewall.Instance.Remove(item.Key);
                                }
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Log.Info("Unable to parse expiration time from filter #" + item.Key);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove expired firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-unknown-filters")
                {
                    try
                    {
                        foreach (var item in F2B.Firewall.Instance.List())
                        {
                            try
                            {
                                Tuple<long, byte[]> fwname = FwData.DecodeName(item.Value);
                            }
                            catch (ArgumentException)
                            {
                                // can't parse filter rule name to F2B structured data
                                Log.Info("Remove filter #" + item.Key + " with unparsable filter name: " + item.Value);
                                F2B.Firewall.Instance.Remove(item.Key);
                            }
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove unknown firewall filters: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "add-filter")
                {
                    if (address == null)
                    {
                        Console.WriteLine("ERROR: missing address argument");
                        Environment.Exit(1);
                    }

                    IPAddress addr;
                    int prefix = 128;
                    if (address.IndexOf('/') > 0)
                    {
                        if (!IPAddress.TryParse(address.Substring(0, address.IndexOf('/')), out addr) || !int.TryParse(address.Substring(address.IndexOf('/')+1), out prefix))
                        {
                            Console.WriteLine("ERROR: unable to parse address " + address);
                            Environment.Exit(1);
                        }
                    }
                    else
                    {
                        if (!IPAddress.TryParse(address, out addr))
                        {
                            Console.WriteLine("ERROR: unable to parse address " + address);
                            Environment.Exit(1);
                        }
                    }

                    try
                    {
                        if (expiration == 0)
                        {
                            string filterName = "F2B " + (permit ? "permit " : "block ") + address + " with no expiration" + (persistent ? " (persistent rule)" : "");
                            UInt64 filterIdNew = F2B.Firewall.Instance.Add(filterName, addr, prefix, weight, permit, persistent);
                            Log.Info("Added new filter #" + filterIdNew + " with name: " + filterName);
                        }
                        else
                        {
                            FwData fwdata = new FwData(expiration, addr, prefix);

                            // This code doesn't enumerate and check existing F2B firewall rules,
                            // but it must be updated together with changes in FwManager ... so
                            // to get consistent behavior in future it is better to use directly
                            // less optimal function from FwManager
                            //
                            //byte[] hash = fwdata.Hash;
                            //FirewallConditions conds = fwdata.Conditions();
                            //
                            //// IPv4 filter layer
                            //if (conds.HasIPv4() || (!conds.HasIPv4() && !conds.HasIPv6()))
                            //{
                            //    byte[] hash4 = new byte[hash.Length];
                            //    hash.CopyTo(hash4, 0);
                            //    hash4[hash4.Length - 1] &= 0xfe;
                            //    string filterName = FwData.EncodeName(expiration, hash4);
                            //    UInt64 filterIdNew = F2B.Firewall.Instance.AddIPv4(filterName, conds);
                            //    Log.Info("Added new IPv4 filter #" + filterIdNew + " for " + addr + "/" + prefix + " with encoded name: " + filterName);
                            //}
                            //
                            //// IPv6 filter layer
                            //if (conds.HasIPv6() || (!conds.HasIPv4() && !conds.HasIPv6()))
                            //{
                            //    byte[] hash6 = new byte[hash.Length];
                            //    hash.CopyTo(hash6, 0);
                            //    hash6[hash6.Length - 1] |= 0x01;
                            //    string filterName = FwData.EncodeName(expiration, hash6);
                            //    UInt64 filterIdNew = F2B.Firewall.Instance.AddIPv4(filterName, conds);
                            //    Log.Info("Added new IPv6 filter #" + filterIdNew + " for " + addr + "/" + prefix + " with encoded name: " + filterName);
                            //}

                            FwManager.Instance.Add(fwdata, weight, permit, persistent);
                        }
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to add firewall filter: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else if (command.ToLower() == "remove-filter")
                {
                    if (filterId == 0)
                    {
                        Console.WriteLine("ERROR: missing filterId argument");
                        Environment.Exit(1);
                    }
                    try
                    {
                        F2B.Firewall.Instance.Remove(filterId);
                    }
                    catch (FirewallException ex)
                    {
                        Log.Error("Unable to remove firewall filter: " + ex.Message);
                        Environment.Exit(1);
                    }
                }
                else
                {
                    Log.Error("Unknown F2BFirewall command: " + command);
                    return;
                }

                // Waiting a key press to not return to VS directly
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    Console.WriteLine();
                    Console.Write("=== Press a key to quit ===");
                    Console.ReadKey();
                    Console.WriteLine();
                }
            }
            else
            {
                if (string.IsNullOrEmpty(host))
                {
                    Log.Error("Missing host command line argument");
                    //Usage();
                    Environment.Exit(1);
                }

                if (string.IsNullOrEmpty(producerQueue) && string.IsNullOrEmpty(registrationQueue))
                {
                    Log.Error("Can't start without production or registration queue name");
                    //Usage();
                    Environment.Exit(1);
                }

                if (!string.IsNullOrEmpty(producerQueue) && !string.IsNullOrEmpty(registrationQueue))
                {
                    Log.Error("Specify only one queue (producer of registration)");
                    //Usage();
                    Environment.Exit(1);
                }

                if (!string.IsNullOrEmpty(registrationQueue) && !(registrationInterval > 0))
                {
                    Log.Warn("Using registration queue without specifying registration interval doesn't make too much sense");
                }

                if (!(cleanupExpiredInterval > 0))
                {
                    Log.Warn("Running without specifying cleanup interval doesn't make too much sense");
                }

                // Initialize the service to start
                ServiceBase[] servicesToRun = new ServiceBase[]
                {
                    new Service(host, producerQueue, registrationQueue, registrationInterval, cleanupExpiredInterval, maxFilterRules),
                };

                if (!Environment.UserInteractive)
                {
                    // Start windows service
                    ServiceBase.Run(servicesToRun);
                }
                else // command.ToLower() == "run"
                {
                    // Get the method to invoke on each service to start it
                    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Start services loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Starting " + service.ServiceName + " ...");
                        onStartMethod.Invoke(service, new object[] { new string[] { } });
                    }

                    // Waiting the end
                    string help = "Interactive help\n"
                        + "  press 'h' key for this help\n"
                        + "  press 'q' key to quit\n"
                        + "  press 'f' key to reread WFP F2B filter rules\n"
            #if DEBUG
                        + "  press 'd' key to write debug info\n"
            #endif
                        ;
                    Console.Write(help);
                    while (true)
                    {
                        ConsoleKeyInfo key = Console.ReadKey();
                        if (key.KeyChar == 'q')
                        {
                            Log.Info("Quit key pressed");
                            break;
                        }
                        else if (key.KeyChar == 'h')
                        {
                            Log.Info("Interactive help");
                            Console.Write(help);
                        }
                        else if (key.KeyChar == 'f')
                        {
                            Log.Info("Reread F2B filter rules from WFP");
                            F2B.FwManager.Instance.Refresh();
                        }
            #if DEBUG
                        else if (key.KeyChar == 'd')
                        {
                            Log.Info("Debug key pressed");
                            ((Service)servicesToRun[0]).Dump();
                        }
            #endif
                        else
                        {
                            Console.WriteLine("Unsupported key " + key.KeyChar);
                        }
                    }

                    // Get the method to invoke on each service to stop it
                    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);

                    // Stop loop
                    foreach (ServiceBase service in servicesToRun)
                    {
                        Log.Info("Stopping " + service.ServiceName + " ...");
                        onStopMethod.Invoke(service, null);
                    }

                    Log.Info("Debug F2B service finished");
                }
            }

            Log.Info("F2BFirewall main finished");
        }