Skip to content

Commit c9a4cc3

Browse files
committed
update
1 parent e86b325 commit c9a4cc3

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed

03-docs.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ Advanced topics:
2727
* [Webservers](/docs/webservers)
2828
* [Totp](/docs/totp)
2929
* [Firewall](/docs/firewall)
30+
* [Network](/docs/network)
3031
* [Analyzer](/docs/analyzer)
3132
* [Template](/docs/template)

docs/network.md

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
layout: page
3+
title: Network
4+
permalink: /docs/network/
5+
---
6+
7+
The "Network" class provides network-related utility functions for working with IP addresses, including checking local IPs and matching IP addresses against CIDR ranges for both IPv4 and IPv6.
8+
9+
## isLocalIP
10+
11+
```
12+
Network::isLocalIP(string $ipAddress): bool
13+
```
14+
15+
Check if the given IP address is assigned to a local network interface on the server.
16+
17+
This method executes the `ip a` command to retrieve all network interfaces and their assigned IP addresses, then checks if the provided IP address matches any of them.
18+
19+
Parameters:
20+
- `$ipAddress` - The IP address to check (can be IPv4 or IPv6)
21+
22+
Returns:
23+
- `true` if the IP address is assigned to a local interface
24+
- `false` otherwise
25+
26+
Example:
27+
28+
```
29+
if (Network::isLocalIP('127.0.0.1')) {
30+
echo "This is a local IP address";
31+
}
32+
33+
if (Network::isLocalIP('::1')) {
34+
echo "This is a local IPv6 loopback address";
35+
}
36+
```
37+
38+
This is useful for determining if a request is coming from the local machine or for security checks.
39+
40+
## ip4Match
41+
42+
```
43+
Network::ip4Match(string $ip4, string $range): bool
44+
```
45+
46+
Check if an IPv4 address is within a given CIDR range.
47+
48+
This method validates both the IP address and the range, then performs bitwise comparison to determine if the IP falls within the specified subnet.
49+
50+
Parameters:
51+
- `$ip4` - The IPv4 address to check
52+
- `$range` - The CIDR range (e.g., "192.168.1.0/24" or "10.0.0.1" for single IP)
53+
54+
Returns:
55+
- `true` if the IP address is within the range
56+
- `false` if the IP is outside the range or if inputs are invalid
57+
58+
Example:
59+
60+
```
61+
// Check if IP is in a specific subnet
62+
if (Network::ip4Match('192.168.1.50', '192.168.1.0/24')) {
63+
echo "IP is in the 192.168.1.0/24 subnet";
64+
}
65+
66+
// Check against a single IP (implicitly /32)
67+
if (Network::ip4Match('10.0.0.1', '10.0.0.1')) {
68+
echo "IP matches exactly";
69+
}
70+
71+
// Check if IP is in a larger range
72+
if (Network::ip4Match('172.16.50.10', '172.16.0.0/12')) {
73+
echo "IP is in the 172.16.0.0/12 range";
74+
}
75+
```
76+
77+
Common use cases:
78+
- Restricting access to specific IP ranges
79+
- Implementing IP-based whitelists or blacklists
80+
- Network security filtering
81+
- Geographic or organizational IP range checks
82+
83+
## ip6Match
84+
85+
```
86+
Network::ip6Match(string $ip6, string $range): bool
87+
```
88+
89+
Check if an IPv6 address is within a given CIDR range.
90+
91+
This method validates both the IPv6 address and the range, converts them to binary representation, and compares the prefix bits to determine if the IP falls within the specified subnet.
92+
93+
Parameters:
94+
- `$ip6` - The IPv6 address to check
95+
- `$range` - The CIDR range (e.g., "2001:db8::/32" or "::1" for single IP)
96+
97+
Returns:
98+
- `true` if the IP address is within the range
99+
- `false` if the IP is outside the range or if inputs are invalid
100+
101+
Example:
102+
103+
```
104+
// Check if IPv6 is in a specific subnet
105+
if (Network::ip6Match('2001:db8::1', '2001:db8::/32')) {
106+
echo "IP is in the 2001:db8::/32 subnet";
107+
}
108+
109+
// Check against IPv6 loopback
110+
if (Network::ip6Match('::1', '::1')) {
111+
echo "This is the IPv6 loopback address";
112+
}
113+
114+
// Check if IP is in a larger range
115+
if (Network::ip6Match('2001:0db8:85a3::8a2e:0370:7334', '2001:db8::/32')) {
116+
echo "IP is in the documentation range";
117+
}
118+
```
119+
120+
The method handles IPv6 address normalization internally, so various representations of the same address will be matched correctly.
121+
122+
## Practical Examples
123+
124+
### IP Whitelisting
125+
126+
```
127+
$allowedRanges = [
128+
'192.168.1.0/24', // Local network
129+
'10.0.0.0/8', // Private network
130+
'2001:db8::/32', // IPv6 range
131+
];
132+
133+
$clientIP = $_SERVER['REMOTE_ADDR'];
134+
135+
$isAllowed = false;
136+
foreach ($allowedRanges as $range) {
137+
if (filter_var($clientIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
138+
if (Network::ip4Match($clientIP, $range)) {
139+
$isAllowed = true;
140+
break;
141+
}
142+
} elseif (filter_var($clientIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
143+
if (Network::ip6Match($clientIP, $range)) {
144+
$isAllowed = true;
145+
break;
146+
}
147+
}
148+
}
149+
150+
if (!$isAllowed) {
151+
http_response_code(403);
152+
die('Access denied');
153+
}
154+
```
155+
156+
### Local Request Detection
157+
158+
```
159+
$clientIP = $_SERVER['REMOTE_ADDR'];
160+
161+
if (Network::isLocalIP($clientIP)) {
162+
// Enable debug mode for local requests
163+
ini_set('display_errors', '1');
164+
error_reporting(E_ALL);
165+
} else {
166+
// Hide errors for external requests
167+
ini_set('display_errors', '0');
168+
}
169+
```
170+
171+
### Network-Based Feature Flags
172+
173+
```
174+
function isInternalNetwork(string $ip): bool {
175+
$internalRanges = [
176+
'10.0.0.0/8',
177+
'172.16.0.0/12',
178+
'192.168.0.0/16',
179+
];
180+
181+
foreach ($internalRanges as $range) {
182+
if (Network::ip4Match($ip, $range)) {
183+
return true;
184+
}
185+
}
186+
return false;
187+
}
188+
189+
$clientIP = $_SERVER['REMOTE_ADDR'];
190+
if (isInternalNetwork($clientIP)) {
191+
// Show admin features for internal users
192+
$showAdminPanel = true;
193+
}
194+
```

0 commit comments

Comments
 (0)