Skip to content

philipp2604/S7Scanner

Repository files navigation

S7Scanner 📡

A modern, high-performance .NET library for discovering Siemens S7 devices (PLCs and HMIs) across a network. It provides a simple, asynchronous API to scan IP ranges, identify potential Siemens devices, and classify them, and retrieve detailed hardware information from compatible PLCs. The project also includes a ready-to-use command-line tool.

.NET 8 (LTS) Build & Test .NET 9 (Latest) Build & Test Language NuGet Version License: MIT GitHub issues

✨ Key Features

  • ⚡️ High-Speed Parallel Scanning: Utilizes modern async/await and Parallel.ForEachAsync to scan hundreds of IP addresses concurrently, delivering results quickly.
  • 🔬 Detailed Device Identification: Intelligently distinguishes between Siemens PLCs and HMIs. For PLCs, it actively queries for detailed hardware information.
    • Full Details for S7-300/400: Retrieves module info, serial number, system name, and version from S7-300 PLCs using the S7-COMM protocol.
    • Identifies S7-1200/1500: Detects modern PLCs that normally restrict detailed queries, marking them as "Potential S7-1200/-1500".
  • 〰️ Flexible IP Range Parsing: Easily parse various input formats, including single IP addresses (192.168.0.1) and complex ranges (192.168.0.1-192.168.1.254).
  • 🖥️ Ready-to-Use CLI: Includes a powerful and easy-to-use command-line interface for immediate scanning without writing any code.
  • 🏗️ Modern & Asynchronous API: A fully async and thread-safe library built with modern C# features, including records for immutable data transfer objects.
  • ✅ Well-Tested: Comes with a comprehensive suite of unit and integration tests to ensure reliability and correctness.
  • 💾 JSON Output: The CLI can export scan results to a structured JSON file for easy integration with other tools and scripts.

🚀 Getting Started

Installation

S7Scanner.Lib is available on NuGet. You can install it using the .NET CLI:

dotnet add package philipp2604.S7Scanner.Lib

Or via the NuGet Package Manager in Visual Studio.

Quick Start (Library Usage)

Here's a simple example of how to use the S7Scanner.Lib in your own application.

using S7Scanner.Lib.Helpers;
using S7Scanner.Lib.IpScannerService;
using System.Net;

// 1. Define the scan parameters
const string ipRange = "192.168.0.1-192.168.0.254";
const int timeoutMs = 500;
const int parallelism = 100;

Console.WriteLine($"Scanning IP range: {ipRange}...");

try
{
    // 2. Parse the IP range string into a collection of IP addresses
    IEnumerable<IPAddress> ipsToScan = IpRangeParser.Parse(ipRange);

    // 3. Run the discovery process asynchronously
    var discoveredDevices = await IpScannerService.DiscoverDevicesAsync(
        ipsToScan,
        timeoutMs,
        parallelism,
        CancellationToken.None
    );

    // 4. Process the results
    if (!discoveredDevices.Any())
    {
        Console.WriteLine("No devices found.");
    }
    else
    {
        Console.WriteLine($"Found {discoveredDevices.Count()} device(s):");
        foreach (var device in discoveredDevices)
        {
            Console.WriteLine($"  - IP: {device.IpAddress,-15} | Type: {device.Type}");
            // Display PLC details if they were retrieved
            if (device.Details != null)
            {
                Console.WriteLine($"    - Module: {device.Details.Module}");
                Console.WriteLine($"    - Serial Number: {device.Details.SerialNumber}");
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"An error occurred: {ex.Message}");
}

🖥️ Command-Line Interface (CLI)

The project includes a pre-built command-line tool for immediate use.

Usage

S7Scanner.CLI.exe --ip-range <RANGE> [--output-file <PATH>] [--timeout <MS>] [--parallelism <COUNT>]

Options

Option Description Required Default
--ip-range The IP range to scan (e.g., '192.168.1.1-192.168.1.254'). Yes N/A
--output-file Optional. Path to save the results as a JSON file. No N/A
--timeout Connection timeout in milliseconds for each IP. No 500
--parallelism Number of IPs to scan concurrently. No 100

Example

# Scan a C-class network and print results to the console
./S7Scanner.CLI.exe --ip-range "192.168.0.1-192.168.0.254"

# Scan with higher timeout and save results to a file
./S7Scanner.CLI.exe --ip-range "10.0.0.1-10.0.255.254" --timeout 1000 --parallelism 200 --output-file "scan_results.json"

Example Output

# Scan a C-class network and print results to the console
./S7Scanner.CLI.exe --ip-range "192.168.0.1-192.168.0.254"

# Example Console Output:
# Starting Siemens Device Scanner...
# ...
# Found 3 device(s):
#   - 192.168.0.2     | Type: PLC
#     Module:               6ES7 315-2EH14-0AB0
#     Serial Number:        S C-U9B12345678
#     ...
#   - 192.168.0.3     | Type: HMI
#   - 192.168.0.5     | Type: PLC
#     Module:               Potential S7-1200/-1500
#     Serial Number:        Potential S7-1200/-1500
#     ...

📖 Documentation

  • S7ScannerService: The S7ScannerService is the primary entry point for all scanning operations.
  • CLI Example: A runnable console application demonstrating library usage in detail.
  • Integration Tests: These tests showcase real-world usage patterns against a live network and serve as excellent, practical examples.

🤝 Contributing

Contributions are welcome! Whether it's bug reports, feature requests, or pull requests, your help is appreciated.

  1. Fork the repository.
  2. Create a new branch for your feature or bug fix.
  3. Make your changes.
  4. Add or update unit/integration tests to cover your changes.
  5. Submit a Pull Request with a clear description of your changes.

Please open an issue first to discuss any major changes.

⚖️ License

This project is licensed under the MIT License. See the LICENSE file for details. You are free to use, modify, and distribute this software in commercial and private applications.