emion 0.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.
- emion-0.2.0/MANIFEST.in +3 -0
- emion-0.2.0/PKG-INFO +144 -0
- emion-0.2.0/README.md +120 -0
- emion-0.2.0/emion/__init__.py +19 -0
- emion-0.2.0/emion/cli.py +67 -0
- emion-0.2.0/emion/core/__init__.py +3 -0
- emion-0.2.0/emion/core/engine.py +74 -0
- emion-0.2.0/emion/core/network.py +101 -0
- emion-0.2.0/emion/core/node.py +188 -0
- emion-0.2.0/emion/dashboard/__init__.py +1 -0
- emion-0.2.0/emion/dashboard/server.py +240 -0
- emion-0.2.0/emion/dashboard/static/app.js +287 -0
- emion-0.2.0/emion/dashboard/static/index.html +119 -0
- emion-0.2.0/emion/dashboard/static/style.css +218 -0
- emion-0.2.0/emion/plugins/__init__.py +10 -0
- emion-0.2.0/emion/plugins/base.py +122 -0
- emion-0.2.0/emion.egg-info/PKG-INFO +144 -0
- emion-0.2.0/emion.egg-info/SOURCES.txt +24 -0
- emion-0.2.0/emion.egg-info/dependency_links.txt +1 -0
- emion-0.2.0/emion.egg-info/entry_points.txt +2 -0
- emion-0.2.0/emion.egg-info/requires.txt +5 -0
- emion-0.2.0/emion.egg-info/top_level.txt +1 -0
- emion-0.2.0/pyproject.toml +44 -0
- emion-0.2.0/setup.cfg +4 -0
- emion-0.2.0/setup.py +22 -0
- emion-0.2.0/tests/test_emion.py +147 -0
emion-0.2.0/MANIFEST.in
ADDED
emion-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: emion
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Professional ION-DTN Mission Control & BPv7 Simulation Framework
|
|
5
|
+
Author: EmION Team
|
|
6
|
+
Author-email: EmION Team <dev@info-gallary.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/info-gallary/emion
|
|
9
|
+
Project-URL: Repository, https://github.com/info-gallary/emion.git
|
|
10
|
+
Keywords: dtn,ion,bpv7,simulation,space,networking
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Provides-Extra: dashboard
|
|
20
|
+
Requires-Dist: fastapi>=0.100.0; extra == "dashboard"
|
|
21
|
+
Requires-Dist: uvicorn>=0.20.0; extra == "dashboard"
|
|
22
|
+
Requires-Dist: websockets>=11.0; extra == "dashboard"
|
|
23
|
+
Dynamic: author
|
|
24
|
+
|
|
25
|
+
# โ๏ธ EmION โ Professional ION-DTN Simulation
|
|
26
|
+
|
|
27
|
+
EmION is an authentic, production-ready Delay-Tolerant Networking (DTN) simulation framework. Unlike other simulators, EmION uses the **real ION-DTN C-engine** and **Contact Graph Routing (CGR)** for 100% protocol authenticity.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ๐ 1. Installation
|
|
32
|
+
|
|
33
|
+
EmION requires **ION-DTN** (C-engine) and **pyion** to be installed on your Linux system.
|
|
34
|
+
|
|
35
|
+
### One-Click Setup
|
|
36
|
+
We provide a unified installer that checks dependencies and installs the package:
|
|
37
|
+
```bash
|
|
38
|
+
chmod +x install.sh
|
|
39
|
+
./install.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Manual Installation
|
|
43
|
+
```bash
|
|
44
|
+
pip install -e ".[dashboard]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## ๐งช 2. Verification
|
|
50
|
+
|
|
51
|
+
Ensure your environment is correctly configured by running the professional test suite. This verifies real-time bundle transit and CGR routing:
|
|
52
|
+
```bash
|
|
53
|
+
python3 tests/test_emion.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## ๐ฐ๏ธ 3. Usage
|
|
59
|
+
|
|
60
|
+
### Launching Mission Control
|
|
61
|
+
Start the visual dashboard to manage multi-node topologies and view live telemetry:
|
|
62
|
+
```bash
|
|
63
|
+
emion dashboard
|
|
64
|
+
```
|
|
65
|
+
- **URL**: `http://localhost:8420`
|
|
66
|
+
- **Telemetry**: Real-time SDR memory and bundle tracking.
|
|
67
|
+
- **Visuals**: Canvas-based topology with bundle animation.
|
|
68
|
+
|
|
69
|
+
### Command Line Interface
|
|
70
|
+
```bash
|
|
71
|
+
emion info # Check ION system status
|
|
72
|
+
emion dashboard # Start visual UI
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## ๐ 4. Connecting Third-Party Modules (API)
|
|
78
|
+
|
|
79
|
+
EmION supports selective attachment of Anomaly Detection or Security modules via a **FastAPI-based Plugin System**.
|
|
80
|
+
|
|
81
|
+
### Step A: Implement your Plugin
|
|
82
|
+
Your module must be a web service (FastAPI) with these endpoints:
|
|
83
|
+
1. `GET /health` -> `{"status": "ok"}`
|
|
84
|
+
2. `POST /analyze` -> Receives bundle `payload` and `metadata`, returns:
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"is_anomaly": true,
|
|
88
|
+
"score": 0.95,
|
|
89
|
+
"label": "attack",
|
|
90
|
+
"details": {"reason": "Payload too large"}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Step B: Connect to EmION
|
|
95
|
+
In the Dashboard UI (or via API), connect your module:
|
|
96
|
+
- **Module URL**: `http://localhost:8421`
|
|
97
|
+
- **Target Nodes**: Selectively monitor specific nodes (e.g., `1,3`) or `all`.
|
|
98
|
+
|
|
99
|
+
### Demo Reference
|
|
100
|
+
See `anomaly_detector.py` for a functional sample implementation.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## ๐ณ 5. Docker (Self-Contained BPv7)
|
|
105
|
+
|
|
106
|
+
Run the entire EmION environment (ION-DTN + pyion + Dashboard) without local installation.
|
|
107
|
+
|
|
108
|
+
### Build and Run
|
|
109
|
+
```bash
|
|
110
|
+
docker build -t emion .
|
|
111
|
+
docker run -p 8420:8420 emion
|
|
112
|
+
```
|
|
113
|
+
Access Mission Control at `http://localhost:8420`.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## ๐ฆ 6. Publishing to PyPI
|
|
118
|
+
|
|
119
|
+
### Build the Package
|
|
120
|
+
```bash
|
|
121
|
+
pip install build twine
|
|
122
|
+
python3 -m build
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Upload to PyPI
|
|
126
|
+
```bash
|
|
127
|
+
twine upload dist/*
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## ๐๏ธ Project Structure
|
|
133
|
+
- `emion/` โ Core BPv7 orchestration.
|
|
134
|
+
- `docs/` โ [Coding Guide](docs/coding_guide.md) & [Usage Notebook](docs/usage_demo.ipynb).
|
|
135
|
+
- `ION-DTN/` โ Authentic NASA-JPL C-Engine.
|
|
136
|
+
- `Dockerfile` โ Professional self-contained environment.
|
|
137
|
+
- `README.md` โ This guide.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
**Authentic. Professional. Space-Ready.** โ๏ธ
|
|
142
|
+
- ION-DTN (compiled, with ionadmin/bpadmin in PATH)
|
|
143
|
+
- pyion (built against your ION installation)
|
|
144
|
+
- FastAPI + uvicorn + websockets (for dashboard)
|
emion-0.2.0/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# โ๏ธ EmION โ Professional ION-DTN Simulation
|
|
2
|
+
|
|
3
|
+
EmION is an authentic, production-ready Delay-Tolerant Networking (DTN) simulation framework. Unlike other simulators, EmION uses the **real ION-DTN C-engine** and **Contact Graph Routing (CGR)** for 100% protocol authenticity.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ๐ 1. Installation
|
|
8
|
+
|
|
9
|
+
EmION requires **ION-DTN** (C-engine) and **pyion** to be installed on your Linux system.
|
|
10
|
+
|
|
11
|
+
### One-Click Setup
|
|
12
|
+
We provide a unified installer that checks dependencies and installs the package:
|
|
13
|
+
```bash
|
|
14
|
+
chmod +x install.sh
|
|
15
|
+
./install.sh
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Manual Installation
|
|
19
|
+
```bash
|
|
20
|
+
pip install -e ".[dashboard]"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## ๐งช 2. Verification
|
|
26
|
+
|
|
27
|
+
Ensure your environment is correctly configured by running the professional test suite. This verifies real-time bundle transit and CGR routing:
|
|
28
|
+
```bash
|
|
29
|
+
python3 tests/test_emion.py
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## ๐ฐ๏ธ 3. Usage
|
|
35
|
+
|
|
36
|
+
### Launching Mission Control
|
|
37
|
+
Start the visual dashboard to manage multi-node topologies and view live telemetry:
|
|
38
|
+
```bash
|
|
39
|
+
emion dashboard
|
|
40
|
+
```
|
|
41
|
+
- **URL**: `http://localhost:8420`
|
|
42
|
+
- **Telemetry**: Real-time SDR memory and bundle tracking.
|
|
43
|
+
- **Visuals**: Canvas-based topology with bundle animation.
|
|
44
|
+
|
|
45
|
+
### Command Line Interface
|
|
46
|
+
```bash
|
|
47
|
+
emion info # Check ION system status
|
|
48
|
+
emion dashboard # Start visual UI
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## ๐ 4. Connecting Third-Party Modules (API)
|
|
54
|
+
|
|
55
|
+
EmION supports selective attachment of Anomaly Detection or Security modules via a **FastAPI-based Plugin System**.
|
|
56
|
+
|
|
57
|
+
### Step A: Implement your Plugin
|
|
58
|
+
Your module must be a web service (FastAPI) with these endpoints:
|
|
59
|
+
1. `GET /health` -> `{"status": "ok"}`
|
|
60
|
+
2. `POST /analyze` -> Receives bundle `payload` and `metadata`, returns:
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"is_anomaly": true,
|
|
64
|
+
"score": 0.95,
|
|
65
|
+
"label": "attack",
|
|
66
|
+
"details": {"reason": "Payload too large"}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step B: Connect to EmION
|
|
71
|
+
In the Dashboard UI (or via API), connect your module:
|
|
72
|
+
- **Module URL**: `http://localhost:8421`
|
|
73
|
+
- **Target Nodes**: Selectively monitor specific nodes (e.g., `1,3`) or `all`.
|
|
74
|
+
|
|
75
|
+
### Demo Reference
|
|
76
|
+
See `anomaly_detector.py` for a functional sample implementation.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## ๐ณ 5. Docker (Self-Contained BPv7)
|
|
81
|
+
|
|
82
|
+
Run the entire EmION environment (ION-DTN + pyion + Dashboard) without local installation.
|
|
83
|
+
|
|
84
|
+
### Build and Run
|
|
85
|
+
```bash
|
|
86
|
+
docker build -t emion .
|
|
87
|
+
docker run -p 8420:8420 emion
|
|
88
|
+
```
|
|
89
|
+
Access Mission Control at `http://localhost:8420`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## ๐ฆ 6. Publishing to PyPI
|
|
94
|
+
|
|
95
|
+
### Build the Package
|
|
96
|
+
```bash
|
|
97
|
+
pip install build twine
|
|
98
|
+
python3 -m build
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Upload to PyPI
|
|
102
|
+
```bash
|
|
103
|
+
twine upload dist/*
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## ๐๏ธ Project Structure
|
|
109
|
+
- `emion/` โ Core BPv7 orchestration.
|
|
110
|
+
- `docs/` โ [Coding Guide](docs/coding_guide.md) & [Usage Notebook](docs/usage_demo.ipynb).
|
|
111
|
+
- `ION-DTN/` โ Authentic NASA-JPL C-Engine.
|
|
112
|
+
- `Dockerfile` โ Professional self-contained environment.
|
|
113
|
+
- `README.md` โ This guide.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
**Authentic. Professional. Space-Ready.** โ๏ธ
|
|
118
|
+
- ION-DTN (compiled, with ionadmin/bpadmin in PATH)
|
|
119
|
+
- pyion (built against your ION installation)
|
|
120
|
+
- FastAPI + uvicorn + websockets (for dashboard)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EmION โ Authentic ION-DTN Framework.
|
|
3
|
+
All operations use real ION C-engine + pyion. No dummies.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "0.1.0"
|
|
7
|
+
__author__ = "EmION Team"
|
|
8
|
+
|
|
9
|
+
from .core.node import EmionNode
|
|
10
|
+
from .core.engine import EmionEngine
|
|
11
|
+
from .plugins.base import APIPlugin
|
|
12
|
+
|
|
13
|
+
ION_AVAILABLE = True
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def dashboard(host="0.0.0.0", port=8420):
|
|
17
|
+
"""Launch the EmION web dashboard."""
|
|
18
|
+
from .dashboard.server import run
|
|
19
|
+
run(host=host, port=port)
|
emion-0.2.0/emion/cli.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EmION CLI โ all operations use real ION-DTN.
|
|
3
|
+
|
|
4
|
+
emion dashboard Launch the web dashboard
|
|
5
|
+
emion info Show ION-DTN status
|
|
6
|
+
emion test Run the 2-node communication test
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import argparse
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
parser = argparse.ArgumentParser(
|
|
15
|
+
prog="emion",
|
|
16
|
+
description="EmION โ Authentic ION-DTN Framework"
|
|
17
|
+
)
|
|
18
|
+
sub = parser.add_subparsers(dest="cmd")
|
|
19
|
+
|
|
20
|
+
d = sub.add_parser("dashboard", help="Launch the web dashboard")
|
|
21
|
+
d.add_argument("--host", default="0.0.0.0")
|
|
22
|
+
d.add_argument("--port", type=int, default=8420)
|
|
23
|
+
|
|
24
|
+
sub.add_parser("info", help="Show ION-DTN status")
|
|
25
|
+
sub.add_parser("test", help="Run 2-node comm test")
|
|
26
|
+
|
|
27
|
+
args = parser.parse_args()
|
|
28
|
+
|
|
29
|
+
if args.cmd == "dashboard":
|
|
30
|
+
from emion.dashboard.server import run
|
|
31
|
+
run(host=args.host, port=args.port)
|
|
32
|
+
elif args.cmd == "info":
|
|
33
|
+
_info()
|
|
34
|
+
elif args.cmd == "test":
|
|
35
|
+
_test()
|
|
36
|
+
else:
|
|
37
|
+
parser.print_help()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _info():
|
|
41
|
+
import shutil
|
|
42
|
+
import emion
|
|
43
|
+
print(f"\n โ EmION v{emion.__version__}")
|
|
44
|
+
for cmd in ["ionadmin", "bpadmin", "ionsecadmin", "bprecvfile", "bpsendfile"]:
|
|
45
|
+
path = shutil.which(cmd)
|
|
46
|
+
print(f" {cmd}: {'โ
' + path if path else 'โ not found'}")
|
|
47
|
+
try:
|
|
48
|
+
import pyion
|
|
49
|
+
print(f" pyion: โ
")
|
|
50
|
+
except ImportError:
|
|
51
|
+
print(f" pyion: โ not found")
|
|
52
|
+
try:
|
|
53
|
+
import fastapi
|
|
54
|
+
print(f" fastapi: v{fastapi.__version__}")
|
|
55
|
+
except ImportError:
|
|
56
|
+
print(f" fastapi: โ (pip install fastapi uvicorn websockets)")
|
|
57
|
+
print()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _test():
|
|
61
|
+
from tests.test_emion import test_two_node_communication
|
|
62
|
+
ok = test_two_node_communication()
|
|
63
|
+
sys.exit(0 if ok else 1)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
main()
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EmionEngine โ Python interface to ION-DTN via pyion C-bindings.
|
|
3
|
+
Handles memory attachment, bundle send/receive.
|
|
4
|
+
No dummies โ requires a running ION node.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
import pyion
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EmionEngine:
|
|
13
|
+
"""
|
|
14
|
+
High-level Python wrapper over pyion C-bindings for a single ION node.
|
|
15
|
+
Must be used after EmionNode.start() has booted the C daemons.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, node_id: int, base_dir: str = "/tmp/emion_nodes"):
|
|
19
|
+
self.node_id = node_id
|
|
20
|
+
self.node_dir = os.path.join(base_dir, str(node_id))
|
|
21
|
+
self.proxy = None
|
|
22
|
+
|
|
23
|
+
def attach(self, retries=5, delay=2):
|
|
24
|
+
"""Attach to the ION shared-memory region via pyion."""
|
|
25
|
+
print(f"[EmION] Attaching engine to Node {self.node_id}...")
|
|
26
|
+
|
|
27
|
+
# Ensure ION_NODE_LIST_DIR is unset โ we use cwd instead
|
|
28
|
+
os.environ.pop("ION_NODE_LIST_DIR", None)
|
|
29
|
+
pyion.ION_NODE_LIST_DIR = None
|
|
30
|
+
os.environ["ION_NODE_NUMBER"] = str(self.node_id)
|
|
31
|
+
|
|
32
|
+
saved_dir = os.getcwd()
|
|
33
|
+
os.chdir(self.node_dir)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
for attempt in range(1, retries + 1):
|
|
37
|
+
try:
|
|
38
|
+
self.proxy = pyion.get_bp_proxy(self.node_id)
|
|
39
|
+
print(f" โ
Attached (attempt {attempt})")
|
|
40
|
+
return True
|
|
41
|
+
except Exception as e:
|
|
42
|
+
print(f" [!] Attempt {attempt}/{retries}: {e}")
|
|
43
|
+
time.sleep(delay)
|
|
44
|
+
finally:
|
|
45
|
+
os.chdir(saved_dir)
|
|
46
|
+
|
|
47
|
+
raise RuntimeError(
|
|
48
|
+
f"Cannot attach to ION Node {self.node_id}. "
|
|
49
|
+
f"Is the node running? Check {self.node_dir}/node_boot.log"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def send(self, src_eid: str, dst_eid: str, payload: bytes):
|
|
53
|
+
"""Send a bundle via the real ION Bundle Protocol engine."""
|
|
54
|
+
if not self.proxy:
|
|
55
|
+
self.attach()
|
|
56
|
+
with self.proxy.bp_open(src_eid) as ep:
|
|
57
|
+
result = ep.bp_send(dst_eid, payload)
|
|
58
|
+
print(f" ๐ก Sent {len(payload)}B {src_eid} โ {dst_eid}")
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
def receive(self, eid: str, timeout: int = 10):
|
|
62
|
+
"""Receive a bundle from the ION BP engine."""
|
|
63
|
+
if not self.proxy:
|
|
64
|
+
self.attach()
|
|
65
|
+
with self.proxy.bp_open(eid) as ep:
|
|
66
|
+
data = ep.bp_receive(timeout=timeout)
|
|
67
|
+
if data:
|
|
68
|
+
print(f" ๐ฅ Received {len(data)}B on {eid}")
|
|
69
|
+
return data
|
|
70
|
+
|
|
71
|
+
def detach(self):
|
|
72
|
+
"""Detach from the ION proxy."""
|
|
73
|
+
if self.proxy:
|
|
74
|
+
self.proxy = None
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Emion Network - High-level orchestration API for ION-DTN.
|
|
3
|
+
Provides simple functional interface for notebooks and scripts.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import time
|
|
7
|
+
import subprocess
|
|
8
|
+
from typing import List, Dict, Optional
|
|
9
|
+
from emion.core.node import EmionNode
|
|
10
|
+
from emion.core.engine import EmionEngine
|
|
11
|
+
from emion.plugins.base import APIPlugin
|
|
12
|
+
|
|
13
|
+
_nodes: Dict[int, EmionNode] = {}
|
|
14
|
+
_engines: Dict[int, EmionEngine] = {}
|
|
15
|
+
_plugins: Dict[str, APIPlugin] = {}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def register_node(node_id: int):
|
|
19
|
+
"""Register an authentic ION-DTN node."""
|
|
20
|
+
if node_id in _nodes:
|
|
21
|
+
return _nodes[node_id]
|
|
22
|
+
|
|
23
|
+
n = EmionNode(node_id)
|
|
24
|
+
# auto-connect routing
|
|
25
|
+
for existing_id, existing_node in _nodes.items():
|
|
26
|
+
n.connect_to(existing_id)
|
|
27
|
+
existing_node.connect_to(node_id)
|
|
28
|
+
|
|
29
|
+
_nodes[node_id] = n
|
|
30
|
+
return n
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def start_core(cleanup: bool = True):
|
|
34
|
+
"""
|
|
35
|
+
Boot all registered ION nodes.
|
|
36
|
+
Minimum 2 nodes recommended for routing verification.
|
|
37
|
+
"""
|
|
38
|
+
if cleanup:
|
|
39
|
+
print("[EmION] Cleaning up existing ION processes (killm)...")
|
|
40
|
+
subprocess.run(["killm"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
41
|
+
time.sleep(2)
|
|
42
|
+
|
|
43
|
+
print(f"[EmION] Initializing {len(_nodes)} nodes...")
|
|
44
|
+
for nid, node in _nodes.items():
|
|
45
|
+
node.start(cleanup=False)
|
|
46
|
+
|
|
47
|
+
# Wait for shared memory regions to stabilize
|
|
48
|
+
time.sleep(6)
|
|
49
|
+
|
|
50
|
+
print("[EmION] Attaching bundle engines...")
|
|
51
|
+
for nid in _nodes:
|
|
52
|
+
eng = EmionEngine(nid)
|
|
53
|
+
eng.attach()
|
|
54
|
+
_engines[nid] = eng
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def stop_core():
|
|
58
|
+
"""Shut down all ION nodes and engines."""
|
|
59
|
+
for nid, node in _nodes.items():
|
|
60
|
+
try:
|
|
61
|
+
node.stop()
|
|
62
|
+
except:
|
|
63
|
+
pass
|
|
64
|
+
_engines.clear()
|
|
65
|
+
subprocess.run(["killm"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def send_bundle(src: int, dst: int, payload: str):
|
|
69
|
+
"""Send a real BPv7 bundle via IPN."""
|
|
70
|
+
if src not in _engines:
|
|
71
|
+
raise RuntimeError(f"Engine for Node {src} not initialized. Call start_core() first.")
|
|
72
|
+
|
|
73
|
+
src_eid = f"ipn:{src}.1"
|
|
74
|
+
dst_eid = f"ipn:{dst}.1"
|
|
75
|
+
data = payload.encode()
|
|
76
|
+
|
|
77
|
+
res = _engines[src].send(src_eid, dst_eid, data)
|
|
78
|
+
|
|
79
|
+
# Analyze with plugins
|
|
80
|
+
module_results = {}
|
|
81
|
+
for name, plugin in _plugins.items():
|
|
82
|
+
module_results[name] = plugin.analyze(data, {"src": src_eid, "dst": dst_eid})
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
"status": "sent",
|
|
86
|
+
"bundle_id": res,
|
|
87
|
+
"src": src_eid,
|
|
88
|
+
"dst": dst_eid,
|
|
89
|
+
"size": len(data),
|
|
90
|
+
"analyzer_results": module_results
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def attach_plugin(url: str, target_nodes: str = "all"):
|
|
95
|
+
"""Attach an external anomaly/security module."""
|
|
96
|
+
plugin = APIPlugin(base_url=url, name=url)
|
|
97
|
+
if plugin.health_check():
|
|
98
|
+
_plugins[url] = plugin
|
|
99
|
+
return {"status": "ok", "url": url}
|
|
100
|
+
else:
|
|
101
|
+
raise ConnectionError(f"Could not reach plugin at {url}/health")
|