private void OnDevicePacketArrival(object sender, CaptureEventArgs args)
        {
            Packet packet;

            try {
                packet = Packet.ParsePacket(args.Packet.LinkLayerType, args.Packet.Data);
            }
            catch (Exception ex) when(ex is ArgumentOutOfRangeException || ex is IndexOutOfRangeException)
            {
                return;
            }

            int length = args.Packet.Data.Length;

            DomainPacket domainPacket = new DomainPacket {
                Bytes = length
            };

            try {
                if (packet.Extract <TcpPacket>() is { } tcpPacket)
                {
                    if (!(tcpPacket.ParentPacket is IPPacket ipPacket))
                    {
                        return;
                    }

                    domainPacket.SourceEndPoint      = new IPEndPoint(ipPacket.SourceAddress, tcpPacket.SourcePort);
                    domainPacket.DestinationEndPoint = new IPEndPoint(ipPacket.DestinationAddress, tcpPacket.DestinationPort);

                    domainPacket.ConnectionType = ipPacket.Version == IPVersion.IPv6 ? "TCPv6" : "TCP";

                    domainPacket.Key1 = $"{domainPacket.ConnectionType}/{domainPacket.SourceEndPoint.Address}/{domainPacket.SourceEndPoint.Port}/{domainPacket.DestinationEndPoint.Address}/{domainPacket.DestinationEndPoint.Port}";
                    domainPacket.Key2 = $"{domainPacket.ConnectionType}/{domainPacket.DestinationEndPoint.Address}/{domainPacket.DestinationEndPoint.Port}/{domainPacket.SourceEndPoint.Address}/{domainPacket.SourceEndPoint.Port}";
                }
                else if (packet.Extract <UdpPacket>() is { } udpPacket)
                {
                    if (!(udpPacket.ParentPacket is IPPacket ipPacket))
                    {
                        return;
                    }

                    domainPacket.SourceEndPoint      = new IPEndPoint(ipPacket.SourceAddress, udpPacket.SourcePort);
                    domainPacket.DestinationEndPoint = new IPEndPoint(ipPacket.DestinationAddress, udpPacket.DestinationPort);

                    domainPacket.ConnectionType = ipPacket.Version == IPVersion.IPv6 ? "UDPv6" : "UDP";

                    domainPacket.Key1 = $"{domainPacket.ConnectionType}/{domainPacket.SourceEndPoint.Address}/{domainPacket.SourceEndPoint.Port}";
                    domainPacket.Key2 = $"{domainPacket.ConnectionType}/{domainPacket.DestinationEndPoint.Address}/{domainPacket.DestinationEndPoint.Port}";
                }
            }
        private void OnPacketCaptured(DomainPacket packet)
        {
            List <ConnectionViewEntity> locals;

            lock (entityLock) locals = viewModel.Connections.Where(c => c.Key == packet.Key1).ToList();

            locals.ForEach(local => {
                local.PacketsSent = (local.PacketsSent ?? 0) + 1;
                local.BytesSent   = (local.BytesSent ?? 0) + packet.Bytes;

                local.HasData  = true;
                local.IsNew    = false;
                local.IsClosed = false;

                local.LastChange = DateTime.Now;
            });

            List <ConnectionViewEntity> remotes;

            lock (entityLock) remotes = viewModel.Connections.Where(c => c.Key == packet.Key2).ToList();

            remotes.ForEach(remote => {
                remote.PacketsReceived = (remote.PacketsReceived ?? 0) + 1;
                remote.BytesReceived   = (remote.BytesReceived ?? 0) + packet.Bytes;

                remote.HasData  = true;
                remote.IsNew    = false;
                remote.IsClosed = false;

                remote.LastChange = DateTime.Now;
            });

            if (!locals.Any() && !remotes.Any())
            {
                viewModel.DroppedPackets++;

                if (!viewModel.ViewDropped)
                {
                    return;
                }

                bool exists;

                lock (packetLock) exists = packets.Any(p => packet.Key1 == p.Key || packet.Key2 == p.Key);

                if (!exists)
                {
                    lock (packetLock) {
                        if (!packets.Any(p => packet.Key1 == p.Key || packet.Key2 == p.Key))
                        {
                            bool isSourceLocal      = connectionService.IsLocalAddress(packet.SourceEndPoint);
                            bool isDestinationLocal = connectionService.IsLocalAddress(packet.DestinationEndPoint);

                            DomainConnection connection = mapper.Map <DomainConnection>(packet);

                            if ((isSourceLocal && isDestinationLocal) || isSourceLocal)
                            {
                                connection.Key = packet.Key1;

                                connection.LocalEndPoint  = packet.SourceEndPoint;
                                connection.RemoteEndPoint = packet.DestinationEndPoint;
                            }
                            else
                            {
                                connection.Key = packet.Key2;

                                connection.LocalEndPoint  = packet.DestinationEndPoint;
                                connection.RemoteEndPoint = packet.SourceEndPoint;
                            }

                            connection.ResolveHostNames(connectionService).FireAndForget();

                            packets.Add(connection);
                        }
                    }
                }
            }
        }