Re: wha is ipv4 prefix?? (why not netmask)



On Aug 7, 2008, at 1:11 PM, Nathaniel McCallum wrote:

Derek Atkins wrote:
Miguel Angel Cañedo <mcanedo grupogcm com> writes:


I was pulling my hair trying to set static ipv4 settings.
Until I realized that NM 0.7 asks for PREFIX instead of NETMASK....

Now, my netmask should be 255.255.0.0
How do I transalte that into the Prefix?


/16 ?

I also thought the wording was less-than-clear.


Prefix means CIDR prefix, which probably doesn't help clear it up either. People have been using classful IPv4 vocabulary for a long time, but we don't really do that at a low level anymore. Everything is classless. Being able to accept a subnet mask in dotted quad notation is really a convenience thing for people still wanting to use the pre-CIDR notation.

This Wikipedia article does a reasonable job at explaining what CIDR is:

	http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing

It also has a chart that lists all of the /XX values and what the equivalent subnet mask is. The /XX value refers to how many of the leading bits of the 32-bit IPv4 address we want to be the same across all of our hosts. The most common would be /24, which is the old Class C subnet with a mask of 255.255.255.0. That means the first three octets of the address will be the same for every host. Only the last octet is unique. That gives you the possibility of having 256 unique hosts (in reality, it's 254 because .0 is the network address and .255 is the broadcast address in IPv4-world). See the table on the wikipedia page for more details.

Changing from prefix to netmask or netmask to prefix can be challenging depending on where you need to do it. Here's how to convert a prefix to a netmask in C (take an int, give a struct in_addr):

    struct in_addr *prefix2netmask(int prefix) {
        int mask = 0;
        char *buf = NULL;
        struct in_addr *ret;

if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) {
            return NULL;
        }

        mask = htonl(~((1 << (32 - prefix)) - 1));

        if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf,
                      INET_ADDRSTRLEN) == NULL) {
            return NULL;
        }

        if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) {
            return NULL;
        }

        memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr));
        return ret;
    }

And converting a netmask to a prefix in C (take a struct in_addr, give back an int):

    int netmask2prefix(struct in_addr *netmask) {
        int ret = -1;
        struct in_addr mask;

        if (netmask == NULL) {
            return -1;
        }

        memcpy(&mask, netmask, sizeof(struct in_addr));

        while (mask.s_addr != 0) {
            mask.s_addr = mask.s_addr >> 1;
            ret++;
        }

        return ret;
    }

I pulled that code from a library a wrote...didn't just write it here, so the API is based around what that library needs internally. But all of that is probably not useful to most people, so is there a command that can convert between netmasks and prefixes? Yes. ipcalc:

    $ ipcalc -p 192.168.1.100 255.255.255.0
    PREFIX=24
    $ ipcalc -m 192.168.1.100/24
    NETMASK=255.255.255.0

And it even gives it to you in shell env format so you can use it in scripts.

--
David Cantrell <dcantrell redhat com>
Red Hat / Honolulu, HI



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]