[Ottawa-pm] Fwd: CIDR to IP-netmask

Allan Fields allan.fields at gmail.com
Mon Apr 4 18:38:59 PDT 2011


Dunno why this didn't get to the list.  It's not exactly off-topic.

-Allan

---------- Forwarded message ----------
From: allan.fields at gmail.com
Date: Fri, 1 Apr 2011 19:19:54 +0000
Subject: CIDR to IP:netmask
To: ottawa-pm at pm.org

What do you'all do to get the netmask in dotted-quad form from CIDR?
Or apply the mask to your IP to get the subnet?

Does anyone have the arithmetic answer?  No modules allowed!  I do a
bitwise-stringy version.

The reason I ask is I found this an interesting example of using
perl's pack/unpack as an IP calculator.  Linux has a command named
ipcalc, but you may know not all installs can just request specific
binary/modules.

As a reminder CIDR for IPv4 is:
    IP ::= ([0-9]{1,3} '.' ){3} [0-9]{1,3}
    MASK ::= integer(0..32)
    CIDR ::= IP '/' MASK

Example (not meant to resemble real network):
    166.66.7.24/23
    166.66.7.0/23
    0.0.0.0/32
    1.2.3.4/22

I do something like:

If ($IPADDR=~qr{ \s* ['"]*
    ( (?:[0-9]{1,3}\.){3} [0-9]{1,3} ) /
    (     [0-9]{1,2}.                           )
['"]* \s* }x) {
    ($subnet_ip, $subnet_mask) = ($1,$2);

    if (not defined $subnet_mask or
        ($subnet_mask < 0 or $subnet_mask > 32)) {
        print "CIDR: Invalid mask\n";
        return 1;
    }

    my $bitstr = '1';
          $bitstr.= '0' x (32 - $subnet_mask);

    my $mask = join('.',unpack('C4',pack('B*',$bitstr)));

    print "IP: $subnet_ip Netmask: $mask\n";

    return 0;
} else {
    print "CIDR: Invalid\n";
    return 1:
}

# More advanced examples include calculating the subnet mask for two
CIDR's and determining if they reside in the same range.

.. Tired of typing on my BB keyboard.
Please post your code.

Sent from my BlackBerry device on the Rogers Wireless Network


More information about the Ottawa-pm mailing list