Skip to content

Commit 3c9049e

Browse files
committed
feat: Add IP address analysis module with validation and range support
1 parent 105090f commit 3c9049e

File tree

2 files changed

+105
-100
lines changed

2 files changed

+105
-100
lines changed

Jiyu_udp_attack/ip_analyze.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""
2+
This module provides functions to analyze IP addresses and ranges, converting them into a list of valid IP addresses.
3+
"""
4+
5+
6+
def ip_to_tuple(ip: str) -> tuple[int, int, int, int]:
7+
"""
8+
Converts an IP address string to a tuple of four integers.
9+
10+
Args:
11+
ip (str): The IP address in string format (e.g., "192.168.1.1").
12+
13+
Returns:
14+
tuple[int, int, int, int]: A tuple representing the four octets of the IP address.
15+
16+
Raises:
17+
TypeError: If the input is not a string.
18+
ValueError: If the input is not a valid IP address format.
19+
"""
20+
if not isinstance(ip, str):
21+
raise TypeError(f"Expected string, got {type(ip).__name__}")
22+
try:
23+
ip_tuple = tuple(int(x) for x in ip.split("."))
24+
except ValueError:
25+
raise ValueError(f"Invalid IP address format: {ip}") from None
26+
if len(ip_tuple) != 4 or any(x < 0 or x > 255 for x in ip_tuple):
27+
raise ValueError(f"Invalid IP address format: {ip}")
28+
return ip_tuple
29+
30+
31+
# pylint: disable=too-many-branches
32+
def ip_analyze(ip: str) -> list[str]:
33+
"""
34+
Analyzes an IP address or range and returns a list of valid IP addresses.
35+
36+
Args:
37+
ip (str): The IP address or range in string format (e.g., "192.168.1.1", "192.168.1.1/24", "192.168.1.1-100").
38+
39+
Returns:
40+
list[str]: A list of valid IP addresses.
41+
42+
Raises:
43+
TypeError: If the input is not a string.
44+
ValueError: If the input is not a valid IP address or range.
45+
"""
46+
if not isinstance(ip, str):
47+
raise TypeError(f"Expected string, got {type(ip).__name__}")
48+
ip = ip.replace(" ", "")
49+
if "/" in ip:
50+
match ip.split("/"):
51+
case [ip_addr, mask]:
52+
if not mask.isdigit():
53+
raise ValueError(f"Invalid subnet mask: {mask}")
54+
mask = int(mask)
55+
if mask < 0 or mask > 32:
56+
raise ValueError(f"Subnet mask out of range: {mask}")
57+
if mask < 16:
58+
raise ValueError(f"Subnet mask too small: {mask}")
59+
case _:
60+
raise ValueError(f"Invalid IP address format: {ip}")
61+
ip_tuple = ip_to_tuple(ip_addr)
62+
ip32 = ip_tuple[0] << 24 | ip_tuple[1] << 16 | ip_tuple[2] << 8 | ip_tuple[3]
63+
ip32 &= (0xFFFFFFFF >> (32 - mask)) << (32 - mask)
64+
return [
65+
f"{(i >> 24) & 0xFF}.{(i >> 16) & 0xFF}.{(i >> 8) & 0xFF}.{i & 0xFF}"
66+
for i in range(ip32 + 1, ip32 | ((1 << (32 - mask)) - 1))
67+
]
68+
if "-" in ip:
69+
ip_range_tuple = ip.split(".")
70+
if len(ip_range_tuple) != 4:
71+
raise ValueError(f"Invalid IP address range format: {ip}")
72+
ip_count = 1
73+
ip_range: list[tuple[int, int]] = []
74+
for i in ip_range_tuple:
75+
match i.split("-"):
76+
case [single]:
77+
if not single.isdigit():
78+
raise ValueError(f"Invalid IP address range format: {ip}")
79+
single = int(single)
80+
if single < 0 or single > 255:
81+
raise ValueError(f"IP address out of range: {single}")
82+
ip_range.append((single, single))
83+
case [start, end]:
84+
if not (start.isdigit() and end.isdigit()):
85+
raise ValueError(f"Invalid IP address range format: {ip}")
86+
start = int(start)
87+
end = int(end)
88+
if start < 0 or start > 255 or end < 0 or end > 255 or start > end:
89+
raise ValueError(f"Invalid IP address range: {start}-{end}")
90+
ip_range.append((start, end))
91+
case _:
92+
raise ValueError(f"Invalid IP address range format: {ip}")
93+
ip_count *= ip_range[-1][1] - ip_range[-1][0] + 1
94+
if ip_count > 65536:
95+
raise ValueError(f"IP address range too large: {ip_count} addresses")
96+
return [
97+
f"{a}.{b}.{c}.{d}"
98+
for a in range(ip_range[0][0], ip_range[0][1] + 1)
99+
for b in range(ip_range[1][0], ip_range[1][1] + 1)
100+
for c in range(ip_range[2][0], ip_range[2][1] + 1)
101+
for d in range(ip_range[3][0], ip_range[3][1] + 1)
102+
]
103+
ip_tuple = ip_to_tuple(ip)
104+
return [f"{ip_tuple[0]}.{ip_tuple[1]}.{ip_tuple[2]}.{ip_tuple[3]}"]

Jiyu_udp_attack/sender.py

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -4,106 +4,7 @@
44

55
import scapy.all as scapy
66

7-
8-
def ip_to_tuple(ip: str) -> tuple[int, int, int, int]:
9-
"""
10-
Converts an IP address string to a tuple of four integers.
11-
12-
Args:
13-
ip (str): The IP address in string format (e.g., "192.168.1.1").
14-
15-
Returns:
16-
tuple[int, int, int, int]: A tuple representing the four octets of the IP address.
17-
18-
Raises:
19-
TypeError: If the input is not a string.
20-
ValueError: If the input is not a valid IP address format.
21-
"""
22-
if not isinstance(ip, str):
23-
raise TypeError(f"Expected string, got {type(ip).__name__}")
24-
try:
25-
ip_tuple = tuple(int(x) for x in ip.split("."))
26-
except ValueError:
27-
raise ValueError(f"Invalid IP address format: {ip}") from None
28-
if len(ip_tuple) != 4 or any(x < 0 or x > 255 for x in ip_tuple):
29-
raise ValueError(f"Invalid IP address format: {ip}")
30-
return ip_tuple
31-
32-
33-
# pylint: disable=too-many-branches
34-
def ip_analyze(ip: str) -> list[str]:
35-
"""
36-
Analyzes an IP address or range and returns a list of valid IP addresses.
37-
38-
Args:
39-
ip (str): The IP address or range in string format (e.g., "192.168.1.1", "192.168.1.1/24", "192.168.1.1-100").
40-
41-
Returns:
42-
list[str]: A list of valid IP addresses.
43-
44-
Raises:
45-
TypeError: If the input is not a string.
46-
ValueError: If the input is not a valid IP address or range.
47-
"""
48-
if not isinstance(ip, str):
49-
raise TypeError(f"Expected string, got {type(ip).__name__}")
50-
ip = ip.replace(" ", "")
51-
if "/" in ip:
52-
match ip.split("/"):
53-
case [ip_addr, mask]:
54-
if not mask.isdigit():
55-
raise ValueError(f"Invalid subnet mask: {mask}")
56-
mask = int(mask)
57-
if mask < 0 or mask > 32:
58-
raise ValueError(f"Subnet mask out of range: {mask}")
59-
if mask < 16:
60-
raise ValueError(f"Subnet mask too small: {mask}")
61-
case _:
62-
raise ValueError(f"Invalid IP address format: {ip}")
63-
ip_tuple = ip_to_tuple(ip_addr)
64-
ip32 = ip_tuple[0] << 24 | ip_tuple[1] << 16 | ip_tuple[2] << 8 | ip_tuple[3]
65-
ip32 &= (0xFFFFFFFF >> (32 - mask)) << (32 - mask)
66-
return [
67-
f"{(i >> 24) & 0xFF}.{(i >> 16) & 0xFF}.{(i >> 8) & 0xFF}.{i & 0xFF}"
68-
for i in range(ip32 + 1, ip32 | ((1 << (32 - mask)) - 1))
69-
]
70-
if "-" in ip:
71-
ip_range_tuple = ip.split(".")
72-
if len(ip_range_tuple) != 4:
73-
raise ValueError(f"Invalid IP address range format: {ip}")
74-
ip_count = 1
75-
ip_range: list[tuple[int, int]] = []
76-
for i in ip_range_tuple:
77-
match i.split("-"):
78-
case [single]:
79-
if not single.isdigit():
80-
raise ValueError(f"Invalid IP address range format: {ip}")
81-
single = int(single)
82-
if single < 0 or single > 255:
83-
raise ValueError(f"IP address out of range: {single}")
84-
ip_range.append((single, single))
85-
case [start, end]:
86-
if not (start.isdigit() and end.isdigit()):
87-
raise ValueError(f"Invalid IP address range format: {ip}")
88-
start = int(start)
89-
end = int(end)
90-
if start < 0 or start > 255 or end < 0 or end > 255 or start > end:
91-
raise ValueError(f"Invalid IP address range: {start}-{end}")
92-
ip_range.append((start, end))
93-
case _:
94-
raise ValueError(f"Invalid IP address range format: {ip}")
95-
ip_count *= ip_range[-1][1] - ip_range[-1][0] + 1
96-
if ip_count > 65536:
97-
raise ValueError(f"IP address range too large: {ip_count} addresses")
98-
return [
99-
f"{a}.{b}.{c}.{d}"
100-
for a in range(ip_range[0][0], ip_range[0][1] + 1)
101-
for b in range(ip_range[1][0], ip_range[1][1] + 1)
102-
for c in range(ip_range[2][0], ip_range[2][1] + 1)
103-
for d in range(ip_range[3][0], ip_range[3][1] + 1)
104-
]
105-
ip_tuple = ip_to_tuple(ip)
106-
return [f"{ip_tuple[0]}.{ip_tuple[1]}.{ip_tuple[2]}.{ip_tuple[3]}"]
7+
from Jiyu_udp_attack.ip_analyze import ip_analyze
1078

1089

10910
def send_packet(src_ip: str, dst_ip: str, dst_port: int, data: bytes) -> None:

0 commit comments

Comments
 (0)