testprotocols 0.1.0__py3-none-any.whl

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.
Files changed (119) hide show
  1. testprotocols/__init__.py +217 -0
  2. testprotocols/aftr_gateway.py +22 -0
  3. testprotocols/appliance_nat.py +52 -0
  4. testprotocols/appliance_uplinks.py +32 -0
  5. testprotocols/appliance_vlans.py +50 -0
  6. testprotocols/arp_client.py +26 -0
  7. testprotocols/bgp.py +55 -0
  8. testprotocols/conntrack.py +147 -0
  9. testprotocols/content_filtering.py +47 -0
  10. testprotocols/device_lifecycle.py +49 -0
  11. testprotocols/device_management.py +50 -0
  12. testprotocols/devices/__init__.py +46 -0
  13. testprotocols/devices/base.py +40 -0
  14. testprotocols/devices/client.py +133 -0
  15. testprotocols/devices/cpe.py +66 -0
  16. testprotocols/devices/infra.py +62 -0
  17. testprotocols/devices/sdwan.py +97 -0
  18. testprotocols/devices/switch.py +115 -0
  19. testprotocols/devices/traffic.py +53 -0
  20. testprotocols/devices/voice.py +69 -0
  21. testprotocols/devices/wan.py +60 -0
  22. testprotocols/dhcp_client.py +30 -0
  23. testprotocols/dhcp_server.py +23 -0
  24. testprotocols/discovery.py +20 -0
  25. testprotocols/dns_client.py +23 -0
  26. testprotocols/file_transfer.py +22 -0
  27. testprotocols/firewall.py +121 -0
  28. testprotocols/firewall_zones.py +133 -0
  29. testprotocols/first_hop_security.py +52 -0
  30. testprotocols/gateway_redundancy.py +29 -0
  31. testprotocols/http_client.py +36 -0
  32. testprotocols/http_server.py +22 -0
  33. testprotocols/hw_console.py +48 -0
  34. testprotocols/infra_controller.py +28 -0
  35. testprotocols/interface_dhcp.py +30 -0
  36. testprotocols/ip_interface.py +62 -0
  37. testprotocols/ip_routing.py +57 -0
  38. testprotocols/iperf_client.py +47 -0
  39. testprotocols/iperf_generator.py +42 -0
  40. testprotocols/iperf_server.py +41 -0
  41. testprotocols/l3_firewall.py +74 -0
  42. testprotocols/l7_firewall.py +32 -0
  43. testprotocols/link_aggregation.py +24 -0
  44. testprotocols/mac_table.py +20 -0
  45. testprotocols/models/__init__.py +304 -0
  46. testprotocols/models/dhcp.py +28 -0
  47. testprotocols/models/firewall.py +197 -0
  48. testprotocols/models/impairment.py +18 -0
  49. testprotocols/models/l2_common.py +53 -0
  50. testprotocols/models/multicast.py +22 -0
  51. testprotocols/models/networking.py +50 -0
  52. testprotocols/models/packets.py +21 -0
  53. testprotocols/models/qoe.py +31 -0
  54. testprotocols/models/radius.py +63 -0
  55. testprotocols/models/sdwan_appliance.py +637 -0
  56. testprotocols/models/switch.py +297 -0
  57. testprotocols/models/switch_routing.py +122 -0
  58. testprotocols/models/tr069.py +35 -0
  59. testprotocols/models/traffic.py +29 -0
  60. testprotocols/models/wan_edge.py +116 -0
  61. testprotocols/models/wifi.py +183 -0
  62. testprotocols/multicast_client.py +20 -0
  63. testprotocols/nat.py +87 -0
  64. testprotocols/netem_controller.py +42 -0
  65. testprotocols/network_endpoint.py +32 -0
  66. testprotocols/network_probe.py +27 -0
  67. testprotocols/nmap_scanner.py +27 -0
  68. testprotocols/ntp_client.py +26 -0
  69. testprotocols/ntp_config.py +25 -0
  70. testprotocols/ospf.py +24 -0
  71. testprotocols/packet_filter.py +144 -0
  72. testprotocols/pcap_capture.py +39 -0
  73. testprotocols/pdu_controller.py +26 -0
  74. testprotocols/port_poe.py +25 -0
  75. testprotocols/port_security.py +25 -0
  76. testprotocols/port_status.py +23 -0
  77. testprotocols/py.typed +0 -0
  78. testprotocols/qoe_browser.py +62 -0
  79. testprotocols/radius_client.py +78 -0
  80. testprotocols/radius_server.py +130 -0
  81. testprotocols/routed_interfaces.py +29 -0
  82. testprotocols/router.py +53 -0
  83. testprotocols/routing_read.py +22 -0
  84. testprotocols/sdwan_policy_manager.py +64 -0
  85. testprotocols/sip_phone.py +230 -0
  86. testprotocols/sip_server.py +205 -0
  87. testprotocols/site_to_site_vpn.py +61 -0
  88. testprotocols/snmp_client.py +17 -0
  89. testprotocols/spanning_tree.py +37 -0
  90. testprotocols/static_routes.py +47 -0
  91. testprotocols/storm_control.py +24 -0
  92. testprotocols/streaming_server.py +32 -0
  93. testprotocols/switch_acl.py +29 -0
  94. testprotocols/switch_ports.py +28 -0
  95. testprotocols/switch_qos.py +33 -0
  96. testprotocols/switch_vlans.py +34 -0
  97. testprotocols/syslog_config.py +31 -0
  98. testprotocols/tftp_server.py +22 -0
  99. testprotocols/threat_prevention.py +60 -0
  100. testprotocols/tr069_client.py +47 -0
  101. testprotocols/tr069_server.py +151 -0
  102. testprotocols/traffic_shaping.py +54 -0
  103. testprotocols/upnp_client.py +37 -0
  104. testprotocols/vlan_client.py +22 -0
  105. testprotocols/wan_link_admin.py +34 -0
  106. testprotocols/wifi_bss.py +197 -0
  107. testprotocols/wifi_client.py +72 -0
  108. testprotocols/wifi_mesh.py +259 -0
  109. testprotocols/wifi_onboarding.py +105 -0
  110. testprotocols/wifi_radio.py +153 -0
  111. testprotocols/wifi_rf.py +78 -0
  112. testprotocols/wifi_stations.py +59 -0
  113. testprotocols/wifi_transitions.py +112 -0
  114. testprotocols-0.1.0.dist-info/METADATA +29 -0
  115. testprotocols-0.1.0.dist-info/RECORD +119 -0
  116. testprotocols-0.1.0.dist-info/WHEEL +5 -0
  117. testprotocols-0.1.0.dist-info/licenses/LICENSE +201 -0
  118. testprotocols-0.1.0.dist-info/licenses/NOTICE +11 -0
  119. testprotocols-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,304 @@
1
+ """Shared data models for palco-templates."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from testprotocols.models.dhcp import DHCPTraceData, DHCPV6TraceData
6
+ from testprotocols.models.firewall import (
7
+ Connection,
8
+ ConntrackStats,
9
+ FirewallRule,
10
+ NatRule,
11
+ PortMapping,
12
+ Zone,
13
+ ZonePolicy,
14
+ )
15
+ from testprotocols.models.impairment import ImpairmentProfile
16
+ from testprotocols.models.multicast import (
17
+ McastGroup,
18
+ McastSource,
19
+ MulticastGroupRecord,
20
+ MulticastGroupRecordType,
21
+ )
22
+ from testprotocols.models.networking import HTTPResult, ICMPPacketData, IPAddresses
23
+ from testprotocols.models.packets import RIPv2PacketData
24
+ from testprotocols.models.qoe import MeasurementSpec, QoEResult
25
+ from testprotocols.models.sdwan_appliance import (
26
+ ApplicationCategory,
27
+ BgpConfig,
28
+ BgpNeighbor,
29
+ BgpPeerStatus,
30
+ BgpSessionState,
31
+ ContentCategory,
32
+ DhcpLease,
33
+ DhcpMode,
34
+ DhcpOption,
35
+ DhcpOptionType,
36
+ DhcpReservation,
37
+ FlowMatch,
38
+ IntrusionConfig,
39
+ IntrusionMode,
40
+ IntrusionSensitivity,
41
+ L3Rule,
42
+ L7MatchType,
43
+ L7Rule,
44
+ MalwareConfig,
45
+ MalwareMode,
46
+ NatInboundAllow,
47
+ OneToManyNatRule,
48
+ OneToOneNatRule,
49
+ PortForwardRule,
50
+ RuleAction,
51
+ RuleProtocol,
52
+ SecurityAction,
53
+ SecurityEvent,
54
+ ShapingPriority,
55
+ ShapingRule,
56
+ SiteToSiteVpnConfig,
57
+ StaticRoute,
58
+ SteeringScope,
59
+ SyslogRole,
60
+ SyslogServer,
61
+ ThreatCategory,
62
+ UplinkSelectionRule,
63
+ UplinkState,
64
+ UplinkStatus,
65
+ VlanConfig,
66
+ VpnHub,
67
+ VpnPeerState,
68
+ VpnPeerStatus,
69
+ VpnRole,
70
+ VpnSubnet,
71
+ )
72
+ from testprotocols.models.l2_common import (
73
+ MacTableEntry,
74
+ StpGuard,
75
+ StpMode,
76
+ StpPortState,
77
+ )
78
+ from testprotocols.models.switch import (
79
+ AccessPolicy,
80
+ AccessPolicyType,
81
+ AclDirection,
82
+ AggregationMode,
83
+ BindingSource,
84
+ DiscoveryProtocol,
85
+ Duplex,
86
+ FhsBinding,
87
+ FhsScope,
88
+ FhsTrustState,
89
+ LinkAggregationGroup,
90
+ LinkState,
91
+ LldpNeighbor,
92
+ NtpServer,
93
+ PoePortStatus,
94
+ PoePriority,
95
+ PoeStatus,
96
+ PortAdminState,
97
+ PortMode,
98
+ PortStatusEntry,
99
+ QosRule,
100
+ QosTrustMode,
101
+ StormControlConfig,
102
+ StormControlType,
103
+ StpPortConfig,
104
+ SwitchAclRule,
105
+ SwitchPort,
106
+ VlanDef,
107
+ )
108
+ from testprotocols.models.radius import (
109
+ RadiusAccountingRecord,
110
+ RadiusServerConfig,
111
+ RadiusSession,
112
+ RadiusUser,
113
+ )
114
+ from testprotocols.models.tr069 import CpeConnectionStatus
115
+ from testprotocols.models.traffic import TrafficResult, TrafficSpec
116
+ from testprotocols.models.switch_routing import (
117
+ InterfaceDhcpConfig,
118
+ InterfaceMode,
119
+ OspfConfig,
120
+ OspfInterfaceSettings,
121
+ OspfVersion,
122
+ RedundancyGroup,
123
+ RedundancyRole,
124
+ RoutedInterface,
125
+ )
126
+ from testprotocols.models.wan_edge import (
127
+ AppFlow,
128
+ LinkHealthReport,
129
+ LinkStatus,
130
+ PathMetrics,
131
+ RouteEntry,
132
+ RouteOrigin,
133
+ SLAPolicy,
134
+ TrafficShapingRule,
135
+ VPNPeerStatus,
136
+ )
137
+ from testprotocols.models.wifi import (
138
+ WifiAcl,
139
+ WifiBssConfig,
140
+ WifiCaptiveConfig,
141
+ WifiChannelUtilization,
142
+ WifiDfsState,
143
+ WifiMeshLink,
144
+ WifiMeshNode,
145
+ WifiMeshStatus,
146
+ WifiMeshTopology,
147
+ WifiNeighbor,
148
+ WifiRadioStats,
149
+ WifiStation,
150
+ WifiTransitionConfig,
151
+ )
152
+
153
+ __all__ = [
154
+ # l2_common
155
+ "MacTableEntry",
156
+ "StpGuard",
157
+ "StpMode",
158
+ "StpPortState",
159
+ # switch
160
+ "AccessPolicy",
161
+ "AccessPolicyType",
162
+ "AclDirection",
163
+ "AggregationMode",
164
+ "BindingSource",
165
+ "DiscoveryProtocol",
166
+ "Duplex",
167
+ "FhsBinding",
168
+ "FhsScope",
169
+ "FhsTrustState",
170
+ "LinkAggregationGroup",
171
+ "LinkState",
172
+ "LldpNeighbor",
173
+ "NtpServer",
174
+ "PoePortStatus",
175
+ "PoePriority",
176
+ "PoeStatus",
177
+ "PortAdminState",
178
+ "PortMode",
179
+ "PortStatusEntry",
180
+ "QosRule",
181
+ "QosTrustMode",
182
+ "StormControlConfig",
183
+ "StormControlType",
184
+ "StpPortConfig",
185
+ "SwitchAclRule",
186
+ "SwitchPort",
187
+ "VlanDef",
188
+ # switch_routing
189
+ "InterfaceDhcpConfig",
190
+ "InterfaceMode",
191
+ "OspfConfig",
192
+ "OspfInterfaceSettings",
193
+ "OspfVersion",
194
+ "RedundancyGroup",
195
+ "RedundancyRole",
196
+ "RoutedInterface",
197
+ # wan_edge
198
+ "AppFlow",
199
+ # firewall
200
+ "Connection",
201
+ "ConntrackStats",
202
+ # tr069
203
+ "CpeConnectionStatus",
204
+ # dhcp
205
+ "DHCPTraceData",
206
+ "DHCPV6TraceData",
207
+ "FirewallRule",
208
+ # networking
209
+ "HTTPResult",
210
+ "ICMPPacketData",
211
+ "IPAddresses",
212
+ # impairment
213
+ "ImpairmentProfile",
214
+ # sdwan_appliance
215
+ "ApplicationCategory",
216
+ "BgpConfig",
217
+ "BgpNeighbor",
218
+ "BgpPeerStatus",
219
+ "BgpSessionState",
220
+ "ContentCategory",
221
+ "DhcpLease",
222
+ "DhcpMode",
223
+ "DhcpOption",
224
+ "DhcpOptionType",
225
+ "DhcpReservation",
226
+ "FlowMatch",
227
+ "IntrusionConfig",
228
+ "IntrusionMode",
229
+ "IntrusionSensitivity",
230
+ "L3Rule",
231
+ "L7MatchType",
232
+ "L7Rule",
233
+ "MalwareConfig",
234
+ "MalwareMode",
235
+ "NatInboundAllow",
236
+ "OneToManyNatRule",
237
+ "OneToOneNatRule",
238
+ "PortForwardRule",
239
+ "RuleAction",
240
+ "RuleProtocol",
241
+ "SecurityAction",
242
+ "SecurityEvent",
243
+ "ShapingPriority",
244
+ "ShapingRule",
245
+ "SiteToSiteVpnConfig",
246
+ "StaticRoute",
247
+ "SteeringScope",
248
+ "SyslogRole",
249
+ "SyslogServer",
250
+ "ThreatCategory",
251
+ "UplinkSelectionRule",
252
+ "UplinkState",
253
+ "UplinkStatus",
254
+ "VlanConfig",
255
+ "VpnHub",
256
+ "VpnPeerState",
257
+ "VpnPeerStatus",
258
+ "VpnRole",
259
+ "VpnSubnet",
260
+ "LinkHealthReport",
261
+ "LinkStatus",
262
+ # multicast
263
+ "McastGroup",
264
+ "McastSource",
265
+ # qoe
266
+ "MeasurementSpec",
267
+ "MulticastGroupRecord",
268
+ "MulticastGroupRecordType",
269
+ "NatRule",
270
+ "PathMetrics",
271
+ "PortMapping",
272
+ "QoEResult",
273
+ # packets
274
+ "RIPv2PacketData",
275
+ # radius
276
+ "RadiusAccountingRecord",
277
+ "RadiusServerConfig",
278
+ "RadiusSession",
279
+ "RadiusUser",
280
+ "RouteEntry",
281
+ "RouteOrigin",
282
+ "SLAPolicy",
283
+ # traffic
284
+ "TrafficResult",
285
+ "TrafficShapingRule",
286
+ "TrafficSpec",
287
+ "VPNPeerStatus",
288
+ # wifi
289
+ "WifiAcl",
290
+ "WifiBssConfig",
291
+ "WifiCaptiveConfig",
292
+ "WifiChannelUtilization",
293
+ "WifiDfsState",
294
+ "WifiMeshLink",
295
+ "WifiMeshNode",
296
+ "WifiMeshStatus",
297
+ "WifiMeshTopology",
298
+ "WifiNeighbor",
299
+ "WifiRadioStats",
300
+ "WifiStation",
301
+ "WifiTransitionConfig",
302
+ "Zone",
303
+ "ZonePolicy",
304
+ ]
@@ -0,0 +1,28 @@
1
+ """DHCP and DHCPv6 packet trace data models."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+ from testprotocols.models.networking import IPAddresses
9
+
10
+
11
+ @dataclass
12
+ class DHCPTraceData:
13
+ """Holds a captured DHCPv4 packet with source/destination addresses and message type."""
14
+
15
+ source: IPAddresses
16
+ destination: IPAddresses
17
+ dhcp_packet: dict[str, Any]
18
+ dhcp_message_type: int
19
+
20
+
21
+ @dataclass
22
+ class DHCPV6TraceData:
23
+ """Holds a captured DHCPv6 packet with source/destination addresses and message type."""
24
+
25
+ source: IPAddresses
26
+ destination: IPAddresses
27
+ dhcpv6_packet: dict[str, Any]
28
+ dhcpv6_message_type: int
@@ -0,0 +1,197 @@
1
+ """Firewall-domain data models.
2
+
3
+ Shared across the ``packet_filter``, ``firewall``, ``nat``,
4
+ ``conntrack``, ``firewall_zones``, and ``sdwan_policy_manager`` templates.
5
+ Transport-agnostic: drivers translate these structures into iptables /
6
+ nftables / pf / TR-069 / vendor CLI as appropriate.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass, field
12
+
13
+
14
+ @dataclass
15
+ class FirewallRule:
16
+ """Holds a stateless or stateful packet-filter rule with match criteria and action.
17
+
18
+ Used by the ``packet_filter`` and ``firewall`` templates (per-chain
19
+ rule lists). The IPv4 / IPv6 split is not a contract dimension
20
+ — each rule's address family is inferred from its CIDR fields.
21
+
22
+ *action* is one of ``"allow"``, ``"deny"``, ``"reject"``, ``"log"``.
23
+ *protocol* is one of ``"tcp"``, ``"udp"``, ``"icmp"``, ``"any"``.
24
+ *dst_port* is a port number, a range like ``"1024-65535"``, or ``"any"``.
25
+ *application* / *application_category* are L7 classifiers used by
26
+ SD-WAN policy; they are ignored by simple packet-filter drivers.
27
+ """
28
+
29
+ name: str
30
+ action: str
31
+ protocol: str
32
+ src_cidr: str
33
+ dst_cidr: str
34
+ dst_port: str
35
+ application: str | None = None
36
+ application_category: str | None = None
37
+ log: bool = True
38
+
39
+
40
+ @dataclass
41
+ class NatRule:
42
+ """A NAT translation rule.
43
+
44
+ Three modes are supported via the *mode* discriminator:
45
+
46
+ - ``"snat"`` — source-NAT (rewrite source on egress). Requires
47
+ *translated_src* (or empty string to fall back to the egress
48
+ interface address). *translated_dst* and *translated_port* must
49
+ be empty.
50
+ - ``"dnat"`` — destination-NAT / port-forward primitive (rewrite
51
+ destination on ingress). Requires *translated_dst*; *translated_port*
52
+ is optional. *translated_src* must be empty.
53
+ - ``"1to1"`` — bidirectional one-to-one NAT (static mapping between
54
+ an outside and inside address). Requires *translated_dst* (the
55
+ inside address). Port fields must be empty.
56
+
57
+ Match criteria default to ``""`` meaning "any". *interface* is the
58
+ egress interface for snat / 1to1, the ingress interface for dnat;
59
+ drivers may also accept a logical name resolved via ``IpInterface``.
60
+ """
61
+
62
+ name: str
63
+ mode: str
64
+ interface: str
65
+ protocol: str = "any"
66
+ src_cidr: str = ""
67
+ dst_cidr: str = ""
68
+ dst_port: str = ""
69
+ translated_src: str = ""
70
+ translated_dst: str = ""
71
+ translated_port: str = ""
72
+ enabled: bool = True
73
+
74
+
75
+ @dataclass
76
+ class PortMapping:
77
+ """A named external-port → internal-host:port mapping.
78
+
79
+ Higher-level than ``NatRule``: drivers may lower a ``PortMapping`` to
80
+ a DNAT primitive, a TR-069 ``Device.NAT.PortMapping`` object, a
81
+ UPnP-IGD / PCP entry, or a vendor port-forward CLI — tests never
82
+ need to know which.
83
+
84
+ *protocol* is one of ``"tcp"``, ``"udp"``, ``"tcp-udp"``.
85
+ *external_interface* of ``None`` means "all external interfaces".
86
+ *src_cidr* may restrict the mapping to a specific source range
87
+ (firewall hardening); the default ``"0.0.0.0/0"`` accepts any source.
88
+ """
89
+
90
+ name: str
91
+ external_port: int
92
+ protocol: str
93
+ internal_host: str
94
+ internal_port: int
95
+ external_interface: str | None = None
96
+ src_cidr: str = "0.0.0.0/0"
97
+ description: str = ""
98
+ enabled: bool = True
99
+
100
+
101
+ @dataclass
102
+ class Connection:
103
+ """A single tracked connection / flow as observed by the conntrack template.
104
+
105
+ Direction is original → reply. *bytes_orig* / *packets_orig* count
106
+ the original direction; *bytes_reply* / *packets_reply* count the
107
+ reverse path.
108
+
109
+ *state* is protocol-specific:
110
+
111
+ - TCP: ``"SYN_SENT"``, ``"SYN_RECV"``, ``"ESTABLISHED"``,
112
+ ``"FIN_WAIT"``, ``"CLOSE_WAIT"``, ``"LAST_ACK"``, ``"TIME_WAIT"``,
113
+ ``"CLOSE"``, ``"LISTEN"``.
114
+ - UDP / ICMP / other: ``"UNREPLIED"``, ``"ASSURED"``, or
115
+ driver-specific values.
116
+
117
+ *translated_src* / *translated_dst* are populated (non-None) when NAT
118
+ is altering this flow. *src_port* / *dst_port* are ``None`` for ICMP.
119
+ """
120
+
121
+ protocol: str
122
+ src_ip: str
123
+ dst_ip: str
124
+ src_port: int | None
125
+ dst_port: int | None
126
+ state: str
127
+ timeout_seconds: int
128
+ bytes_orig: int
129
+ bytes_reply: int
130
+ packets_orig: int
131
+ packets_reply: int
132
+ translated_src: str | None = None
133
+ translated_dst: str | None = None
134
+ mark: int | None = None
135
+ zone: str | None = None
136
+
137
+
138
+ @dataclass
139
+ class ConntrackStats:
140
+ """Conntrack table-level aggregate counters.
141
+
142
+ *count* and *max* are the only universally available values; the
143
+ remaining fields are populated where the driver can report them.
144
+ ``None`` means "driver does not expose this counter", not zero.
145
+ """
146
+
147
+ count: int
148
+ max: int
149
+ inserted: int | None = None
150
+ deleted: int | None = None
151
+ drops: int | None = None
152
+ early_drops: int | None = None
153
+ invalid: int | None = None
154
+ search_restarts: int | None = None
155
+
156
+
157
+ @dataclass
158
+ class Zone:
159
+ """A named firewall zone — a group of interfaces and / or networks
160
+ sharing default-input / default-forward / default-output policy.
161
+
162
+ Models the OpenWrt-style zone model (also maps to firewalld zones,
163
+ pfSense interface groups, etc.). Empty *interfaces* and *networks*
164
+ lists are valid (zone exists but is not yet bound).
165
+
166
+ *default_input* / *default_forward* / *default_output* are one of
167
+ ``"accept"``, ``"drop"``, ``"reject"`` and govern traffic that
168
+ doesn't match any explicit rule. *masquerade* enables auto-SNAT on
169
+ egress traffic from this zone; *mss_clamping* enables PMTU clamping
170
+ (helpful on PPPoE WAN zones).
171
+ """
172
+
173
+ name: str
174
+ interfaces: list[str] = field(default_factory=list[str])
175
+ networks: list[str] = field(default_factory=list[str])
176
+ default_input: str = "drop"
177
+ default_forward: str = "drop"
178
+ default_output: str = "accept"
179
+ masquerade: bool = False
180
+ mss_clamping: bool = False
181
+
182
+
183
+ @dataclass
184
+ class ZonePolicy:
185
+ """Default forwarding action between two zones.
186
+
187
+ Models the per-zone-pair forwarding link in OpenWrt-style firewalls.
188
+ More specific traffic between the same pair is still controlled by
189
+ ``FirewallRule`` records (in ``packet_filter`` or ``firewall``);
190
+ this is the fall-through.
191
+
192
+ *action* is one of ``"accept"``, ``"drop"``, ``"reject"``.
193
+ """
194
+
195
+ src_zone: str
196
+ dst_zone: str
197
+ action: str
@@ -0,0 +1,18 @@
1
+ """Network impairment profile data model."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+
8
+ @dataclass
9
+ class ImpairmentProfile:
10
+ """Holds parameters describing a network impairment scenario (latency, jitter, loss, etc.)."""
11
+
12
+ latency_ms: int
13
+ jitter_ms: int
14
+ loss_percent: float
15
+ bandwidth_limit_mbps: int | None = None
16
+ reorder_percent: float = 0.0
17
+ corrupt_percent: float = 0.0
18
+ duplicate_percent: float = 0.0
@@ -0,0 +1,53 @@
1
+ """Shared L2 vocabulary for the switch archetypes and the future CPE L2 bridge.
2
+
3
+ STP and FDB concepts are common to a hardware switch (``SpanningTree`` /
4
+ ``MacTable``) and a Linux bridge (the deferred ``L2Bridge``, see GAPS.md). The
5
+ normalized vocabularies live here, in a neutral module, so neither
6
+ ``models/switch.py`` nor a future bridge model depends on the other.
7
+
8
+ Vendor neutrality is part of the contract: members are plain strings (trivial to
9
+ serialize), constructing from a value validates it, and a testbed plugin maps its
10
+ product's terms to/from these neutral values. No vendor identifier appears here.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from enum import StrEnum
17
+
18
+
19
+ class StpMode(StrEnum):
20
+ """IEEE spanning-tree mode (802.1D / 802.1w / 802.1s). Seeded in full."""
21
+
22
+ STP = "stp"
23
+ RSTP = "rstp"
24
+ MSTP = "mstp"
25
+ UNKNOWN = "unknown"
26
+
27
+
28
+ class StpGuard(StrEnum):
29
+ """Per-port spanning-tree guard."""
30
+
31
+ NONE = "none"
32
+ ROOT = "root"
33
+ BPDU = "bpdu"
34
+ LOOP = "loop"
35
+
36
+
37
+ class StpPortState(StrEnum):
38
+ """Observed per-port spanning-tree state."""
39
+
40
+ FORWARDING = "forwarding"
41
+ BLOCKING = "blocking"
42
+ LEARNING = "learning"
43
+ LISTENING = "listening"
44
+ DISABLED = "disabled"
45
+
46
+
47
+ @dataclass
48
+ class MacTableEntry:
49
+ """A single forwarding-database (FDB) entry — normalized."""
50
+
51
+ mac: str
52
+ port: str
53
+ vlan: int
@@ -0,0 +1,22 @@
1
+ """Multicast group record types and type aliases."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+
7
+
8
+ class MulticastGroupRecordType(Enum):
9
+ """IGMPv3 group record type codes as defined in RFC 3376."""
10
+
11
+ MODE_IS_INCLUDE = 1
12
+ MODE_IS_EXCLUDE = 2
13
+ CHANGE_TO_INCLUDE_MODE = 3
14
+ CHANGE_TO_EXCLUDE_MODE = 4
15
+ ALLOW_NEW_SOURCES = 5
16
+ BLOCK_OLD_SOURCES = 6
17
+
18
+
19
+ McastSource = str
20
+ McastGroup = str
21
+ MulticastGroupRecord = list[tuple[list[McastSource], McastGroup, MulticastGroupRecordType]]
22
+ """A list of (sources, group, record_type) tuples representing IGMPv3 group records."""
@@ -0,0 +1,50 @@
1
+ """Networking data models for IP addresses and protocol results."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from ipaddress import IPv4Address, IPv6Address
7
+
8
+
9
+ @dataclass
10
+ class IPAddresses:
11
+ """Holds optional IPv4, IPv6, and link-local IPv6 addresses for a network endpoint."""
12
+
13
+ ipv4: IPv4Address | None
14
+ ipv6: IPv6Address | None
15
+ link_local_ipv6: IPv6Address | None
16
+
17
+
18
+ @dataclass
19
+ class ICMPPacketData:
20
+ """Holds ICMP packet fields including query code and source/destination addresses."""
21
+
22
+ query_code: int
23
+ source: IPAddresses
24
+ destination: IPAddresses
25
+
26
+
27
+ class HTTPResult:
28
+ """Parses and holds an HTTP response string, exposing the status code and body."""
29
+
30
+ def __init__(self, response: str) -> None:
31
+ self.raw = response
32
+ self.code, self.beautified_text, _ = self._parse_response(response)
33
+
34
+ @staticmethod
35
+ def _parse_response(response: str) -> tuple[str, str, str]:
36
+ lines = response.split("\r\n", 1) if "\r\n" in response else response.split("\n", 1)
37
+ status_line = lines[0] if lines else ""
38
+ parts = status_line.split(" ", 2)
39
+ code = parts[1] if len(parts) > 1 else ""
40
+ reason = parts[2] if len(parts) > 2 else ""
41
+ body = lines[1] if len(lines) > 1 else ""
42
+ if "\r\n\r\n" in body:
43
+ body = body.split("\r\n\r\n", 1)[1]
44
+ elif "\n\n" in body:
45
+ body = body.split("\n\n", 1)[1]
46
+ elif body.startswith("\r\n"):
47
+ body = body[2:]
48
+ elif body.startswith("\n"):
49
+ body = body[1:]
50
+ return code, body, reason
@@ -0,0 +1,21 @@
1
+ """Protocol-specific packet data models."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime
7
+ from ipaddress import IPv4Address, IPv4Interface, IPv6Interface
8
+
9
+
10
+ @dataclass
11
+ class RIPv2PacketData:
12
+ """Holds fields extracted from a RIPv2 packet.
13
+
14
+ Includes source, destination, and route entries.
15
+ """
16
+
17
+ source: IPv4Address
18
+ destination: IPv4Address
19
+ ip_address: list[IPv4Address]
20
+ subnet: list[IPv4Interface | IPv6Interface]
21
+ frame_time: datetime | None = None