Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

From time to time I want to grep CIDR ranges out of my Apache log files. This is easy for ranges that fall on the natural boundaries (/8, /16 and /24) but not so easy for other ranges such as /17 and /25.

Examples:

# 192.168.0.0/16: (easy)
grep " 192\.168\." access_log

# 192.168.128.0/17: (more thought required)
grep -E " 192\.168\.(12[89]|1[3-9][0-9]|2[0-5][0-9])\." access_log

# 192.168.0.0/17: (more thought required)
grep -E " 192\.168\.([0-9]|[0-9][0-9]|1[01][0-9]|12[0-7])\." access_log

# 192.168.128.0/18: (straining my brain)
grep -E " 192\.168\.(1[2-8][0-9]|19[01])\." access_log

These regexes ignore IP addresses that include leading zeros, such as 192.168.001.001, which isn't a problem in Apache log files but could be in other log files. Printers in particular seem to like the leading zeroes. It's easy enough to add the optional zeroes to the regex but it just makes the whole thing a little bit more difficult. There has to be an easier way.

Is there an easy way to select lines from a file that match any CIDR range?

Fancy regex extensions will be considered as will different tools (such as awk or perl if necessary but I want it to be a one-liner) if they make the job easier. Ideally, what I'd like is something like

grep "[:CIDR 192.168.128.0/18:]" access_log

A tool that converts a CIDR range into the appropriate regex would also be OK.

$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}

or

$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log

Bonus points if your answer also covers IPv6.

share|improve this question
1  
While searching around this I found a web-based tool for converting IP ranges to regexes. –  Ladadadada Jul 23 '12 at 17:05
    
And now it has moved here. –  Ladadadada Apr 11 '13 at 15:27

2 Answers 2

up vote 9 down vote accepted

There is, unsurprisingly, a tool for this: grepcidr.

It is not included by default with any system I'm aware of, but you can download it from here, and it is in both the Ubuntu package repository and the FreeBSD ports collection as well.

(Version 2.0 works with IPv6 networks too)

share|improve this answer
2  
If you need IPv6 functionality something horrible could be hacked together using Net::CIDR in perl... –  voretaq7 Jul 23 '12 at 17:04

The recently released rgxg command line tool generates regular expressions that match all addresses in a CIDR block:

$ rgxg cidr 192.168.128.0/18
192\.168\.(19[01]|1[3-8][0-9]|12[89])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])

or

$ rgxg cidr 2001:db8:a:b:c:d::/112
2001:0?[Dd][Bb]8:0?0?0?[Aa]:0?0?0?[Bb]:0?0?0?[Cc]:0?0?0?[Dd]((::[0-9A-Fa-f]{1,4}|::|:0?0?0?0(::|:[0-9A-Fa-f]{1,4}))|:0\.0(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){2})

For more information, see http://rgxg.sf.net.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.