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.
@@ -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"