RegEx IP Address Validation

I recently had a project at work where I had to add in some strict IP Address validation and restrictions. We are being required to prevent end users from entering certain IP addresses or ranges. This is a perfect task for Regular Expressions. I am not an expert in RegEx, but I can get out basic RegEx expressions. The first thing I did was search around the net to see if there were expressions already done for IP addresses. There are, but not entirely what I needed. The best I could find were expressions to validate the IP address to ensure it is valid. I didn't find anything to test for certain ranges of IP Addresses. Since I can hack at RegEx a bit I took the expression I found to validate the IP address and made modifications to do the tests I needed. These are the Regular Expressions I hacked up to do the validation and restrictions.

We were required to block these IP addresses or ranges.

view plain print about
410.0.0.0 -
5172.16.0.0 -
6192.168.0.0 -


The first three where just plain string matches so no RegEx. The remaining three I did using these expressions.

view plain print about
1<!--- test to see if it is a valid IP Address --->
2<cfset var pattern = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
4<!--- see if IP Address is in this range - --->
5<cfset var pattern2 = "^(10)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
7<!--- see if IP Address is in this range - --->
8<cfset var pattern3 = "^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
10<!--- see if IP Address is in this range - --->    
11<cfset var pattern4 = "^(192)\.(168)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">


Using these expressions is done like this.

view plain print about
1<cfif !REFindNoCase(pattern,arguments.theIpAddress)>
2    <cfreturn false />

I have a validation object for all my validation so I added a new method to test the IP Addresses.

view plain print about
1<cffunction name="validIpAddress" access="public" output="false" returntype="boolean" hint="returns T/F based on private rules for valid Ip address">
2    <cfargument name="theIpAddress" type="string" required="false" default="" hint=""/>
3        <cfset var pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
4        <cfset var pattern2 = "^(10)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
5        <cfset var pattern3 = "^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
6        <cfset var pattern4 = "^(192)\.(168)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)">
8        <cfif !REFindNoCase(pattern,arguments.theIpAddress)>
9            <cfreturn false />
10        </cfif>
12        <cfif !len(trim(arguments.theIpAddress))>
13            <cfreturn false />
14        </cfif>
15        <cfif arguments.theIpAddress eq "" or arguments.theIpAddress eq "" or arguments.theIpAddress eq "">
16            <cfreturn false />
17        </cfif>
19        <cfif REFindNoCase(pattern2,arguments.theIpAddress)>
20            <cfreturn false />
21        </cfif>
23        <cfif REFindNoCase(pattern3,arguments.theIpAddress)>
24            <cfreturn false />
25        </cfif>
27        <cfif REFindNoCase(pattern4,arguments.theIpAddress)>
28            <cfreturn false />
29        </cfif>
31    <cfreturn true />
34--------- in my code I test my ip address this way ---------
36<cfset BValid = createObject("component", "model.utils.bValid").init() >
38<cfif Bvalid.validIpAddress(ipAddress)>
39    <cfset invalid = true />

Regular Expressions are not always an exact science and as such many times can be written differently to achieve the same result. For me these work just fine so I'm using them in both the ColdFusion server side validation and in the JavaScript client side validation. Enjoy this little <cf_gem>.