codecraftai-networking 1.2.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.
- ccai/networking/__init__.py +12 -0
- ccai/networking/arp.py +80 -0
- ccai/networking/broadcast.py +38 -0
- ccai/networking/constants.py +169 -0
- ccai/networking/interfaces.py +409 -0
- ccai/networking/multicast.py +199 -0
- ccai/networking/py.typed +0 -0
- ccai/networking/resolution.py +393 -0
- ccai/networking/trafficcapturecontext.py +126 -0
- ccai/networking/unicast.py +102 -0
- codecraftai_networking-1.2.0.dist-info/METADATA +89 -0
- codecraftai_networking-1.2.0.dist-info/RECORD +14 -0
- codecraftai_networking-1.2.0.dist-info/WHEEL +4 -0
- codecraftai_networking-1.2.0.dist-info/licenses/LICENSE.md +204 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: networking
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Package that contains modules for interoperating with networks and network APIs.
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Code Craft AI LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
|
ccai/networking/arp.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: arp
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Module that contains helper functions for working with the ARP table.
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Code Craft AI LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
from typing import List, Dict
|
|
15
|
+
|
|
16
|
+
import platform
|
|
17
|
+
|
|
18
|
+
def get_arp_table() -> List[Dict[str, str]]:
|
|
19
|
+
"""
|
|
20
|
+
Get the ARP table from the system.
|
|
21
|
+
|
|
22
|
+
:returns: A list of dictionaries containing ARP table entries.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import subprocess
|
|
26
|
+
import re
|
|
27
|
+
|
|
28
|
+
arp_command = None
|
|
29
|
+
arp_item_match = None
|
|
30
|
+
|
|
31
|
+
this_platform = platform.system()
|
|
32
|
+
if this_platform == 'Windows':
|
|
33
|
+
# Windows uses a different command for ARP
|
|
34
|
+
arp_command = ['arp', '-a']
|
|
35
|
+
arp_item_match = re.compile(
|
|
36
|
+
r"\s*([-.0-9]+)\s+([0-9A-Fa-f:-]{17})\s+(\w+)",
|
|
37
|
+
re.MULTILINE | re.IGNORECASE
|
|
38
|
+
)
|
|
39
|
+
else:
|
|
40
|
+
arp_command = ['ip', 'neigh']
|
|
41
|
+
arp_item_match = re.compile(
|
|
42
|
+
r'([\da-fA-F.:]+)\s+dev\s+([\w-]+)\s+lladdr\s+([\da-fA-F:]+)\s+.*',
|
|
43
|
+
re.MULTILINE
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Run the arp command and capture the output
|
|
47
|
+
try:
|
|
48
|
+
output = subprocess.check_output(arp_command, universal_newlines=True)
|
|
49
|
+
except subprocess.CalledProcessError as e:
|
|
50
|
+
print(f"Error running arp command: {e}")
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
# Parse the output using regex
|
|
54
|
+
arp_entries = []
|
|
55
|
+
for line in output.splitlines():
|
|
56
|
+
match = arp_item_match.match(line)
|
|
57
|
+
if match:
|
|
58
|
+
if this_platform == 'Windows':
|
|
59
|
+
ip, mac_addr, arp_type = match.groups()
|
|
60
|
+
hw_value = arp_type
|
|
61
|
+
else:
|
|
62
|
+
ip, interface, mac_addr = match.groups()
|
|
63
|
+
hw_value = interface
|
|
64
|
+
|
|
65
|
+
arp_entries.append({
|
|
66
|
+
'IPAddress': ip,
|
|
67
|
+
'HWType': hw_value,
|
|
68
|
+
'MACAddress': mac_addr
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return arp_entries
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
# Example usage
|
|
76
|
+
arp_table = get_arp_table()
|
|
77
|
+
for entry in arp_table:
|
|
78
|
+
print(f"IP Address: {entry['IPAddress']}, HW Type: {entry['HWType']}, MAC Address: {entry['MACAddress']}")
|
|
79
|
+
|
|
80
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: broadcast
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Module that contains broadcast helper functions.
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Code Craft AI LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def broadcast_wake_on_lan_magic_message(broadcast_addr: str, mac_addr: str):
|
|
15
|
+
"""
|
|
16
|
+
Broadcasts a Wake-on-LAN magic message.
|
|
17
|
+
|
|
18
|
+
:param broadcast_addr: The broadcast address to send the magic packet to.
|
|
19
|
+
:param mac_addr: The MAC address of the device to wake.
|
|
20
|
+
|
|
21
|
+
:returns: ``None``
|
|
22
|
+
"""
|
|
23
|
+
import socket
|
|
24
|
+
|
|
25
|
+
mac_bytes = mac_addr.replace(":", "").replace("-", "")
|
|
26
|
+
if len(mac_bytes) != 12:
|
|
27
|
+
raise ValueError(f"Invalid MAC address: {mac_addr}")
|
|
28
|
+
|
|
29
|
+
magic_packet = bytes.fromhex("FF" * 6 + mac_bytes * 16)
|
|
30
|
+
|
|
31
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
32
|
+
try:
|
|
33
|
+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
34
|
+
sock.sendto(magic_packet, (broadcast_addr, 9))
|
|
35
|
+
finally:
|
|
36
|
+
sock.close()
|
|
37
|
+
|
|
38
|
+
return
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: constants
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Module that contains constants associated with network activities from the test framework.
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Code Craft AI LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import re
|
|
15
|
+
import socket
|
|
16
|
+
|
|
17
|
+
HTTP1_1_LINESEP = b"\r\n"
|
|
18
|
+
HTTP1_1_END_OF_HEADER = b"\r\n\r\n"
|
|
19
|
+
HTTP1_1_END_OF_MESSAGE = b"\r\n\r\n"
|
|
20
|
+
|
|
21
|
+
if hasattr(socket, "IPPROTO_IPV6"):
|
|
22
|
+
IPPROTO_IPV6 = socket.IPPROTO_IPV6
|
|
23
|
+
else:
|
|
24
|
+
# Sigh: https://bugs.python.org/issue29515
|
|
25
|
+
IPPROTO_IPV6 = 41
|
|
26
|
+
|
|
27
|
+
MDNS_GROUP_ADDR = '224.0.0.251'
|
|
28
|
+
MDNS_GROUP_ADDR6 = 'ff02::fb'
|
|
29
|
+
|
|
30
|
+
MDNS_PORT = 5353
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
UPNP_GROUP_ADDR = '239.255.255.250'
|
|
34
|
+
|
|
35
|
+
UPNP_GROUP_LOCAL_ADDR6 = 'FF02::1'
|
|
36
|
+
UPNP_GROUP_SITE_ADDR6 = 'FF05::1'
|
|
37
|
+
UPNP_GROUP_ORG_ADDR6 = 'FF08::1'
|
|
38
|
+
UPNP_GROUP_GLOBAL_ADDR6 = 'FF0E::1'
|
|
39
|
+
|
|
40
|
+
UPNP_PORT = 1900
|
|
41
|
+
|
|
42
|
+
UPNP_DEFAULT_SEARCH_WINDOW_LENGTH = 20
|
|
43
|
+
|
|
44
|
+
CHARSET_IPV6_ADDR = 'ABCDEFabcdef0123456789:'
|
|
45
|
+
|
|
46
|
+
REGEX_IPV4_COMPONENTS = re.compile(r"^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$")
|
|
47
|
+
REGEX_IPV6_COMPONENTS = re.compile(r"^([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+)$")
|
|
48
|
+
|
|
49
|
+
if hasattr(socket, "SO_RECV_ANYIF"):
|
|
50
|
+
SO_RECV_ANYIF = socket.SO_RECV_ANYIF
|
|
51
|
+
else:
|
|
52
|
+
# https://opensource.apple.com/source/xnu/xnu-4570.41.2/bsd/sys/socket.h
|
|
53
|
+
SO_RECV_ANYIF = 0x1104
|
|
54
|
+
|
|
55
|
+
class RegisteredMulticastAddresses:
|
|
56
|
+
"""
|
|
57
|
+
https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
BASE = "224.0.0.0" # RFC 1112
|
|
61
|
+
ALL_SYSTEMS_ON_SUBNET = "224.0.0.1" # RFC 1112
|
|
62
|
+
ALL_ROUTERS_ON_SUBNET = "224.0.0.2"
|
|
63
|
+
UNASSIGNED_A = "224.0.0.3"
|
|
64
|
+
DVMRP_ROUTERS = "224.0.0.4" # RFC 1075
|
|
65
|
+
OSPFIGP_ALL_ROUTERS = "224.0.0.5" # RFC 2328
|
|
66
|
+
OSPFIGP_DESIGNATED_ROUTERS = "224.0.0.6" # RFC 2328
|
|
67
|
+
ST_ROUTERS = "224.0.0.7" # RFC 1190
|
|
68
|
+
ST_HOSTS = "224.0.0.8" # RFC 1190
|
|
69
|
+
RIP2_ROUTERS = "224.0.0.9" # RFC 1723
|
|
70
|
+
EIGRP_ROUTERS = "224.0.0.10" # RFC 7868
|
|
71
|
+
MOBILE_AGENTS = "224.0.0.11"
|
|
72
|
+
DHCP_SERVER_OR_AGENT = "224.0.0.12"
|
|
73
|
+
ALL_PIM_ROUTERS = "224.0.0.13"
|
|
74
|
+
RSVP_ENCAPSULATION = "224.0.0.14"
|
|
75
|
+
ALL_CBT_ROUTERS = "224.0.0.15"
|
|
76
|
+
DESIGNATED_SBM = "224.0.0.16"
|
|
77
|
+
ALL_SBMS = "224.0.0.17"
|
|
78
|
+
VRRP = "224.0.0.18"
|
|
79
|
+
IPAll_L1_ISs = "224.0.0.19"
|
|
80
|
+
IPAll_L2_ISs = "224.0.0.20"
|
|
81
|
+
IPAll_INTERMEDIATE_SYSTEMS = "224.0.0.21"
|
|
82
|
+
IGMP = "224.0.0.22"
|
|
83
|
+
GLOBECAST_ID = "224.0.0.23"
|
|
84
|
+
OSPFIGP_TE = "224.0.0.24"
|
|
85
|
+
ROUTER_TO_SWITCH = "224.0.0.25"
|
|
86
|
+
UNASSIGNED_B = "224.0.0.26"
|
|
87
|
+
AL_MPP_HELLO = "224.0.0.27"
|
|
88
|
+
ETC_CONTROL = "224.0.0.28"
|
|
89
|
+
GE_FANUC = "224.0.0.29"
|
|
90
|
+
INDIGO_VHDP = "224.0.0.30"
|
|
91
|
+
SHIN_BROAD_BAND = "224.0.0.31"
|
|
92
|
+
DIGISTAR = "224.0.0.32"
|
|
93
|
+
FF_SYSTEM_MANAGEMENT = "224.0.0.33"
|
|
94
|
+
PT2_DISCOVER = "224.0.0.34"
|
|
95
|
+
DXCLUSTER = "224.0.0.35"
|
|
96
|
+
DTCP_ANNOUNCEMENT = "224.0.0.36"
|
|
97
|
+
ZERO_CONF_ADDR = [
|
|
98
|
+
"224.0.0.36", "224.0.0.37", "224.0.0.38", "224.0.0.39", "224.0.0.40",
|
|
99
|
+
"224.0.0.41", "224.0.0.42", "224.0.0.43", "224.0.0.44", "224.0.0.45",
|
|
100
|
+
"224.0.0.46", "224.0.0.47", "224.0.0.48", "224.0.0.49", "224.0.0.50",
|
|
101
|
+
"224.0.0.51", "224.0.0.52", "224.0.0.53", "224.0.0.54", "224.0.0.55",
|
|
102
|
+
"224.0.0.56", "224.0.0.57", "224.0.0.58", "224.0.0.59", "224.0.0.60",
|
|
103
|
+
"224.0.0.61", "224.0.0.62", "224.0.0.63", "224.0.0.64", "224.0.0.65",
|
|
104
|
+
"224.0.0.66", "224.0.0.67", "224.0.0.68"
|
|
105
|
+
]
|
|
106
|
+
UNASSIGNED_C = [
|
|
107
|
+
"224.0.0.69", "224.0.0.70", "224.0.0.71", "224.0.0.72", "224.0.0.73",
|
|
108
|
+
"224.0.0.74", "224.0.0.75", "224.0.0.76", "224.0.0.77", "224.0.0.78",
|
|
109
|
+
"224.0.0.79", "224.0.0.80", "224.0.0.81", "224.0.0.82", "224.0.0.83",
|
|
110
|
+
"224.0.0.84", "224.0.0.85", "224.0.0.86", "224.0.0.87", "224.0.0.88",
|
|
111
|
+
"224.0.0.89", "224.0.0.90", "224.0.0.91", "224.0.0.92", "224.0.0.93",
|
|
112
|
+
"224.0.0.94", "224.0.0.95", "224.0.0.96", "224.0.0.97", "224.0.0.98",
|
|
113
|
+
"224.0.0.99", "224.0.0.100"
|
|
114
|
+
]
|
|
115
|
+
CISCO_NHAP = "224.0.0.101"
|
|
116
|
+
HSRP = "224.0.0.102"
|
|
117
|
+
MDAP = "224.0.0.103"
|
|
118
|
+
NOKIA_MC_CH = "224.0.0.104"
|
|
119
|
+
FF_LR_ADDRESS = "224.0.0.105"
|
|
120
|
+
ALL_SNOOPERS = "224.0.0.106"
|
|
121
|
+
PTP_PDELAY = "224.0.0.107"
|
|
122
|
+
SARATOGA = "224.0.0.108"
|
|
123
|
+
LL_MANET_ROUTERS = "224.0.0.109"
|
|
124
|
+
IGRS = "224.0.0.110"
|
|
125
|
+
BABEL = "224.0.0.111"
|
|
126
|
+
MMA_DEVICE_DISCOVERY = "224.0.0.112"
|
|
127
|
+
ALL_JOYN = "224.0.0.113"
|
|
128
|
+
INTER_RFID_READER_PROTOCOL = "224.0.0.114"
|
|
129
|
+
JSDP = "224.0.0.115"
|
|
130
|
+
DEVICE_DISCOVERY = "224.0.0.116"
|
|
131
|
+
DLEP_DISCOVERY = "224.0.0.117"
|
|
132
|
+
MAAS = "224.0.0.118"
|
|
133
|
+
ALL_GRASP_NEIGHBORS = "224.0.0.119"
|
|
134
|
+
UNASSIGNED_D = [
|
|
135
|
+
"224.0.0.120", "224.0.0.121", "224.0.0.122", "224.0.0.123", "224.0.0.124",
|
|
136
|
+
"224.0.0.125", "224.0.0.126", "224.0.0.127", "224.0.0.128", "224.0.0.129",
|
|
137
|
+
"224.0.0.130", "224.0.0.131", "224.0.0.132", "224.0.0.133", "224.0.0.134",
|
|
138
|
+
"224.0.0.135", "224.0.0.136", "224.0.0.137", "224.0.0.138", "224.0.0.139",
|
|
139
|
+
"224.0.0.140", "224.0.0.141", "224.0.0.142", "224.0.0.143", "224.0.0.144",
|
|
140
|
+
"224.0.0.145", "224.0.0.146", "224.0.0.147", "224.0.0.148", "224.0.0.149"
|
|
141
|
+
]
|
|
142
|
+
RAMP_ALTITUDE_CDN = "224.0.0.150"
|
|
143
|
+
UNASSIGNED_E = [
|
|
144
|
+
"224.0.0.151", "224.0.0.152", "224.0.0.153", "224.0.0.154", "224.0.0.155",
|
|
145
|
+
"224.0.0.156", "224.0.0.157", "224.0.0.158", "224.0.0.159", "224.0.0.160",
|
|
146
|
+
"224.0.0.161", "224.0.0.162", "224.0.0.163", "224.0.0.164", "224.0.0.165",
|
|
147
|
+
"224.0.0.166", "224.0.0.167", "224.0.0.168", "224.0.0.169", "224.0.0.170",
|
|
148
|
+
"224.0.0.171", "224.0.0.172", "224.0.0.173", "224.0.0.174", "224.0.0.175",
|
|
149
|
+
"224.0.0.176", "224.0.0.177", "224.0.0.178", "224.0.0.179", "224.0.0.180",
|
|
150
|
+
"224.0.0.181", "224.0.0.182", "224.0.0.183", "224.0.0.184", "224.0.0.185",
|
|
151
|
+
"224.0.0.186", "224.0.0.187", "224.0.0.188", "224.0.0.189", "224.0.0.190",
|
|
152
|
+
"224.0.0.191", "224.0.0.192", "224.0.0.193", "224.0.0.194", "224.0.0.195",
|
|
153
|
+
"224.0.0.196", "224.0.0.197", "224.0.0.198", "224.0.0.199", "224.0.0.200",
|
|
154
|
+
"224.0.0.201", "224.0.0.202", "224.0.0.203", "224.0.0.204", "224.0.0.205",
|
|
155
|
+
"224.0.0.206", "224.0.0.207", "224.0.0.208", "224.0.0.209", "224.0.0.210",
|
|
156
|
+
"224.0.0.211", "224.0.0.212", "224.0.0.213", "224.0.0.214", "224.0.0.215",
|
|
157
|
+
"224.0.0.216", "224.0.0.217", "224.0.0.218", "224.0.0.219", "224.0.0.220",
|
|
158
|
+
"224.0.0.221", "224.0.0.222", "224.0.0.223", "224.0.0.224", "224.0.0.225",
|
|
159
|
+
"224.0.0.226", "224.0.0.227", "224.0.0.228", "224.0.0.229", "224.0.0.230",
|
|
160
|
+
"224.0.0.231", "224.0.0.232", "224.0.0.233", "224.0.0.234", "224.0.0.235",
|
|
161
|
+
"224.0.0.236", "224.0.0.237", "224.0.0.238", "224.0.0.239", "224.0.0.240",
|
|
162
|
+
"224.0.0.241", "224.0.0.242", "224.0.0.243", "224.0.0.244", "224.0.0.245",
|
|
163
|
+
"224.0.0.246", "224.0.0.247", "224.0.0.248", "224.0.0.249", "224.0.0.250"
|
|
164
|
+
]
|
|
165
|
+
MDNS = "224.0.0.251"
|
|
166
|
+
LINK_LOCAL_NAME_RESOLUTION = "224.0.0.252"
|
|
167
|
+
TEREDO = "224.0.0.253"
|
|
168
|
+
RFC3692 = "224.0.0.254"
|
|
169
|
+
UNASSIGNED_F = "224.0.0.255"
|