hath(1)

NAME
hath - Manipulate network blocks in CIDR notation

SYNOPSIS
hath [regexed|reduced|duped|diffed|listed] [-hb] <input>

INPUT

The input (stdin) should be a list of CIDR blocks, separated by whitespace. Empty lines will be ignored, but otherwise, malformed entries will cause an error to be displayed.

DESCRIPTION

Hath is a Haskell program for working with network blocks in CIDR notation. When dealing with blocks of network addresses, there are a few things that one usually wants to do with them:

•   Create a regular expression matching the CIDR block(s). This is because grep will throw up if you feed it CIDR.

•   Combine small blocks into larger ones. For example, if you have two consecutive /24s, they might combine into a larger /23.

•   View the result of block combination in a useful way.

•   List them.

Hath does just that. It takes as its input (via stdin) a list of CIDR blocks.

MODES

Hath has several modes:

•   Regexed This computes a (Perl-compatible) regular expression matching the input CIDR blocks. It's the default mode of operation.
    $ echo "10.0.0.0/29 10.0.0.8/29" | hath
    ((10).(0).(0).(15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0))

•   Reduced This combines small blocks into larger ones where possible, and eliminates redundant blocks. The output should be equivalent to the input, though.
    $ echo "10.0.0.0/24 10.0.1.0/24" | hath reduced
    10.0.0.0/23

•   Duped Shows only the blocks that would be removed by reduce; that is, it shows the ones that would get combined into larger blocks or are simply redundant.
    $ echo "10.0.0.0/24 10.0.1.0/24" | hath duped
    10.0.0.0/24
    10.0.1.0/24

•   Diffed Shows what would change if you used reduce. Uses diff-like notation.
    $ echo "10.0.0.0/24 10.0.1.0/24" | hath diffed
    -10.0.0.0/24
    -10.0.1.0/24
    +10.0.0.0/23

•   Listed List the IP addresses contained within the given CIDRs.
    $ echo 192.168.0.240/29 | hath listed
    192.168.0.240
    192.168.0.241
    192.168.0.242
    192.168.0.243
    192.168.0.244
    192.168.0.245
    192.168.0.246
    192.168.0.247

EXAMPLES

Use the "dig" command to look up the PTR records for a netblock:
$ echo 198.41.0.4/30 | hath listed | xargs -I{} dig +noall +answer -x '{}'
4.0.41.198.in-addr.arpa. 897	IN	PTR	a.root-servers.net.
6.0.41.198.in-addr.arpa. 900	IN	PTR	rs.internic.net.

OPTIONS

--barriers, -b
    (regexed mode only) Place barriers in front/back of the regex to prevent, for example, '127.0.0.1' from matching '127.0.0.100'. The downside is that the resulting regexp will match something that is not an IP address. This can interfere with things like grep -o. Without --barriers, you can match things you shouldn't:
    $ echo 127.0.0.100 | grep -P $(echo 127.0.0.1/32 | hath)
    127.0.0.100
    Using --barriers can prevent this:
    $ echo 127.0.0.100 | grep -P $(echo 127.0.0.1/32 | hath -b)
    $ echo $?
    1
    But, this may also cause the regex to match something that isn't an IP address:
    $ echo x127.0.0.1x | grep -Po $(echo 127.0.0.1/32 | hath -b)
    x127.0.0.1x

--normalize, -n
    (reduced mode only) Normalize the output representation of CIDRs by zeroing the host bits. This option only has an effect in "reduced" mode, because in the "duped" or "diffed" modes, it would be confusing to see CIDRs that you did not input in the first place being removed.
    $ echo 127.0.0.1/8 | hath reduced
    127.0.0.1/8
    $ echo 127.0.0.1/8 | hath reduced --normalize
    127.0.0.0/8

--sort, -s
    (reduced mode only) Sort the output CIDRs numerically by octet. The "sort" utility doesn't understand IP addresses, so the default pipe-to-sort approach fails in some cases:
    $ echo "10.0.121.32/28 10.0.93.248/29" | hath reduced | sort
    10.0.121.32/28
    10.0.93.248/29
    $ echo "10.0.121.32/28 10.0.93.248/29" | hath reduced | sort -n
    10.0.121.32/28
    10.0.93.248/29
    That failure justifies adding the additional option to hath:
    $ echo "10.0.121.32/28 10.0.93.248/29" | hath reduced --sort
    10.0.93.248/29
    10.0.121.32/28

BUGS
Send bugs to michael@orlitzky.com.