-3

I am doing some programming, I wanna convert the netmask to network prefix length.

For example 255.255.255.0 ----> 24.

Finally I write some code to do so.

const char *network = "255.255.255.0";
int n = inet_addr(netowrk);
int i = 0;
while (n > 0) {
    n = n << 1;
    i++;

}

i will be the network count

bigpotato
  • 211
  • 2
  • 3
  • 13
  • 1
    That's an admirable goal. Good luck with it, and please post your result on your favourite social platform (Twitter, Whatssnap, etc.), but not here. This is a website for *questions*. – Kerrek SB Jun 27 '14 at 08:52
  • look at n inside the loop and you will see whats going wrong. – mch Jun 27 '14 at 09:22
  • This question is effectively a duplicate of [**How to count the number of set bits in a 32-bit integer?**](https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer) – Andrew Henle Mar 17 '21 at 21:43

4 Answers4

8

You should first try to compile your code, it can help you a lot. There are compilations errors because you mistyped variable name "netowrk"

To calculate prefix instead to left shift you should try with right shift and instead of using inet_addr try inet_pton().

For more details go through the post IPv4 to decimal different values?

Here you can check the code:

int main()
{
    const char *network = "255.255.255.0";
    int n;
    inet_pton(AF_INET, network, &n);
    int i = 0;

    while (n > 0) {
            n = n >> 1;
            i++;
    }

    printf("network = %s, suffix = %d\n", network, i);
}
Community
  • 1
  • 1
Jaymin Patel
  • 96
  • 1
  • 4
0

I cannot add comments, but be aware that Jaymin's answer is dependent on the host byte order. You should use ntohl(3) to convert the address returned by inet_pton to host byte order, and then left shift, right shift, or bit-count to get the prefix length.

For that matter, you really ought to be passing a struct sockaddr_in into inet_pton...

wolf1oo
  • 177
  • 1
  • 5
0

As for netmask, we know that the value is always a continuous series of set bits followed by zero bits. there are no zero bits in between. So given that we know that max set bits could be only 32, counting the number of zero bits makes a smaller loop count to calculate the prefix len.

unsigned int n = 0xFFFFFE00; // (255.255.254.0) => 23 bits
int zerobits = 0;

while ((n & 0x1) == 0) {
    n = n >> 1;
    zerobits++;
}
return (32 - zerobits);

So here , the loop count is only for the number of zero bits (9 in this case).

0

This works for IPv4 networks.

#include <arpa/inet.h>
#include <iostream>

int main() {
  // const char *network = "255.255.255.0";
  // const char *network = "255.0.0.0";
  // const char *network = "224.0.0.0";
  const char *network = "255.255.255.224";

  int ret;
  int count_ones = 0;      
  std::uint8_t byte;
  std::uint8_t buf[sizeof(struct in_addr)];

  ret = inet_pton(AF_INET, network, &buf);
  // assert(ret > 0);

  for (int i = 0; i < sizeof(struct in_addr); i++) {
    // std::cout << int(buf[i]) << std::endl;

    byte = buf[i];

    for (int j = 0; j < 8; j++) {
      count_ones += (byte & 1);
      byte >>= 1;
    }
  }

  std::cout << "network: " << network << ", suffix: " << count_ones << std::endl;
}
nvd
  • 2,995
  • 28
  • 16