IPMG — IP Management & Ping Monitoring Tool
Scan and monitor IP networks from the command line — or from a local web dashboard. IPMG pings hosts in parallel, resolves hostnames, and exports results as Excel, CSV, JSON, or Markdown reports.
Security note: only scan networks you are authorized to scan. Unauthorized scanning may violate your organization's policies or the law.
Install
pip install ipmg
Check that it works:
ipmg --version
Other install methods
uv (isolated global install):
uv tool install git+https://github.com/sameeralam3127/ipmg.git
curl installer (installs uv if missing):
curl -sSL https://raw.githubusercontent.com/sameeralam3127/ipmg/main/install.sh | bash
From source (development):
git clone https://github.com/sameeralam3127/ipmg.git
cd ipmg
pip install -e .
Quick start
# Scan your local subnet automatically
ipmg --discover
# Scan a single host
ipmg --input 8.8.8.8
# Scan a CIDR range
ipmg --input 192.168.1.0/24
# Scan an IP range
ipmg --input 10.0.0.1-10.0.0.50
# Scan targets from a file (xlsx, csv, txt, or list)
ipmg --input targets.txt
# Resolve hostnames and export CSV + a readable Markdown report
ipmg --input targets.txt --resolve --formats md csv
# Scan and report what changed since the previous scan
ipmg --input targets.txt --compare
# List stored scans, then compare any two of them
ipmg history
ipmg diff 12 14
# Open the local web dashboard
ipmg dashboard
Running plain ipmg uses ip_list.xlsx as input and creates a sample file
if it does not exist.
Change detection
Every scan is stored in a local SQLite history (~/.ipmg/dashboard.db),
shared by the CLI and the dashboard. IPMG can then tell you what moved
between any two scans.
ipmg --input targets.txt --compare # compare with the previous scan
ipmg diff # compare the two latest scans
ipmg diff 14 # compare scan 14 with the one before it
ipmg diff 12 14 # compare two specific scans
ipmg diff --diff-formats md json # export the change summary
ipmg diff --fail-on-change # exit 2 when anything changed (CI)
ipmg history --limit 10 # list stored scans
Detected changes:
| Change | Severity | Meaning |
|---|---|---|
| Host offline | critical | Reachable in the baseline, not reachable now |
| New host | warning | An IP that the baseline never saw |
| Host removed | warning | An IP the current scan no longer covers |
| IP address changed | warning | A known hostname moved to a different IP |
| Service changed | warning | Status moved between failure modes (e.g. Timeout → Unreachable) |
| Host back online | info | Recovered since the baseline |
| Hostname changed | info | Same IP, different PTR record |
| Latency changed | info | Latency moved past both thresholds |
A latency change is only reported when it clears both --latency-threshold
(default 5 ms) and --latency-pct (default 25%), which keeps normal jitter out
of the report.
| Flag | Default | Description |
|---|---|---|
--compare |
off | Print a change report after the scan |
--compare-any-source |
off | Allow a baseline from a different target source |
--no-history |
off | Do not store the scan |
--db |
~/.ipmg/dashboard.db |
History database location |
--diff-formats |
none | Export the change summary as md, json, csv |
--diff-output |
changes |
Base filename for exported change summaries |
--latency-threshold |
5 |
Minimum latency delta in ms |
--latency-pct |
25 |
Minimum relative latency change |
--fail-on-change |
off | ipmg diff exits 2 when changes are found |
By default a scan is compared against the previous scan of the same target
source, so file-based and --discover runs do not get mixed up.
Web dashboard
ipmg dashboard # starts http://127.0.0.1:8080 and opens your browser
A modern browser UI that shares the CLI's scanning engine and runs fully offline — every stylesheet and script is bundled with the package, nothing is loaded from a CDN. It gives you:
- Dashboard — status donut, latency trend, and recent scan overview
- New Scan — upload Excel/CSV/text/JSON target files or type IPs, CIDR blocks, and ranges; configure threads, timeout, and DNS options
- Live Monitor — real-time progress and results over WebSockets
- History — every scan stored locally in SQLite (
~/.ipmg/dashboard.db), searchable and downloadable as XLSX/CSV/JSON/Markdown - Changes — pick any two scans and see new/offline hosts, IP and hostname moves, and latency shifts; export the summary as Markdown/JSON/CSV
- Inventory — every host seen across scans, with last status and export
| Flag | Default | Description |
|---|---|---|
--port |
8080 |
Port to listen on |
--host |
127.0.0.1 |
Bind address (local-only by default) |
--no-browser |
off | Don't open the browser automatically |
--db |
~/.ipmg/dashboard.db |
History database location |
ipmg web is an alias for ipmg dashboard.
Options
| Flag | Default | Description |
|---|---|---|
--input |
ip_list.xlsx |
Targets: a file (.xlsx, .xls, .csv, .txt, .list), a single IP, a CIDR block, or an IP range (10.0.0.1-10.0.0.50) |
--output |
results |
Output file name prefix |
--formats |
xlsx |
One or more of xlsx, csv, json, md |
--discover |
off | Auto-detect and scan the local subnet |
--resolve |
off | Reverse DNS (PTR) lookup for each host |
--dns-cache-ttl |
300 |
Cache DNS results for this many seconds (0 disables caching) |
--timeout |
2 |
Ping timeout in seconds |
--count |
1 |
Pings per host |
--threads |
50 |
Parallel workers |
--interval |
off | Repeat the scan every N minutes |
--compare |
off | Report what changed since the previous scan |
--no-history |
off | Do not store the scan in the history database |
--verbose |
off | Debug logging |
Exit codes: 0 success, 1 error, 2 changes detected
(ipmg diff --fail-on-change), 130 interrupted.
Input formats
-
Excel / CSV — must contain an
IP Addresscolumn:IP Address 192.168.1.1 10.0.1.0/30 -
Text file — one IP or CIDR per line; blank lines and
#comments are ignored:# Production DNS 8.8.8.8 192.168.1.0/30
-
Command line — a literal IP (
8.8.8.8), CIDR block (10.0.0.0/24), or IP range (10.0.0.1-10.0.0.200)
Output
Every scan prints a color-coded summary and writes result files
(e.g. results_20260628_120000.xlsx). Each row includes:
| IP Address | Status | Latency | Hostname | Batch Timestamp | Scan Duration (s) |
|---|---|---|---|---|---|
| 8.8.8.8 | Active | 12.5 | dns.google | 2026-04-09 11:42:13 | 6.24 |
Status values: Active, Inactive, Timeout, Unreachable, Invalid IP, Error.
The md format produces a shareable Markdown report with a status summary
table — handy for tickets, handoffs, and incident timelines.
Troubleshooting
command not found: ipmg— make sure pip's script directory is on yourPATH, or reinstall withpip install ipmg.- Hostname shows
Unresolvable— the host has no DNS PTR record. - Input file rejected — check the extension is supported and that
spreadsheets/CSVs include an
IP Addresscolumn.
Development
pip install -e ".[dev]"
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -q
Releases are automated: merging a conventional commit (feat: ...,
fix: ...) to main triggers GitHub Actions to run tests, create a
semantic-release tag, and publish to PyPI.
License
MIT — free for commercial and personal use.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ipmg-1.7.0.tar.gz.
File metadata
- Download URL: ipmg-1.7.0.tar.gz
- Upload date:
- Size: 64.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd0c82af2a60c305ed98ed5ff2a988f425e68aeafc466a6721449c0cd04eeb9e
|
|
| MD5 |
56d7ee8465c46c9c024bf0a29094310d
|
|
| BLAKE2b-256 |
f696f1eec7b461585c692426520c71c91b58c5568aa0b56509c4da782e5f7104
|
Provenance
The following attestation bundles were made for ipmg-1.7.0.tar.gz:
Publisher:
publish.yml on sameeralam3127/ipmg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ipmg-1.7.0.tar.gz -
Subject digest:
fd0c82af2a60c305ed98ed5ff2a988f425e68aeafc466a6721449c0cd04eeb9e - Sigstore transparency entry: 2256340662
- Sigstore integration time:
-
Permalink:
sameeralam3127/ipmg@f4fb55c4131d6e6f929426ae17a02d484fa0456b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sameeralam3127
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4fb55c4131d6e6f929426ae17a02d484fa0456b -
Trigger Event:
push
-
Statement type:
File details
Details for the file ipmg-1.7.0-py3-none-any.whl.
File metadata
- Download URL: ipmg-1.7.0-py3-none-any.whl
- Upload date:
- Size: 58.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7e58299a152043957fe1b406e00fdad063811268b956b1403b3f8ddca5fcc39
|
|
| MD5 |
d24cb05bb178aed0e2dae3e0b901a1d7
|
|
| BLAKE2b-256 |
8f1a927c1fe4102899fb1c3ae65cc294fc0efebc66a976ee97acb16e779be3e6
|
Provenance
The following attestation bundles were made for ipmg-1.7.0-py3-none-any.whl:
Publisher:
publish.yml on sameeralam3127/ipmg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ipmg-1.7.0-py3-none-any.whl -
Subject digest:
f7e58299a152043957fe1b406e00fdad063811268b956b1403b3f8ddca5fcc39 - Sigstore transparency entry: 2256340673
- Sigstore integration time:
-
Permalink:
sameeralam3127/ipmg@f4fb55c4131d6e6f929426ae17a02d484fa0456b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sameeralam3127
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4fb55c4131d6e6f929426ae17a02d484fa0456b -
Trigger Event:
push
-
Statement type: