private static bool OnConnectionRequest(object parameter, IPAddress ipAddress)
        {
            var allowedIp = false;

            foreach (var r in _settings.AllowedIPAddresses)
            {
                if (Equals(r, ipAddress))
                {
                    allowedIp = true;
                    break;
                }
            }

            if (allowedIp)
            {
                if (_server.HasActiveConnections)
                {
                    SmprMonitoringService.Log("Connection from " + ipAddress + " is not allowed because the server already has an active connection");
                    return(false);
                }

                SmprMonitoringService.Log("Allowed connection request from " + ipAddress);
                return(true);
            }
            else
            {
                SmprMonitoringService.Log("Denied connection request from " + ipAddress);
                return(false);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Главная точка входа для приложения.
        /// </summary>
        static void Main()
        {
#if DEBUG
            SmprMonitoringService s = new SmprMonitoringService();
            s.OnDebug();
            Thread.Sleep(10000);
#else
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new SmprMonitoringService()
            };
            ServiceBase.Run(ServicesToRun);
#endif
        }
        internal static void Start()
        {
            if (_started)
            {
                return;
            }
            _started = true;

            using (var file = File.OpenText(AppDomain.CurrentDomain.BaseDirectory + "settings.json"))
            {
                var serializer = new JsonSerializer();
                _settings = (Settings)serializer.Deserialize(file, typeof(Settings));
            }

            var checkSettings = _settings.CheckSettings();

            if (checkSettings != null)
            {
                throw new Exception("Wrong settings: " + checkSettings);
            }

            foreach (var destination in _settings.Destinations)
            {
                foreach (var ipAddress in destination.IpAddresses)
                {
                    long ipPort = ipAddress.AsUint * 65536 + destination.Port;
                    _destinationDictionary.Add(ipPort, destination);
                }
            }

            _timer1.Elapsed += Timer1Elapsed;

            PacketDevice selectedDevice = null;
            var          localIpAddress = string.Empty;

#if DEBUG
            selectedDevice = new OfflinePacketDevice(_settings.DebugPcapFile);

            SmprMonitoringService.Log("Selected offline packet device: " + _settings.DebugPcapFile);
            localIpAddress = _settings.DebugLocalIP;
#else
            IList <LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

            if (allDevices.Count == 0)
            {
                throw new Exception("No interfaces found! Make sure WinPcap is installed");
            }

            foreach (var device in allDevices)
            {
                if (device.Name == _settings.DeviceName)
                {
                    selectedDevice = device;
                    break;
                }
            }

            if (selectedDevice == null)
            {
                throw new Exception("Device specified in settings file not found");
            }

            SmprMonitoringService.Log("Selected device: " + selectedDevice.Description);

            bool ipFound = false;
            for (int i = 0; i < selectedDevice.Addresses.Count; i++)
            {
                if (selectedDevice.Addresses[i].Address.Family != SocketAddressFamily.Internet)
                {
                    continue;
                }

                if (ipFound)
                {
                    throw new Exception("Devices with two or more IPv4 addresses are not supported");
                }
                ipFound        = true;
                localIpAddress = selectedDevice.Addresses[i].Address.ToString().Remove(0, 9);
            }
#endif
            _asdu   = new ASDU(_alp, TypeID.M_ME_TF_1, CauseOfTransmission.SPONTANEOUS, false, false, 0, _settings.RTUID, false);
            _server = new Server(_settings.Iec104Port)
            {
                ServerMode = ServerMode.SINGLE_REDUNDANCY_GROUP
            };

            _server.SetConnectionRequestHandler(OnConnectionRequest, null);
            _server.SetConnectionEventHandler(OnConnectionEvent, null);
            _server.SetInterrogationHandler(OnInterrogation, null);
#if !DEBUG
            _server.Start();
#endif

            if (_settings.Destinations.Count > 0)
            {
                uint startTime = (uint)(DateTime.UtcNow - _unixOrigin).TotalSeconds - _settings.RequestDepth + 1;

                foreach (var dest in _settings.Destinations)
                {
                    dest.LastRequestedReceivedTime = startTime;
                }

                _nextPeriodTime = (uint)(DateTime.UtcNow - _unixOrigin).TotalSeconds + _settings.AveragingPeriod;
                _elapsedTime    = (uint)(DateTime.UtcNow - _unixOrigin).TotalSeconds + _settings.RequestDepth;
#if !DEBUG
                _timer1.Start();
#endif

                using (_communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
                {
                    if (_communicator.DataLink.Kind != DataLinkKind.Ethernet)
                    {
                        SmprMonitoringService.Log("This program works only on Ethernet networks.");
                        return;
                    }

                    /*генерация PacketFilter*/
                    var sb = new StringBuilder();
                    sb.Append("ip dst host ");
                    sb.Append(localIpAddress);
                    sb.Append(" and (");

                    var destinationCount = _settings.Destinations.Count - 1;
                    for (var i = 0; i <= destinationCount; i++)
                    {
                        var currentDestination = _settings.Destinations[i];
                        sb.Append("(");

                        if (currentDestination.IpAddresses.Count > 0)
                        {
                            sb.Append("ip src host ");
                            sb.Append(string.Join(" or ", currentDestination.IpAddresses));
                            sb.Append(" and ");
                        }

                        switch (currentDestination.Protocol)
                        {
                        case DestinationProtocol.TCP:
                            sb.Append("tcp src ");
                            break;

                        case DestinationProtocol.UDP:
                            sb.Append("udp dst ");
                            break;

                        default:
                            throw new Exception("Unknown destination protocol: " + currentDestination.Name);
                        }

                        sb.Append($"port {currentDestination.Port.ToString()}");

                        sb.Append(")");

                        if (i != destinationCount)
                        {
                            sb.Append(" or ");
                        }
                    }

                    sb.Append(")");
                    /*генерация PacketFilter*/

                    SmprMonitoringService.Log("Filter generated: " + sb);

                    using (var filter = _communicator.CreateFilter(sb.ToString()))
                    {
                        _communicator.SetFilter(filter);
                    }
                    _communicator.ReceivePackets(0, PacketHandler);
#if DEBUG
                    using (var sw = new StreamWriter(_settings.DebugPcapFile + ".json"))
                    {
                        var serializer = new JsonSerializer()
                        {
                            Formatting = Formatting.Indented
                        };
                        serializer.Serialize(sw, _settings);
                    }
#endif
                }
            }
            else
            {
                SmprMonitoringService.Log("Destination list is empty");
            }
        }
 private static void OnConnectionEvent(object parameter, ClientConnection connection, ClientConnectionEvent eventType)
 {
     SmprMonitoringService.Log("connection event " + eventType.ToString() + " " + connection.RemoteEndpoint);
 }