Quantcast
Channel: Rather Curious ... » Tek-Tips
Viewing all articles
Browse latest Browse all 2

Comparing an IP Address against a given range

0
0

I was recently asked how one might compare a given IP address against a range of IP addresses (assumedly in an elegant manner). I can’t really see why one would ever really need to do this kind of thing in php, but the chap in question explained that it was for the management of an IP address block-list.

anyway, here’s the code I wrote for it. After having done so, I wonder whether a natural text based comparison would have done the trick just as well (you’d still need the validation of course). It seems to work ok but i have not thought it through fully…

–edit–
my tek-tips colleague feherke, pointed out to me that there’s an even easier way of converting ip addresses to decimal notation. the script is accordingly edited
–/edit–

The code : …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php
 
/**
 * class to compare an ip address against a given range of IPs
 *
 * sample usage
 * <code>
 $ipRangeCompare = new IPRangeCompare;
 $result = $ipRangeCompare->compare('212.143.142.1', '212.142.142.1', '212.143.140.255');
 if ($ipRangeCompare->isError){
 	echo $ipRangeCompare->getErrorMessages();
 	exit;
 } else {
 	if ($result){
 		echo "Confirmed that $ipRangeCompare->ip is within the range $ipRangeCompare->startIP - $ipRangeCompare->endIP";
 	} else {
 		echo "Confirmed that $ipRangeCompare->ip is NOT within the range $ipRangeCompare->startIP - $ipRangeCompare->endIP";
 	}
 }
 * </code>
 */
 
class IPRangeCompare{
 
	public $endIP;
	public $startIP;
	public $ip;
	public $errors;
 
	public $isError;
 
	/**
	 * constructor method
	 * @return
	 */
	public function __construct(){
		$this->flush();
	}
 
	/**
	 * public method that kick starts the engine.
	 *
	 * @return bool - true if the IP is in the provided range, false otherwise
	 *
	 * @param object $startIP
	 * @param object $endIP
	 * @param object $ip
	 */
	public function compare ($startIP, $endIP, $ip){
		$this->flush();
		$this->startIP = $startIP;
		$this->endIP = $endIP;
		$this->ip = $ip;
		if (!$this->isValidIP($this->startIP) || !$this->isValidIP($this->endIP) || !$this->isValidIP($this->ip)){
			$this->setError('IP address provided is not valid');
			return false;
		}
		$this->startIPDecimal = $this->getDecimalIP($this->startIP);
		$this->endIPDecimal = $this->getDecimalIP($this->endIP);
		$this->ipDecimal = $this->getDecimalIP($this->ip);
		$this->checkIPDirection();
 
		$match = ($this->ipDecimal >= $this->startIPDecimal) && ($this->ipDecimal <= $this->endIPDecimal);
		return $match;
	}
	/**
	 * public function to return the error messages
	 *
	 * @return string
	 */
	public function getErrorMessage(){
		$return = '';
		if ($this->isError){
			foreach ($this->errors as $e){
				$return .= "\r\n<div class=\"errorMessage\">$e</div>\r\n";
			}
		}
		return $return;
	}
 
	/**
	 * method to invert start and end ip addresses if they have been entered the wrong way around
	 *
	 * @return void
	 */
	private function checkIPDirection(){
		if ($this->startIPDecimal > $this->endIPDecimal){
			$temp = $this->endIPDecimal;
			$this->endIPDecimal = $this->startIPDecimal;
			$this->startIPDecimal = $temp;
			$temp = $this->endIP;
			$this->endIP = $this->startIP;
			$this->startIP = $temp;
		}
	}
 
	/**
	 * private method to convert an octet based IP address to a decimal
	 *
	 * @return decimal IP address
	 * @param string $ip
	 */
	private function getDecimalIP($ip){
                return ip2long($ip);
                /* left in for historic reasons only
		$bits = explode ('.', $ip);
		//convert the octets to binary
		foreach ($bits as $bit){
			$_bits[] = str_pad(decbin($bit), 8, '0', STR_PAD_LEFT);
		}
 
		//now implode the _bits
		$bin = implode('', $_bits);
		//convert to decimal
		$dec = bindec($bin);
 
		return $dec;
                */
	}
 
	/**
	 * private method for determining whether the ip address provided is in the right format
	 *
	 * @return bool: true for the right format, false otherwise
	 * @param object $ip
	 */
	private function isValidIP($ip){
		$pattern = '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ims';
		$result = preg_match($pattern, $ip, $matches);
		if (!$result){
			return false;
		}
		for($i=1; $i<=4; $i++){
			if ($matches[$i] < 0 || $matches[$i] > 255){
				return false;
			}
		}
		return true;
	}
 
	/**
	 * private helper method to set error messages
	 *
	 * @return void
	 * @param object $error
	 */
	private function setError($error){
		$this->errors[] = $error;
		$this->isError = true;
	}
 
 
	/**
	 * private method for zeroing the variables
	 * @return
	 */
	private function flush(){
		$this->errors = array();
		$this->startIP = $this->endIP = $this->ip = null;
		$this->isError= false;
	}
}
?>

Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images