woninet 2.0.3__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- woninet-2.2.0/PKG-INFO +321 -0
- woninet-2.2.0/README.md +292 -0
- {woninet-2.0.3 → woninet-2.2.0}/pyproject.toml +7 -2
- {woninet-2.0.3 → woninet-2.2.0}/tests/test_alert_events.py +74 -0
- woninet-2.2.0/tests/test_api.py +151 -0
- woninet-2.2.0/tests/test_arp_lookup.py +36 -0
- woninet-2.2.0/tests/test_availability.py +46 -0
- woninet-2.2.0/tests/test_system_ping.py +121 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/__init__.py +1 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/alerts.py +103 -18
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/collectors.py +56 -33
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/engine.py +259 -14
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/manual_ip_enumerator.py +3 -3
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/models.py +25 -11
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/storage.py +103 -2
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/subnet_enumerator.py +1 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/engine.py +1 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/alert_event_repository.py +12 -2
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/alert_state_repository.py +29 -3
- woninet-2.2.0/woninet/database/repositories/availability_repository.py +113 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/device_repository.py +31 -4
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/metric_repository.py +1 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/tables.py +25 -4
- woninet-2.2.0/woninet/exc.py +2 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/main.py +5 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/app.py +19 -18
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/dependencies.py +1 -1
- woninet-2.2.0/woninet/server/routes/api/alerts.py +29 -0
- woninet-2.2.0/woninet/server/routes/api/devices.py +46 -0
- woninet-2.2.0/woninet/server/routes/api/settings.py +47 -0
- woninet-2.2.0/woninet/server/routes/page/about.py +23 -0
- woninet-2.2.0/woninet/server/routes/page/alerts.py +14 -0
- woninet-2.2.0/woninet/server/routes/page/settings.py +14 -0
- woninet-2.2.0/woninet/server/static/css/about.css +141 -0
- woninet-2.2.0/woninet/server/static/css/alerts.css +143 -0
- woninet-2.2.0/woninet/server/static/css/device_info.css +274 -0
- woninet-2.2.0/woninet/server/static/css/settings.css +142 -0
- woninet-2.2.0/woninet/server/static/css/style.css +532 -0
- woninet-2.2.0/woninet/server/static/js/alerts.js +118 -0
- woninet-2.2.0/woninet/server/static/js/app.js +113 -0
- woninet-2.2.0/woninet/server/static/js/device_info.js +289 -0
- woninet-2.2.0/woninet/server/static/js/settings.js +248 -0
- woninet-2.2.0/woninet/server/templates/about.html +114 -0
- woninet-2.2.0/woninet/server/templates/alerts.html +95 -0
- woninet-2.2.0/woninet/server/templates/dashboard.html +153 -0
- woninet-2.2.0/woninet/server/templates/device_info.html +159 -0
- woninet-2.2.0/woninet/server/templates/settings.html +126 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/arguments.py +2 -2
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/create_configuration.py +8 -1
- woninet-2.2.0/woninet/utilities/detect_gateway.py +66 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/detect_ip_range.py +1 -1
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/ip_validator.py +1 -1
- woninet-2.2.0/woninet/utilities/ping.py +103 -0
- woninet-2.2.0/woninet/utilities/update_configuration.py +33 -0
- woninet-2.2.0/woninet.egg-info/PKG-INFO +321 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/SOURCES.txt +23 -5
- {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/requires.txt +3 -1
- woninet-2.0.3/PKG-INFO +0 -272
- woninet-2.0.3/README.md +0 -245
- woninet-2.0.3/tests/test_api.py +0 -10
- woninet-2.0.3/woninet/core/graph.py +0 -66
- woninet-2.0.3/woninet/server/routes/api/devices.py +0 -43
- woninet-2.0.3/woninet/server/static/css/style.css +0 -368
- woninet-2.0.3/woninet/server/static/js/app.js +0 -242
- woninet-2.0.3/woninet/server/static/js/device_info.js +0 -95
- woninet-2.0.3/woninet/server/static/swagger-ui/favicon-32x32.png +0 -0
- woninet-2.0.3/woninet/server/static/swagger-ui/swagger-ui-bundle.js +0 -2
- woninet-2.0.3/woninet/server/static/swagger-ui/swagger-ui.css +0 -3
- woninet-2.0.3/woninet/server/templates/dashboard.html +0 -118
- woninet-2.0.3/woninet/server/templates/device_info.html +0 -93
- woninet-2.0.3/woninet.egg-info/PKG-INFO +0 -272
- {woninet-2.0.3 → woninet-2.2.0}/LICENSE +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/setup.cfg +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/tests/test_ip_validation.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/tests/test_storage.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/__main__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/core/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/base.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/logging.yaml +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/api/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/api/stats.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/page/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/page/devices.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/static/css/404.css +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/server/templates/404.html +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/__init__.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/cli_parser.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/logger.py +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/dependency_links.txt +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/entry_points.txt +0 -0
- {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/top_level.txt +0 -0
woninet-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: woninet
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: A Python-based ARP+ICMP network monitoring tool
|
|
5
|
+
Author-email: Alireza Teymuri <teymuri.alireza98@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/teymuri-alireza/woninet
|
|
8
|
+
Project-URL: Documentation, https://github.com/teymuri-alireza/woninet/tree/main/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/teymuri-alireza/woninet
|
|
10
|
+
Project-URL: Issues, https://github.com/teymuri-alireza/woninet/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/teymuri-alireza/woninet/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: network,network-monitoring,icmp,arp
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: icmplib<3.1,>=3.0.4
|
|
17
|
+
Requires-Dist: fastapi<0.137,>=0.136.0
|
|
18
|
+
Requires-Dist: Jinja2<3.2,>=3.1.6
|
|
19
|
+
Requires-Dist: uvicorn<0.45,>=0.44.0
|
|
20
|
+
Requires-Dist: PyYAML<6.1,>=6.0.3
|
|
21
|
+
Requires-Dist: SQLAlchemy<2.1,>=2.0.46
|
|
22
|
+
Requires-Dist: python-multipart==0.0.32
|
|
23
|
+
Requires-Dist: fastapi-swagger<0.5,>=0.4.64
|
|
24
|
+
Provides-Extra: test
|
|
25
|
+
Requires-Dist: pytest<9.2,>=9.1.1; extra == "test"
|
|
26
|
+
Requires-Dist: httpx<0.29,>=0.28.1; extra == "test"
|
|
27
|
+
Requires-Dist: ruff<0.16,>=0.15.11; extra == "test"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Woninet
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/woninet/)
|
|
33
|
+
[](https://www.python.org/)
|
|
34
|
+
[](https://github.com/teymuri-alireza/woninet/blob/main/LICENSE)
|
|
35
|
+
[](https://pypi.org/project/woninet/)
|
|
36
|
+
|
|
37
|
+
A local network monitoring system.
|
|
38
|
+
|
|
39
|
+
**Woninet** continuously monitors devices on a local network using ARP and ICMP probes. It enumerates candidate IP addresses in a /24 subnet, determines device availability, measures latency, packet loss, and jitter, stores metrics in database, and evaluates configurable alert rules in real time.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
## Table of Contents
|
|
44
|
+
|
|
45
|
+
- [Features](#features)
|
|
46
|
+
- [Requirements](#requirements)
|
|
47
|
+
- [Quick Start](#quick-start)
|
|
48
|
+
- [Installation](#installation)
|
|
49
|
+
- [Configuration](#configuration)
|
|
50
|
+
- [Usage](#usage)
|
|
51
|
+
- [Platform Notes](#platform-notes)
|
|
52
|
+
- [Testing](#testing)
|
|
53
|
+
- [Known Issues](#known-issues)
|
|
54
|
+
- [Documentation](#documentation)
|
|
55
|
+
- [Contributing](#contributing)
|
|
56
|
+
- [License](#license)
|
|
57
|
+
|
|
58
|
+
## Features
|
|
59
|
+
|
|
60
|
+
- **ARP + ICMP host detection.** Distinguishes real devices from nonexistent IP addresses and filters out Wi-Fi ARP-delay noise.
|
|
61
|
+
- **Alert engine.** Evaluates real-time alert rules, such as latency thresholds, against collected metrics.
|
|
62
|
+
- **Threaded collectors.** Sends ICMP probes concurrently using a configurable number of worker threads.
|
|
63
|
+
- **SQLite storage.** Persists devices, recorded metrics, alert states, and alert events.
|
|
64
|
+
- **Database access from the CLI.** Accepts a positional argument for easier access to the database.
|
|
65
|
+
- **Detailed logging.**
|
|
66
|
+
|
|
67
|
+
## Requirements
|
|
68
|
+
|
|
69
|
+
- Python 3.12 or later.
|
|
70
|
+
- Elevated network privileges, because ARP and ICMP probing use raw sockets. On Linux, either of the following satisfies this requirement:
|
|
71
|
+
- the `cap_net_raw` capability granted to the Python interpreter (recommended, see [Installation](#installation)), or
|
|
72
|
+
- root privileges (discouraged for security reasons).
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
On Linux, the minimal path is:
|
|
77
|
+
|
|
78
|
+
```shell
|
|
79
|
+
python3 -m venv --copies venv
|
|
80
|
+
source venv/bin/activate
|
|
81
|
+
pip install woninet
|
|
82
|
+
sudo setcap cap_net_raw=eip venv/bin/python3
|
|
83
|
+
woninet --help
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For Docker, macOS, Windows, and source installs, see [Installation](#installation).
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
### Option 1: Install from PyPI
|
|
91
|
+
|
|
92
|
+
#### Linux (recommended: `icmplib` with `cap_net_raw`)
|
|
93
|
+
|
|
94
|
+
Create and activate a virtual environment. The `--copies` flag forces Python to copy the interpreter instead of symlinking it, which is required because the capability is applied directly to the interpreter binary:
|
|
95
|
+
|
|
96
|
+
```shell
|
|
97
|
+
python3 -m venv --copies venv
|
|
98
|
+
source venv/bin/activate
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Install Woninet:
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
pip install woninet
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Grant the required capability to the Python interpreter:
|
|
108
|
+
|
|
109
|
+
```shell
|
|
110
|
+
sudo setcap cap_net_raw=eip venv/bin/python3
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Run Woninet:
|
|
114
|
+
|
|
115
|
+
```shell
|
|
116
|
+
woninet --help
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Linux (fallback: system `ping`)
|
|
120
|
+
|
|
121
|
+
If you do not grant the capability, Woninet falls back to the system `ping` command. Create the environment without `--copies`:
|
|
122
|
+
|
|
123
|
+
```shell
|
|
124
|
+
python3 -m venv venv
|
|
125
|
+
source venv/bin/activate
|
|
126
|
+
pip install woninet
|
|
127
|
+
woninet --help
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### macOS and Windows
|
|
131
|
+
|
|
132
|
+
```shell
|
|
133
|
+
pip install woninet
|
|
134
|
+
woninet --help
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
See [Platform Notes](#platform-notes) for privilege considerations on these systems.
|
|
138
|
+
|
|
139
|
+
### Option 2: Docker (Linux only)
|
|
140
|
+
|
|
141
|
+
Clone the repository and run:
|
|
142
|
+
|
|
143
|
+
```shell
|
|
144
|
+
chmod +x build_docker.sh
|
|
145
|
+
sudo ./build_docker.sh
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The script runs `docker compose up -d --build` and prints the device's private IP address to standard output so you can open the web interface in a browser.
|
|
149
|
+
|
|
150
|
+
To open Woninet manually, type device's private IP address with the default `8080` port in the browser.
|
|
151
|
+
|
|
152
|
+
### Option 3: Install from source
|
|
153
|
+
|
|
154
|
+
1. Clone the repository:
|
|
155
|
+
|
|
156
|
+
```shell
|
|
157
|
+
git clone https://github.com/teymuri-alireza/woninet
|
|
158
|
+
cd woninet
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
2. Create and activate a virtual environment **outside** the project directory to avoid `Multiple top-level packages discovered in a flat-layout` errors.
|
|
162
|
+
|
|
163
|
+
Linux
|
|
164
|
+
|
|
165
|
+
```shell
|
|
166
|
+
python3 -m venv --copies ../venv
|
|
167
|
+
source ../venv/bin/activate
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Windows (PowerShell):
|
|
171
|
+
|
|
172
|
+
```powershell
|
|
173
|
+
py -m venv ..\venv
|
|
174
|
+
..\venv\Scripts\Activate.ps1
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
3. Install Woninet locally:
|
|
178
|
+
|
|
179
|
+
```shell
|
|
180
|
+
pip3 install .
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
4. Grant raw-socket access and run.
|
|
184
|
+
|
|
185
|
+
**Linux:** grant the capability to the virtual environment's interpreter, then run Woninet:
|
|
186
|
+
|
|
187
|
+
```shell
|
|
188
|
+
sudo setcap cap_net_raw=eip ../venv/bin/python3
|
|
189
|
+
woninet --version
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Running with `sudo` instead is possible but discouraged for security reasons:
|
|
193
|
+
|
|
194
|
+
```shell
|
|
195
|
+
sudo ../venv/bin/python3 -m woninet
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**macOS and Windows:** run `woninet --version` after installation.
|
|
199
|
+
|
|
200
|
+
## Configuration
|
|
201
|
+
|
|
202
|
+
Alert rules and monitoring settings are defined in a JSON file. Rename `config.example.json` to `config.json`; Woninet loads it at startup.
|
|
203
|
+
|
|
204
|
+
When installing from PyPI, `config.example.json` is not included, so Woninet creates a `config.json` file with default values.
|
|
205
|
+
|
|
206
|
+
To use a different configuration file, pass its path with the `--config` CLI flag.
|
|
207
|
+
|
|
208
|
+
### Example
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"monitoring": {
|
|
213
|
+
"arp_noise_limit": 300.0,
|
|
214
|
+
"max_workers": 4
|
|
215
|
+
},
|
|
216
|
+
"database": "woninet.db",
|
|
217
|
+
"target_ip_list": [
|
|
218
|
+
"192.168.1.1", "192.168.1.10", "192.168.1.20-30"
|
|
219
|
+
],
|
|
220
|
+
"alert_rules": [
|
|
221
|
+
{
|
|
222
|
+
"metric": "latency",
|
|
223
|
+
"threshold": 100,
|
|
224
|
+
"consecutive_checks": 3
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"metric": "packet_loss",
|
|
228
|
+
"threshold": 0.0,
|
|
229
|
+
"consecutive_checks": 1
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"metric": "jitter",
|
|
233
|
+
"threshold": 40.0,
|
|
234
|
+
"consecutive_checks": 3
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Settings reference
|
|
241
|
+
|
|
242
|
+
#### Monitoring
|
|
243
|
+
|
|
244
|
+
| Key | Description |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `arp_noise_limit` | Latency threshold in milliseconds used to filter ARP resolution noise. Set to `0` to disable filtering. Helps eliminate Wi-Fi latency spikes. |
|
|
247
|
+
| `max_workers` | Maximum number of worker threads used to send ICMP pings. Higher values may increase system load and latency. |
|
|
248
|
+
|
|
249
|
+
#### Database
|
|
250
|
+
|
|
251
|
+
| Key | Description |
|
|
252
|
+
|---|---|
|
|
253
|
+
| `database` | Path to the SQLite database file where metrics and alerts are stored. |
|
|
254
|
+
|
|
255
|
+
#### Target IP list
|
|
256
|
+
|
|
257
|
+
| Key | Description |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `target_ip_list` | A single address, a list of addresses, or a range (for example `192.168.1.1-100`) to scan. Monitoring is currently limited to a /24 subnet (see [Known Issues](#known-issues)). |
|
|
260
|
+
|
|
261
|
+
#### Alert rules
|
|
262
|
+
|
|
263
|
+
| Key | Description |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `metric` | The metric to evaluate: `latency`, `packet_loss`, or `jitter`. |
|
|
266
|
+
| `threshold` | The value that triggers the alert. |
|
|
267
|
+
| `consecutive_checks` | Number of consecutive evaluations required before the alert state changes. Higher values reduce false positives. |
|
|
268
|
+
|
|
269
|
+
#### Units and ranges
|
|
270
|
+
|
|
271
|
+
- **Latency:** thresholds are evaluated in milliseconds.
|
|
272
|
+
- **Jitter:** thresholds are evaluated in milliseconds.
|
|
273
|
+
- **Packet loss:** values are percentages in the range 0.0 to 100.0. A value of 100.0 indicates 100% packet loss, and a threshold of 0.0 triggers on any packet loss.
|
|
274
|
+
|
|
275
|
+
## Usage
|
|
276
|
+
|
|
277
|
+
See the [usage guide](https://github.com/teymuri-alireza/woninet/blob/main/docs/usage.md) for common ways to run Woninet and how to resolve common issues.
|
|
278
|
+
|
|
279
|
+
## Platform Notes
|
|
280
|
+
|
|
281
|
+
| Platform | Probing method | Privileges |
|
|
282
|
+
|---|---|---|
|
|
283
|
+
| Linux | `icmplib` (recommended) or system `ping` (fallback) | `cap_net_raw` on the interpreter, or root |
|
|
284
|
+
| macOS | Untested | Untested |
|
|
285
|
+
| Windows | Untested | Untested |
|
|
286
|
+
|
|
287
|
+
Woninet has been developed and tested on Linux. macOS and Windows have not been tested, so installation and behavior on those platforms are not guaranteed. Feedback and bug reports from users on these systems are welcome.
|
|
288
|
+
|
|
289
|
+
Docker deployment is available on Linux only.
|
|
290
|
+
|
|
291
|
+
## Testing
|
|
292
|
+
|
|
293
|
+
Install the optional test dependencies:
|
|
294
|
+
|
|
295
|
+
```shell
|
|
296
|
+
pip install -e ".[test]"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Then run:
|
|
300
|
+
|
|
301
|
+
```shell
|
|
302
|
+
pytest
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
The test suite currently focuses on API behavior and core logic and uses pytest for automated verification.
|
|
306
|
+
|
|
307
|
+
## Known Issues
|
|
308
|
+
|
|
309
|
+
- Monitoring is currently limited to a single /24 subnet.
|
|
310
|
+
|
|
311
|
+
## Documentation
|
|
312
|
+
|
|
313
|
+
For questions or clarification, see the [documentation](https://github.com/teymuri-alireza/woninet/blob/main/docs/documentation.md).
|
|
314
|
+
|
|
315
|
+
## Contributing
|
|
316
|
+
|
|
317
|
+
Thank you for considering a contribution to Woninet. To help maintain code quality, stability, and a predictable release process, please review the [Contributing Guide](https://github.com/teymuri-alireza/woninet/blob/main/CONTRIBUTING.md) before submitting changes.
|
|
318
|
+
|
|
319
|
+
## License
|
|
320
|
+
|
|
321
|
+
This project is licensed under the terms of the MIT license.
|
woninet-2.2.0/README.md
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Woninet
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/woninet/)
|
|
4
|
+
[](https://www.python.org/)
|
|
5
|
+
[](https://github.com/teymuri-alireza/woninet/blob/main/LICENSE)
|
|
6
|
+
[](https://pypi.org/project/woninet/)
|
|
7
|
+
|
|
8
|
+
A local network monitoring system.
|
|
9
|
+
|
|
10
|
+
**Woninet** continuously monitors devices on a local network using ARP and ICMP probes. It enumerates candidate IP addresses in a /24 subnet, determines device availability, measures latency, packet loss, and jitter, stores metrics in database, and evaluates configurable alert rules in real time.
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Features](#features)
|
|
17
|
+
- [Requirements](#requirements)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Usage](#usage)
|
|
22
|
+
- [Platform Notes](#platform-notes)
|
|
23
|
+
- [Testing](#testing)
|
|
24
|
+
- [Known Issues](#known-issues)
|
|
25
|
+
- [Documentation](#documentation)
|
|
26
|
+
- [Contributing](#contributing)
|
|
27
|
+
- [License](#license)
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- **ARP + ICMP host detection.** Distinguishes real devices from nonexistent IP addresses and filters out Wi-Fi ARP-delay noise.
|
|
32
|
+
- **Alert engine.** Evaluates real-time alert rules, such as latency thresholds, against collected metrics.
|
|
33
|
+
- **Threaded collectors.** Sends ICMP probes concurrently using a configurable number of worker threads.
|
|
34
|
+
- **SQLite storage.** Persists devices, recorded metrics, alert states, and alert events.
|
|
35
|
+
- **Database access from the CLI.** Accepts a positional argument for easier access to the database.
|
|
36
|
+
- **Detailed logging.**
|
|
37
|
+
|
|
38
|
+
## Requirements
|
|
39
|
+
|
|
40
|
+
- Python 3.12 or later.
|
|
41
|
+
- Elevated network privileges, because ARP and ICMP probing use raw sockets. On Linux, either of the following satisfies this requirement:
|
|
42
|
+
- the `cap_net_raw` capability granted to the Python interpreter (recommended, see [Installation](#installation)), or
|
|
43
|
+
- root privileges (discouraged for security reasons).
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
On Linux, the minimal path is:
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
python3 -m venv --copies venv
|
|
51
|
+
source venv/bin/activate
|
|
52
|
+
pip install woninet
|
|
53
|
+
sudo setcap cap_net_raw=eip venv/bin/python3
|
|
54
|
+
woninet --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For Docker, macOS, Windows, and source installs, see [Installation](#installation).
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
### Option 1: Install from PyPI
|
|
62
|
+
|
|
63
|
+
#### Linux (recommended: `icmplib` with `cap_net_raw`)
|
|
64
|
+
|
|
65
|
+
Create and activate a virtual environment. The `--copies` flag forces Python to copy the interpreter instead of symlinking it, which is required because the capability is applied directly to the interpreter binary:
|
|
66
|
+
|
|
67
|
+
```shell
|
|
68
|
+
python3 -m venv --copies venv
|
|
69
|
+
source venv/bin/activate
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Install Woninet:
|
|
73
|
+
|
|
74
|
+
```shell
|
|
75
|
+
pip install woninet
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Grant the required capability to the Python interpreter:
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
sudo setcap cap_net_raw=eip venv/bin/python3
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Run Woninet:
|
|
85
|
+
|
|
86
|
+
```shell
|
|
87
|
+
woninet --help
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Linux (fallback: system `ping`)
|
|
91
|
+
|
|
92
|
+
If you do not grant the capability, Woninet falls back to the system `ping` command. Create the environment without `--copies`:
|
|
93
|
+
|
|
94
|
+
```shell
|
|
95
|
+
python3 -m venv venv
|
|
96
|
+
source venv/bin/activate
|
|
97
|
+
pip install woninet
|
|
98
|
+
woninet --help
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### macOS and Windows
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
pip install woninet
|
|
105
|
+
woninet --help
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
See [Platform Notes](#platform-notes) for privilege considerations on these systems.
|
|
109
|
+
|
|
110
|
+
### Option 2: Docker (Linux only)
|
|
111
|
+
|
|
112
|
+
Clone the repository and run:
|
|
113
|
+
|
|
114
|
+
```shell
|
|
115
|
+
chmod +x build_docker.sh
|
|
116
|
+
sudo ./build_docker.sh
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The script runs `docker compose up -d --build` and prints the device's private IP address to standard output so you can open the web interface in a browser.
|
|
120
|
+
|
|
121
|
+
To open Woninet manually, type device's private IP address with the default `8080` port in the browser.
|
|
122
|
+
|
|
123
|
+
### Option 3: Install from source
|
|
124
|
+
|
|
125
|
+
1. Clone the repository:
|
|
126
|
+
|
|
127
|
+
```shell
|
|
128
|
+
git clone https://github.com/teymuri-alireza/woninet
|
|
129
|
+
cd woninet
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
2. Create and activate a virtual environment **outside** the project directory to avoid `Multiple top-level packages discovered in a flat-layout` errors.
|
|
133
|
+
|
|
134
|
+
Linux
|
|
135
|
+
|
|
136
|
+
```shell
|
|
137
|
+
python3 -m venv --copies ../venv
|
|
138
|
+
source ../venv/bin/activate
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Windows (PowerShell):
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
py -m venv ..\venv
|
|
145
|
+
..\venv\Scripts\Activate.ps1
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
3. Install Woninet locally:
|
|
149
|
+
|
|
150
|
+
```shell
|
|
151
|
+
pip3 install .
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
4. Grant raw-socket access and run.
|
|
155
|
+
|
|
156
|
+
**Linux:** grant the capability to the virtual environment's interpreter, then run Woninet:
|
|
157
|
+
|
|
158
|
+
```shell
|
|
159
|
+
sudo setcap cap_net_raw=eip ../venv/bin/python3
|
|
160
|
+
woninet --version
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Running with `sudo` instead is possible but discouraged for security reasons:
|
|
164
|
+
|
|
165
|
+
```shell
|
|
166
|
+
sudo ../venv/bin/python3 -m woninet
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**macOS and Windows:** run `woninet --version` after installation.
|
|
170
|
+
|
|
171
|
+
## Configuration
|
|
172
|
+
|
|
173
|
+
Alert rules and monitoring settings are defined in a JSON file. Rename `config.example.json` to `config.json`; Woninet loads it at startup.
|
|
174
|
+
|
|
175
|
+
When installing from PyPI, `config.example.json` is not included, so Woninet creates a `config.json` file with default values.
|
|
176
|
+
|
|
177
|
+
To use a different configuration file, pass its path with the `--config` CLI flag.
|
|
178
|
+
|
|
179
|
+
### Example
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"monitoring": {
|
|
184
|
+
"arp_noise_limit": 300.0,
|
|
185
|
+
"max_workers": 4
|
|
186
|
+
},
|
|
187
|
+
"database": "woninet.db",
|
|
188
|
+
"target_ip_list": [
|
|
189
|
+
"192.168.1.1", "192.168.1.10", "192.168.1.20-30"
|
|
190
|
+
],
|
|
191
|
+
"alert_rules": [
|
|
192
|
+
{
|
|
193
|
+
"metric": "latency",
|
|
194
|
+
"threshold": 100,
|
|
195
|
+
"consecutive_checks": 3
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"metric": "packet_loss",
|
|
199
|
+
"threshold": 0.0,
|
|
200
|
+
"consecutive_checks": 1
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"metric": "jitter",
|
|
204
|
+
"threshold": 40.0,
|
|
205
|
+
"consecutive_checks": 3
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Settings reference
|
|
212
|
+
|
|
213
|
+
#### Monitoring
|
|
214
|
+
|
|
215
|
+
| Key | Description |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `arp_noise_limit` | Latency threshold in milliseconds used to filter ARP resolution noise. Set to `0` to disable filtering. Helps eliminate Wi-Fi latency spikes. |
|
|
218
|
+
| `max_workers` | Maximum number of worker threads used to send ICMP pings. Higher values may increase system load and latency. |
|
|
219
|
+
|
|
220
|
+
#### Database
|
|
221
|
+
|
|
222
|
+
| Key | Description |
|
|
223
|
+
|---|---|
|
|
224
|
+
| `database` | Path to the SQLite database file where metrics and alerts are stored. |
|
|
225
|
+
|
|
226
|
+
#### Target IP list
|
|
227
|
+
|
|
228
|
+
| Key | Description |
|
|
229
|
+
|---|---|
|
|
230
|
+
| `target_ip_list` | A single address, a list of addresses, or a range (for example `192.168.1.1-100`) to scan. Monitoring is currently limited to a /24 subnet (see [Known Issues](#known-issues)). |
|
|
231
|
+
|
|
232
|
+
#### Alert rules
|
|
233
|
+
|
|
234
|
+
| Key | Description |
|
|
235
|
+
|---|---|
|
|
236
|
+
| `metric` | The metric to evaluate: `latency`, `packet_loss`, or `jitter`. |
|
|
237
|
+
| `threshold` | The value that triggers the alert. |
|
|
238
|
+
| `consecutive_checks` | Number of consecutive evaluations required before the alert state changes. Higher values reduce false positives. |
|
|
239
|
+
|
|
240
|
+
#### Units and ranges
|
|
241
|
+
|
|
242
|
+
- **Latency:** thresholds are evaluated in milliseconds.
|
|
243
|
+
- **Jitter:** thresholds are evaluated in milliseconds.
|
|
244
|
+
- **Packet loss:** values are percentages in the range 0.0 to 100.0. A value of 100.0 indicates 100% packet loss, and a threshold of 0.0 triggers on any packet loss.
|
|
245
|
+
|
|
246
|
+
## Usage
|
|
247
|
+
|
|
248
|
+
See the [usage guide](https://github.com/teymuri-alireza/woninet/blob/main/docs/usage.md) for common ways to run Woninet and how to resolve common issues.
|
|
249
|
+
|
|
250
|
+
## Platform Notes
|
|
251
|
+
|
|
252
|
+
| Platform | Probing method | Privileges |
|
|
253
|
+
|---|---|---|
|
|
254
|
+
| Linux | `icmplib` (recommended) or system `ping` (fallback) | `cap_net_raw` on the interpreter, or root |
|
|
255
|
+
| macOS | Untested | Untested |
|
|
256
|
+
| Windows | Untested | Untested |
|
|
257
|
+
|
|
258
|
+
Woninet has been developed and tested on Linux. macOS and Windows have not been tested, so installation and behavior on those platforms are not guaranteed. Feedback and bug reports from users on these systems are welcome.
|
|
259
|
+
|
|
260
|
+
Docker deployment is available on Linux only.
|
|
261
|
+
|
|
262
|
+
## Testing
|
|
263
|
+
|
|
264
|
+
Install the optional test dependencies:
|
|
265
|
+
|
|
266
|
+
```shell
|
|
267
|
+
pip install -e ".[test]"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Then run:
|
|
271
|
+
|
|
272
|
+
```shell
|
|
273
|
+
pytest
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The test suite currently focuses on API behavior and core logic and uses pytest for automated verification.
|
|
277
|
+
|
|
278
|
+
## Known Issues
|
|
279
|
+
|
|
280
|
+
- Monitoring is currently limited to a single /24 subnet.
|
|
281
|
+
|
|
282
|
+
## Documentation
|
|
283
|
+
|
|
284
|
+
For questions or clarification, see the [documentation](https://github.com/teymuri-alireza/woninet/blob/main/docs/documentation.md).
|
|
285
|
+
|
|
286
|
+
## Contributing
|
|
287
|
+
|
|
288
|
+
Thank you for considering a contribution to Woninet. To help maintain code quality, stability, and a predictable release process, please review the [Contributing Guide](https://github.com/teymuri-alireza/woninet/blob/main/CONTRIBUTING.md) before submitting changes.
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
This project is licensed under the terms of the MIT license.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "woninet"
|
|
7
|
-
version = "2.0
|
|
7
|
+
version = "2.2.0"
|
|
8
8
|
description = "A Python-based ARP+ICMP network monitoring tool"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -28,9 +28,13 @@ dependencies = [
|
|
|
28
28
|
"uvicorn>=0.44.0,<0.45",
|
|
29
29
|
"PyYAML>=6.0.3,<6.1",
|
|
30
30
|
"SQLAlchemy>=2.0.46,<2.1",
|
|
31
|
-
"
|
|
31
|
+
"python-multipart==0.0.32",
|
|
32
|
+
"fastapi-swagger>=0.4.64,<0.5",
|
|
32
33
|
]
|
|
33
34
|
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
include = ["woninet*"]
|
|
37
|
+
|
|
34
38
|
[tool.setuptools.package-data]
|
|
35
39
|
woninet = [
|
|
36
40
|
"server/static/**/*",
|
|
@@ -52,4 +56,5 @@ woninet = "woninet.main:main"
|
|
|
52
56
|
test = [
|
|
53
57
|
"pytest>=9.1.1,<9.2",
|
|
54
58
|
"httpx>=0.28.1,<0.29",
|
|
59
|
+
"ruff>=0.15.11,<0.16",
|
|
55
60
|
]
|