iotsploit-protocols 0.0.9__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.
- iotsploit_protocols-0.0.9/PKG-INFO +118 -0
- iotsploit_protocols-0.0.9/README.md +86 -0
- iotsploit_protocols-0.0.9/pyproject.toml +46 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/__init__.py +20 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/autosar/__init__.py +12 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/autosar/arxml.py +765 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/__init__.py +56 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/bus_match.py +121 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/catalog.py +425 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/codec.py +455 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/definitions.py +252 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/errorframes.py +154 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/errors.py +47 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/logfile.py +753 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/canbus/socketcan.py +385 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/doip/__init__.py +22 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/doip/client.py +267 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/doip/facet.py +51 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/doip/uds.py +262 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/errors.py +45 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/someip/__init__.py +19 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/someip/client.py +322 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/someip/codec.py +11 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/someip/facet.py +71 -0
- iotsploit_protocols-0.0.9/src/iotsploit_protocols/someip/sd.py +355 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iotsploit-protocols
|
|
3
|
+
Version: 0.0.9
|
|
4
|
+
Summary: Automotive protocol clients and description parsers for IoTSploit
|
|
5
|
+
License: GPL-3.0-or-later
|
|
6
|
+
Keywords: someip,doip,uds,automotive,security,testing
|
|
7
|
+
Author: IoTSploit Team
|
|
8
|
+
Author-email: support@iotsploit.org
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Information Technology
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Requires-Dist: cantools (==42.0.3)
|
|
23
|
+
Requires-Dist: iotsploit-core
|
|
24
|
+
Requires-Dist: psutil (>=5.9)
|
|
25
|
+
Requires-Dist: pydantic (>=2.0)
|
|
26
|
+
Requires-Dist: python-can (>=4.5)
|
|
27
|
+
Requires-Dist: scapy (>=2.6,<3)
|
|
28
|
+
Project-URL: Homepage, https://www.iotsploit.org/
|
|
29
|
+
Project-URL: Repository, https://github.com/TKXB/iotsploit
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# iotsploit-protocols
|
|
33
|
+
|
|
34
|
+
Automotive protocol clients and description parsers for IoTSploit: SOME/IP,
|
|
35
|
+
DoIP/UDS, and AUTOSAR ARXML.
|
|
36
|
+
|
|
37
|
+
Nothing in this package reads the IoTSploit database, runtime configuration,
|
|
38
|
+
environment variables, or the current target, and nothing runs `sudo` or
|
|
39
|
+
prompts a human. Clients receive explicit config objects and description
|
|
40
|
+
parsers receive caller-selected files. That is what lets them run under
|
|
41
|
+
Celery, under MCP, in a test, or from a plugin — and what keeps one lab bench's
|
|
42
|
+
IP addresses out of a library.
|
|
43
|
+
|
|
44
|
+
scapy is used as a **codec, not as a socket**: packets are built and parsed with
|
|
45
|
+
`scapy.contrib.automotive`, but I/O happens on ordinary sockets, so calling a
|
|
46
|
+
method needs no root.
|
|
47
|
+
|
|
48
|
+
## SOME/IP
|
|
49
|
+
|
|
50
|
+
Call a method:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from iotsploit_protocols.someip import SomeIpClient, SomeIpConfig
|
|
54
|
+
|
|
55
|
+
with SomeIpClient(SomeIpConfig(host="198.18.34.10", port=30509)) as client:
|
|
56
|
+
response = client.call(service=0x1234, instance=0x0001, method=0x0002, payload=b"\x01")
|
|
57
|
+
if response.ok:
|
|
58
|
+
print(response.payload.hex())
|
|
59
|
+
else:
|
|
60
|
+
print("refused:", response.return_code_name)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Fire-and-forget:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
client.notify(service=0x1234, instance=0x0001, method=0x0003, payload=b"\x07")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Hear what a segment announces — passive, no traffic generated, no root:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from iotsploit_protocols.someip import ServiceDiscovery, SdConfig
|
|
73
|
+
|
|
74
|
+
sd = ServiceDiscovery(SdConfig(group="224.244.224.245", interface="eth0"))
|
|
75
|
+
for offer in sd.listen(timeout=10.0):
|
|
76
|
+
print(offer.canonical_id, offer.endpoints) # "1234:0001" [('198.18.34.10', 30509, 'tcp')]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`canonical_id` is the form observations store as `subject_id`, so a discovered
|
|
80
|
+
service joins against the reference catalog without any string munging at the
|
|
81
|
+
call site.
|
|
82
|
+
|
|
83
|
+
## Configuration from a target
|
|
84
|
+
|
|
85
|
+
Inside the IoTSploit app, don't build the config by hand — the Django binding
|
|
86
|
+
layer resolves it from the current target's `someip` facet and component
|
|
87
|
+
address:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from iotsploit_django.adapters.django.protocol_binding import someip_client_for
|
|
91
|
+
|
|
92
|
+
with someip_client_for("TCAM") as client:
|
|
93
|
+
...
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
An unconfigured target raises `NotConfigured` rather than falling back to a
|
|
97
|
+
built-in address, because a helper that guesses a host probes whatever is at
|
|
98
|
+
that address and reports its silence as a finding.
|
|
99
|
+
|
|
100
|
+
## Errors
|
|
101
|
+
|
|
102
|
+
| exception | meaning |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `NotConfigured` | settings are missing — fix the target, not the code |
|
|
105
|
+
| `NegativeResponse` | the peer answered and said no |
|
|
106
|
+
| `ProtocolError` | malformed or unmatchable traffic |
|
|
107
|
+
|
|
108
|
+
Transport failures are left as stdlib `ConnectionError` / `TimeoutError` rather
|
|
109
|
+
than re-spelled in a new namespace.
|
|
110
|
+
|
|
111
|
+
## Tests
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
poetry run pytest iotsploit-protocols/tests
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
No hardware and no network: loopback servers stand in for ECUs.
|
|
118
|
+
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# iotsploit-protocols
|
|
2
|
+
|
|
3
|
+
Automotive protocol clients and description parsers for IoTSploit: SOME/IP,
|
|
4
|
+
DoIP/UDS, and AUTOSAR ARXML.
|
|
5
|
+
|
|
6
|
+
Nothing in this package reads the IoTSploit database, runtime configuration,
|
|
7
|
+
environment variables, or the current target, and nothing runs `sudo` or
|
|
8
|
+
prompts a human. Clients receive explicit config objects and description
|
|
9
|
+
parsers receive caller-selected files. That is what lets them run under
|
|
10
|
+
Celery, under MCP, in a test, or from a plugin — and what keeps one lab bench's
|
|
11
|
+
IP addresses out of a library.
|
|
12
|
+
|
|
13
|
+
scapy is used as a **codec, not as a socket**: packets are built and parsed with
|
|
14
|
+
`scapy.contrib.automotive`, but I/O happens on ordinary sockets, so calling a
|
|
15
|
+
method needs no root.
|
|
16
|
+
|
|
17
|
+
## SOME/IP
|
|
18
|
+
|
|
19
|
+
Call a method:
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from iotsploit_protocols.someip import SomeIpClient, SomeIpConfig
|
|
23
|
+
|
|
24
|
+
with SomeIpClient(SomeIpConfig(host="198.18.34.10", port=30509)) as client:
|
|
25
|
+
response = client.call(service=0x1234, instance=0x0001, method=0x0002, payload=b"\x01")
|
|
26
|
+
if response.ok:
|
|
27
|
+
print(response.payload.hex())
|
|
28
|
+
else:
|
|
29
|
+
print("refused:", response.return_code_name)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Fire-and-forget:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
client.notify(service=0x1234, instance=0x0001, method=0x0003, payload=b"\x07")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Hear what a segment announces — passive, no traffic generated, no root:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from iotsploit_protocols.someip import ServiceDiscovery, SdConfig
|
|
42
|
+
|
|
43
|
+
sd = ServiceDiscovery(SdConfig(group="224.244.224.245", interface="eth0"))
|
|
44
|
+
for offer in sd.listen(timeout=10.0):
|
|
45
|
+
print(offer.canonical_id, offer.endpoints) # "1234:0001" [('198.18.34.10', 30509, 'tcp')]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`canonical_id` is the form observations store as `subject_id`, so a discovered
|
|
49
|
+
service joins against the reference catalog without any string munging at the
|
|
50
|
+
call site.
|
|
51
|
+
|
|
52
|
+
## Configuration from a target
|
|
53
|
+
|
|
54
|
+
Inside the IoTSploit app, don't build the config by hand — the Django binding
|
|
55
|
+
layer resolves it from the current target's `someip` facet and component
|
|
56
|
+
address:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from iotsploit_django.adapters.django.protocol_binding import someip_client_for
|
|
60
|
+
|
|
61
|
+
with someip_client_for("TCAM") as client:
|
|
62
|
+
...
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
An unconfigured target raises `NotConfigured` rather than falling back to a
|
|
66
|
+
built-in address, because a helper that guesses a host probes whatever is at
|
|
67
|
+
that address and reports its silence as a finding.
|
|
68
|
+
|
|
69
|
+
## Errors
|
|
70
|
+
|
|
71
|
+
| exception | meaning |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `NotConfigured` | settings are missing — fix the target, not the code |
|
|
74
|
+
| `NegativeResponse` | the peer answered and said no |
|
|
75
|
+
| `ProtocolError` | malformed or unmatchable traffic |
|
|
76
|
+
|
|
77
|
+
Transport failures are left as stdlib `ConnectionError` / `TimeoutError` rather
|
|
78
|
+
than re-spelled in a new namespace.
|
|
79
|
+
|
|
80
|
+
## Tests
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
poetry run pytest iotsploit-protocols/tests
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
No hardware and no network: loopback servers stand in for ECUs.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "iotsploit-protocols"
|
|
3
|
+
version = "0.0.9"
|
|
4
|
+
description = "Automotive protocol clients and description parsers for IoTSploit"
|
|
5
|
+
authors = ["IoTSploit Team <support@iotsploit.org>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
license = "GPL-3.0-or-later"
|
|
8
|
+
homepage = "https://www.iotsploit.org/"
|
|
9
|
+
repository = "https://github.com/TKXB/iotsploit"
|
|
10
|
+
keywords = ["someip", "doip", "uds", "automotive", "security", "testing"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Intended Audience :: Information Technology",
|
|
15
|
+
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
|
16
|
+
"Topic :: Security",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
]
|
|
22
|
+
packages = [{ include = "iotsploit_protocols", from = "src" }]
|
|
23
|
+
|
|
24
|
+
[tool.poetry.dependencies]
|
|
25
|
+
python = ">=3.10,<4.0"
|
|
26
|
+
iotsploit-core = "*"
|
|
27
|
+
# SOME/IP service discovery parsing and the DoIP socket both come from
|
|
28
|
+
# scapy.contrib.automotive, which needs 2.5+; 2.6 is what the workspace runs.
|
|
29
|
+
scapy = ">=2.6,<3"
|
|
30
|
+
pydantic = ">=2.0"
|
|
31
|
+
cantools = "42.0.3"
|
|
32
|
+
# Same range iotsploit-drivers already pins. The SocketCAN clients import it
|
|
33
|
+
# lazily so that previewing a frame works on a host with no CAN interface.
|
|
34
|
+
python-can = ">=4.5"
|
|
35
|
+
psutil = ">=5.9"
|
|
36
|
+
|
|
37
|
+
[tool.poetry.group.dev.dependencies]
|
|
38
|
+
pytest = ">=8.0"
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["poetry-core>=1.8.0"]
|
|
42
|
+
build-backend = "poetry.core.masonry.api"
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
testpaths = ["tests"]
|
|
46
|
+
addopts = ["-q"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Automotive protocol clients and description parsers, free of runtime state.
|
|
2
|
+
|
|
3
|
+
Nothing here reads the IoTSploit database, environment variables, or the
|
|
4
|
+
current target, and nothing here runs sudo or prompts a human. Inputs are
|
|
5
|
+
explicit config objects or caller-selected description files. That is what
|
|
6
|
+
lets these run under Celery, under MCP, in a test, or from a plugin, and it is
|
|
7
|
+
what keeps one lab bench's IP addresses out of the library.
|
|
8
|
+
|
|
9
|
+
Importing this package is deliberately cheap: scapy costs hundreds of
|
|
10
|
+
milliseconds and reads host network configuration at import time, so every
|
|
11
|
+
scapy import lives inside the module that needs it rather than here.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
__version__ = "0.0.9"
|
|
17
|
+
|
|
18
|
+
__all__ = ["NegativeResponse", "NotConfigured", "ProtocolError"]
|
|
19
|
+
|
|
20
|
+
from iotsploit_protocols.errors import NegativeResponse, NotConfigured, ProtocolError
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""AUTOSAR communication-description readers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from iotsploit_protocols.autosar.arxml import (
|
|
6
|
+
ArxmlImportError,
|
|
7
|
+
ArxmlImportResult,
|
|
8
|
+
dump_target,
|
|
9
|
+
import_arxml,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = ["ArxmlImportError", "ArxmlImportResult", "dump_target", "import_arxml"]
|