Esempio n. 1
0
        private void LoadAndTest(FlowProfile profile, IEnumerable <IPacketRecord> packets)
        {
            var getFlowKeyFunc  = FlowKey.GetFlowKeyFunc(profile.FlowAggregation);
            var getModelKeyFunc = profile.ProtocolFactory.GetModelKeyFunc(profile.ModelKey);

            var startTime  = packets.First().TimeEpoch;
            var packetBins = packets.GroupBy(p => (int)Math.Floor((p.TimeEpoch - startTime) / profile.WindowSize));

            var normalTotal   = 0;
            var abnormalTotal = 0;
            var unknownTotal  = 0;

            foreach (var group in packetBins)
            {
                var flows       = profile.ProtocolFactory.CollectCoapFlows(group, getModelKeyFunc, getFlowKeyFunc);
                var testResults = TestAndPrint(profile, flows, $"{DateTime.UnixEpoch.AddSeconds((long)startTime + (group.Key * profile.WindowSize))}");
                normalTotal   += testResults.Normal;
                abnormalTotal += testResults.Abnormal;
                unknownTotal  += testResults.Unknown;
            }
            var measuresTable = new DataTable();

            measuresTable.Columns.Add("Metric", typeof(string));
            measuresTable.Columns.Add("Value", typeof(double));
            measuresTable.Rows.Add("Normal", normalTotal);
            measuresTable.Rows.Add("Abnormal", abnormalTotal);
            measuresTable.Rows.Add("Unknown", unknownTotal);
            Console.WriteLine("Measures:");
            ConsoleTableBuilder.From(measuresTable)
            .WithFormat(ConsoleTableBuilderFormat.MarkDown)
            .ExportAndWriteLine();
        }
Esempio n. 2
0
 private static void ComputeProfile(FlowProfile profile, IEnumerable <IFlowRecord> flows)
 {
     foreach (var flow in flows)
     {
         var modelObject = flow.Model.ToString();
         if (!profile.TryGetValue(modelObject, out var model))
         {
             model = profile.NewModel();
             profile[modelObject] = model;
         }
         model.Samples.Add(new double[] { flow.FlowPackets, flow.FlowOctets });
     }
 }
Esempio n. 3
0
        private void StoreProfile(FlowProfile profile, string outputFile)
        {
            var fullPath = Path.GetFullPath(outputFile);
            var sw       = new Stopwatch();

            sw.Start();
            Console.WriteLine("┌ Saving profile:");
            var formatter = new BinaryFormatter();

            using (var s = new FileStream(outputFile, FileMode.Create))
            {
                formatter.Serialize(s, profile);
                s.Close();
            }
            Console.WriteLine($"├─ profile written to {fullPath}");
            Console.WriteLine($"└ done [{sw.Elapsed}].");
        }
Esempio n. 4
0
        private void LoadAndCompute(FlowProfile profile, string inputFile, IList <CoapPacketRecord> packets, double windowSize, LearningWindow learningWindows,
                                    ProtocolFactory protocolFactory, Enum modelKey, FlowKey.Fields flowAggregation = FlowKey.Fields.None)
        {
            var getFlowKeyFunc  = FlowKey.GetFlowKeyFunc(flowAggregation);
            var getModelKeyFunc = protocolFactory.GetModelKeyFunc(modelKey);

            Console.WriteLine("┌ Load packets and compute profile:");
            Console.WriteLine($"├─ input file: {inputFile}");
            Console.WriteLine($"├─ packets count: {packets.Count}");
            Console.WriteLine($"├─ window size: {windowSize} seconds");
            Console.WriteLine($"├─ learning window: {learningWindows.Meassure}({learningWindows.Value})");
            Console.WriteLine($"├─ protocol: {protocolFactory.Name}");
            Console.WriteLine($"├─ model key: {modelKey}");
            Console.WriteLine($"├─ flow aggregation: {flowAggregation}");
            var sw = new Stopwatch();

            sw.Start();

            var startTime  = packets.First().TimeEpoch;
            var packetBins = packets.GroupBy(p => (int)Math.Floor((p.TimeEpoch - startTime) / windowSize)).ToList();

            var learningBins = learningWindows.Meassure == LearningWindow.ValueType.Absolute ? packetBins.Take((int)learningWindows.Value) :
                               packetBins.Take((int)(packetBins.Count() * learningWindows.Value));



            var pb1 = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ?  new ProgressBar(packetBins.Count()) : null;

            foreach (var group in packetBins)
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    pb1.Next($"├─ processing bin {group.Key}: {group.Count()} items");
                }
                var flows = protocolFactory.CollectCoapFlows(group, getModelKeyFunc, getFlowKeyFunc);
                ComputeProfile(profile, flows);
            }
            var pb2 = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new ProgressBar(profile.Count) : null;

            profile.Commit(() => { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                                   {
                                       pb2.Next($"├─ fitting models");
                                   }
                           });
            Console.WriteLine($"└ done [{sw.Elapsed}].");
        }
Esempio n. 5
0
        public void Configuration(CommandLineApplication command)
        {
            command.Description = "Tests the differences of the communication to the CoAP profile.";
            command.HelpOption("-?|-Help");

            var inputCsvOption = command.Option("-InputCsvFile <string>",
                                                "A name of an input file in csv format that contains decoded CoAP packets.",
                                                CommandOptionType.MultipleValue);

            var inputCapOption = command.Option("-InputCapFile <string>",
                                                "A name of an input file in cap format that contains CoAP packets.",
                                                CommandOptionType.MultipleValue);

            var profileOption = command.Option("-ProfileFile <string>",
                                               "A name of a profile file.",
                                               CommandOptionType.MultipleValue);

            var tresholdOption = command.Option("-TresholdFactor <double>",
                                                "A Factor used to scale the treshold. The usual values are between 0-1. Default is 1.",
                                                CommandOptionType.SingleValue);

            command.OnExecute(() =>
            {
                var thresholdMultiplier = tresholdOption.HasValue() ? Double.Parse(tresholdOption.Value()) : 1;
                if (profileOption.HasValue())
                {
                    var profiles = profileOption.Values.Select(PrintProfile.LoadProfile).ToList();
                    var profile  = profiles.Count == 1 ? profiles.First() : FlowProfile.MergeProfiles(profiles);
                    profile.ThresholdMultiplier = thresholdMultiplier;
                    if (inputCsvOption.HasValue())
                    {
                        var packets = PacketLoader.LoadCoapPacketsFromCsv(inputCsvOption.Value());
                        LoadAndTest(profile, packets);
                    }
                    if (inputCapOption.HasValue())
                    {
                        var packets = PacketLoader.LoadCoapPacketsFromCap(inputCapOption.Value());
                        LoadAndTest(profile, packets);
                    }
                    return(0);
                }
                throw new CommandParsingException(command, $"Missing required arguments: {inputCsvOption.ShortName}, {profileOption.ShortName}.");
            });
        }
Esempio n. 6
0
        private (int Normal, int Abnormal, int Unknown) TestAndPrint(FlowProfile profile, IEnumerable <IFlowRecord> flows, string label = "")
        {
            var normalCount   = 0;
            var abnormalCount = 0;
            var unknownCount  = 0;
            var matchingTable = new DataTable();

            matchingTable.Columns.Add("CoAP Flow", typeof(string));
            matchingTable.Columns.Add("Packets", typeof(string));
            matchingTable.Columns.Add("Octets", typeof(string));
            matchingTable.Columns.Add("Score", typeof(double));
            matchingTable.Columns.Add("Threshold", typeof(double));
            matchingTable.Columns.Add("Label", typeof(string));
            foreach (var flow in flows)
            {
                var observation = new double[] { flow.FlowPackets, flow.FlowOctets };
                if (profile.TryGetValue(flow.Model.ToString(), out var matchingProfile))
                {
                    var score   = matchingProfile.Score(observation);
                    var matches = (score > (matchingProfile.Threshold * profile.ThresholdMultiplier));
                    matchingTable.Rows.Add($"{flow.Key} {flow.Model}", flow.FlowPackets, flow.FlowOctets, score, matchingProfile.Threshold, matches ? "normal" : "abnormal");
                    if (matches)
                    {
                        normalCount++;
                    }
                    else
                    {
                        abnormalCount++;
                    }
                }
                else
                {
                    matchingTable.Rows.Add($"{flow.Key} {flow.Model}", flow.FlowPackets, flow.FlowOctets, double.NaN, double.NaN, "unknown");
                    unknownCount++;
                }
            }
            Console.WriteLine($"{label}:");
            ConsoleTableBuilder.From(matchingTable)
            .WithFormat(ConsoleTableBuilderFormat.MarkDown)
            .ExportAndWriteLine();
            return(normalCount, abnormalCount, unknownCount);
        }
Esempio n. 7
0
        /// <summary>
        /// Prints PDF of all models as CSV suitable for visualization.
        /// </summary>
        /// <param name="profile"></param>
        private void DumpPdf(FlowProfile profile)
        {
            foreach (var model in profile)
            {
                Console.WriteLine($"{model.Key}:");
                Console.WriteLine($"x,y,score");
                var samples = model.Value.Samples;
                var xmin = samples.Select(x => x[0]).Min(); var xmax = samples.Select(x => x[0]).Max();
                var ymin = samples.Select(x => x[1]).Min(); var ymax = samples.Select(x => x[1]).Max();
                var xdelta = (xmax - xmin) / 10;
                var ydelta = (ymax - ymin) / 10;

                for (var x = xmin; x < xmax; x += xdelta)
                {
                    for (var y = ymin; y < ymax; y += ydelta)
                    {
                        Console.WriteLine($"{x},{y},{model.Value.Score(new[] { x,y})}");
                    }
                }
                Console.WriteLine();
            }
        }
Esempio n. 8
0
        private void ComputeDistances(FlowProfile profile1, FlowProfile profile2)
        {
            var measuresTable = new DataTable();

            measuresTable.Columns.Add("Target", typeof(string));
            measuresTable.Columns.Add("Count 1", typeof(double));
            measuresTable.Columns.Add("Count 2", typeof(double));
            measuresTable.Columns.Add("Distance", typeof(double));
            foreach (var m1 in profile1)
            {
                if (profile2.TryGetValue(m1.Key, out var m2))
                {
                    var b    = new Bhattacharyya();
                    var dist = b.Distance(m1.Value.Samples.ToArray(), m2.Samples.ToArray());
                    measuresTable.Rows.Add(m1.Key, m1.Value.Samples.Count, m2.Samples.Count, dist);
                }
            }

            Console.WriteLine("Distances:");
            ConsoleTableBuilder.From(measuresTable)
            .WithFormat(ConsoleTableBuilderFormat.MarkDown)
            .ExportAndWriteLine();
        }