<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ersin Acar &#187; Add new tag</title>
	<atom:link href="http://ersinacar.com/tag/add-new-tag/feed" rel="self" type="application/rss+xml" />
	<link>http://ersinacar.com</link>
	<description>PHP and Web Technologies Freak</description>
	<lastBuildDate>Fri, 06 Jan 2012 14:19:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Determine whether an IP is within a certain range</title>
		<link>http://ersinacar.com/determine-whether-an-ip-is-within-a-certain-range_112.html</link>
		<comments>http://ersinacar.com/determine-whether-an-ip-is-within-a-certain-range_112.html#comments</comments>
		<pubDate>Sat, 16 May 2009 08:31:43 +0000</pubDate>
		<dc:creator>Ersin Acar</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[ip range]]></category>
		<category><![CDATA[range]]></category>

		<guid isPermaLink="false">http://ersinacar.com/?p=112</guid>
		<description><![CDATA[I spend a lot of time lurking in the channel # PHP (EFnet and freenode, please &#8211; no flame wars) and this issue is a frequently asked that the rule is a simple answer in the form of the use of strpos (), or best to ip2long () in a more than less than reply. [...]]]></description>
			<content:encoded><![CDATA[<p>
I spend a lot of time lurking in the channel # PHP (EFnet and freenode, please &#8211; no flame wars) and this issue is a frequently asked that the rule is a simple answer in the form of the use of strpos (), or best to ip2long () in a more than less than reply.</p>
<p>Unfortunately, although the people in the rule that an IP address is just an unsigned 32-bit integer, and is easy to determine, usually with $ _SERVER [ "REMOTE_ADDR"], where the real challenge &#8211; is in defining the range within which it must decide whether the IP address. IP ranges are usually divided into three categories (in increasing complexity):</p>
<p>         1. Wild Card: 192.168.10 .*<br />
         2. Start-end: 10.1.0.0-10.1.255.255<br />
         3. * CIDR: 172.16.1.0/24</p>
<p>      * Classless Inter-Domain Routing<br />
<span id="more-112"></span><br />
The wild card method, or &#8216;class&#8217;, lets you in the class A (10 .*.*.*), Class B (172.16 .*.*) or Class C (192.168.10 .*) levels granularity of the things we like in the old days (before the web decided to make the popular internet). But still, this is just not granular enough for practice.</p>
<p>Thus was born CIDR (yes, I&#8217;m talking about skipping the end of last start now). CIDR was on the concept that we really do not need to create networks to 8, 16, 24-bit boundaries, and we could be more granular by using an arbitrary number (from 2-30) to a series of networks. Details about why you can not use &#8220;31&#8243; beyond the scope of this article.</p>
<p>CIDR renaming of the former Class A, B and C networks / 8, / 16 and / 24, and reflects the left-most significant bits of the 32-bit IP address. Thus was born the possibility of very specific IP ranges in the form abcd / xx. However, part of the problem with this is that, although it succinctly describes the network beginning and end, the most normal mortal people could not decipher. CIDR addressing may also be in the form of a longer netmask, eg abcd/255.255.255.224</p>
<p>The simplified form of start-IP &#8211; IP in the end was just the place for mortals and is typically used by persons without networking background. There is also strong in the consumer broadband router, and especially in Microsoft Windows DHCP server.</p>
<p>To have declared, as a number, and hence that a network mask is, how can we use this knowledge to help us in determining whether an IP is in an area?</p>
<p>What this article will attempt to do if the design of algorithms for the verification of IP addresses easier.</p>
<p>Logically, Method 1 (the wildcard), the method can be easily 2 (start-end) through the use of setting start and end of the wildcard string and replaces the character &#8220;*&#8221; and 0 for the start and 255 for the end, for example, &#8220;192.168.10 .*&#8221; will &#8220;192.168.10.0-192.168.10.255&#8243; which (I hope) will be for everyone apparently.</p>
<p>We can then assess whether Method1 and Method2 in the same way. In this, we simply use the PHP function in ip2long () for all 3 values and a mathematical test start <= IP <= end.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">list</span> <span style="color: #009900;">&#40;</span>$ low<span style="color: #339933;">,</span> $ II<span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'-'</span><span style="color: #339933;">,</span> $<span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $ Lower_dec <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ lower<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $ Upper_dec <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ top<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $ Ip_dec <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ ip<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>$ ip_dec<span style="color: #339933;">&gt;</span> <span style="color: #339933;">=</span> $ lower_dec<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #339933;">&amp;</span> <span style="color: #009900;">&#40;</span>$ ip_dec <span style="color: #339933;">&lt;=</span> $ upper_dec<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We have, however, a complicating factor here &#8211; PHP does not do unsigned integer (32 bit) &#8211; which would be necessary for this math to work. We can do this by switching to negate floating point datatypes. PHP stores floating species as 64-bit and thus will have no problem with the IPv4 address space (Note &#8211; This is obviously not enough for granular 128bit IPv6 addressing). It is the easiest way to solve the start <= IP <= end of problem with IP-and floating numers is the following piece of code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">$ Lower_dec <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">sprintf</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">% u</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ lower<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $ Upper_dec <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">sprintf</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">% u</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ top<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $ Ip_dec <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #990000;">sprintf</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">% u</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ ip<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>$ ip_dec<span style="color: #339933;">&gt;</span> <span style="color: #339933;">=</span> $ lower_dec<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #339933;">&amp;</span> <span style="color: #009900;">&#40;</span>$ ip_dec <span style="color: #339933;">&lt;=</span> $ upper_dec<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Next we have the challenge of handing the CIDR netmasks. What we can do is to create a format CIDR IP address / netmask, and calculate the start and end IP addresses of this block and proceed as before &#8211; but that would not take a joke &#8211; and would mean that I do not really taught by this article.</p>
<p>The method we use here is how the whole world of Internet routers, if a destination IP is in a given CIDR address space. And we receive and dirty with bitmask and bitwise logical operators.</p>
<p>This is a real world example, my web server IP 80.76.201.37 and the netblock in which it resides, is 80.76.201.32/27, how does this all mean?</p>
<p>Well, the / 27 indicates that the first 27 bits of the IP address are the same network and IP address in this network (area) have the same only 27 bits are identical. Bits 28-32 are variable and may be 5 bits of the variation. If you know your binary, so this means, 32 IP addresses. (However, with routing, you can not use the top and bottom of a range of IP addresses, because this special and the network and broadcast addresses. [This is also the reason why a / 31 is not much (except for PPP connections) you can not use the 2-addresses, which gives you room]).</p>
<p>So thinking logically, bitwise, if my IP address and CIDR specification, then all I have to do is verify that the first 27 bits are all involved, and I&#8217;m good. Right. How would we do this in PHP? Sounds simple, can only use PHP&#8217;s bitwise logical AND operator: &#038;<br />
Also correct.</p>
<p>To achieve this, we need to convert 27 in 27, which really means &#8211; a 32-bit number of 27 ones and zeros in binary-5 (which is what really looks like 255,255,255,224).</p>
<p>In pseudo-code that you then do if (IP &#038; bitmask) == (RANGE &#038; bitmask), then everything is good and you know that the IP is in the area.</p>
<p>Visualization of this with our IP address (using the Unix tool very handy ipcalc):</p>
<p>      Address: 80.76.201.37 01010000.01001100.11001001.00100101<br />
      Netmask: 255,255,255,224 11111111.11111111.11111111.11100000<br />
      Wildcard: 0.0.0.31 00000000.00000000.00000000.00011111</p>
<p>      Network: 80.76.201.32/27 01010000.01001100.11001001.00100000<br />
      HostMin: 80.76.201.33 01010000.01001100.11001001.00100001<br />
      HostMax: 80.76.201.62 01010000.01001100.11001001.00111110<br />
      Broadcast: 80.76.201.63 01010000.01001100.11001001.00111111<br />
      Hosts / Net: 30</p>
<p>You can do this in the wild card line-0.0.0.31, and the network-ored with wildcard results in the broadcast address: 80.76.201.63.</p>
<p>Knowing this, then the IP address ANDed with the network address is the same value as the margin ANDed with the network address and thus can be used as a comparison for an IP Broadcast resident in this area.</p>
<p>How can we network address in PHP, we have two strategies, one is in such a simple substr () and take the left bits of the number pad and then just to the right with 0s. Or we can do some math with &#8220;NOT from 2 to the power of the (32-area) &#8211; 1&#8243;. In order for our value / 27 This gives us the decimal value 31, NOTED results (65536-31) (representation in bit-form &#8211; PHP, it is considered a negative whole number, but we do not need to worry about that).</p>
<p>I am sure that from now on, you scream for some code (and if you are stuck in this long, you really deserve it).</p>
<p>Code to manipulate a number / netmask in a broadcast address, with mathematics, provided:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      $ Ip <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;80.76.201.37&quot;</span><span style="color: #339933;">;</span>
      $ Row <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;80.76.201.32&quot;</span><span style="color: #339933;">;</span>
      $ Netmask <span style="color: #339933;">=</span> <span style="color: #cc66cc;">27</span><span style="color: #339933;">;</span></pre></div></div>

<p>We can change the IP addresses too long integers with ip2long (with variable_dec &#8211; December is the abbreviation for decimal):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      $ Range_dec <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ <span style="color: #990000;">range</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      $ Ip_dec <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span> <span style="color: #009900;">&#40;</span>$ ip<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This gives us the basis of our mathematics, we need now only to the broadcast address.</p>
<p>Strategy 1 with str_pad to a string by padding with 0s and 1s.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      $ Netmask_dec <span style="color: #339933;">=</span> <span style="color: #990000;">bindec</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">str_pad</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> $ netmask<span style="color: #339933;">,</span><span style="color: #0000ff;">'1 '</span><span style="color: #009900;">&#41;</span>
       <span style="color: #339933;">.</span> <span style="color: #990000;">str_pad</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">32</span> <span style="color: #339933;">-</span> $ netmask<span style="color: #339933;">,</span><span style="color: #0000ff;">'0 '</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We can achieve the same result if the mathematics of NOTtin wildcard value. That is our strategy 2:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      $ Wildcard_dec <span style="color: #339933;">=</span> <span style="color: #990000;">pow</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">32</span> <span style="color: #339933;">-</span> $ netmask<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
      $ Netmask_dec <span style="color: #339933;">=</span> ~ $ wildcard_dec<span style="color: #339933;">;</span></pre></div></div>

<p>Once we know that the netmask address (decimal), as we have here, we know that if Anding this with the original IP results to check against the margin ANDed with the netmask, the IP is in the area, defined by the range / mask.</p>
<p>This can be done simply with:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>$ ip_dec <span style="color: #339933;">&amp;</span> $ netmask_dec<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span>$ range_dec <span style="color: #339933;">&amp;</span> $ netmask_dec<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I moved all this logic in an easy to make the file to a single function ip_in_range ($ ip, $ range) in which $ ip is the IP address you want to validate and $ field is a one of the above formats , Wild Card, start-end solution or CIDR. The function is a simple TRUE or FALSE, if the IP is in this area.</p>
]]></content:encoded>
			<wfw:commentRss>http://ersinacar.com/determine-whether-an-ip-is-within-a-certain-range_112.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

