2

I am declaring following variables

unsigned long   dstAddr;
unsigned long   gateWay;
unsigned long   mask;

These variables contains ipaddresses in network byte order. So when I am trying to print the dot notation using inet_ntoa function for mask variable sometimes it is printing strange values. The below code is in a while loop .. which loops for n times.

printf("%s\t%s\t%s\t",inet_ntoa(dstAddr),inet_ntoa(gateWay),inet_ntoa(mask));

  192.168.122.0         0.0.0.0    0.255.255.255    

but it should be

  192.168.122.0         0.0.0.0    255.255.255.0

I printed the HEX values of the variables and it shows ..

007aa8c0    00000000      ffffff00  

So is this because of inet_ntoa ??

Actually I am trying to get the values of the declared variables from 254 routing table in kernel via NETLINKS. I guess I should still use inet_ntoa function to convert the value into dot notation .. ??

codingfreak
  • 4,467
  • 11
  • 48
  • 60
  • 2
    Just a warning, inet_ntoa is deprecated - you should be using inet_ntop() or inet_pton() instead. – Salami Mar 25 '10 at 06:52
  • 1
    inet_ntop() and inet_pton() are also deprecated as they don't support IPv6 scope identifiers. You should be using getaddrinfo() and getnameinfo() if you want IPv6 support. – Steve-o Mar 25 '10 at 08:00
  • @codingfreak, whatever is setting your mask is wrong. The value should be 00ffffff as per my answer. – paxdiablo Mar 25 '10 at 08:19

3 Answers3

5

The only thing that makes sense is that your assumption regarding all the addresses being in network byte order is incorrect.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
4

Well, given that it works for your non-mask values (including the first which also has the high bit set), I'd be looking at what mask actually contains.

What is it when you print it out as a normal unsigned long? My bet is that mask is actually not the correct value:

printf ("%08x\t%08x\t%08x\n", dstAddr, gateWay, mask);

(assuming you have four-byte longs).

For example, this little program (compiled under Cygwin):

#include <stdio.h>

int main (void) {
    unsigned long dstAddr, gateWay, mask;
    dstAddr = 0x007aa8c0;
    gateWay = 0x00000000;
    mask    = 0x00ffffff;

    printf("%-15s %-15s %-15s\n",
        inet_ntoa (dstAddr),
        inet_ntoa (gateWay),
        inet_ntoa (mask));

    printf("%-15s ",  inet_ntoa (dstAddr));
    printf("%-15s ",  inet_ntoa (gateWay));
    printf("%-15s\n", inet_ntoa (mask));

    printf ("%08x%8s%08x%8s%08x\n",
        dstAddr, "",
        gateWay, "",
        mask);

    return 0;
}

outputs:

192.168.122.0   192.168.122.0   192.168.122.0
192.168.122.0   0.0.0.0         255.255.255.0
007aa8c0        00000000        00ffffff

Note that I had to separate my calls to inet_ntoa as it appears to use a static buffer. When I was doing it all within a single printf, it overwrote the contents of that buffer before any of them were printed, hence I only got the last one processed. I don't think that's happening in your case since you're getting different values.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Then your mask has been set incorrectly as I surmised. It should be 00ffffff, *not* ffffff00. You need to find out where that's being set and fix it. This is *not* a problem with inet_ntoa. – paxdiablo Mar 25 '10 at 08:18
  • I guess hex value for 255.255.255.0 is ffffff00 ?? check with the following tool - http://www.kloth.net/services/iplocate.php – codingfreak Mar 25 '10 at 08:23
  • You have to be aware of the byte order for both the network and your architecture (little or big-endian). Plug 192.168.122.0 into that same tool and you get C0A87A00 which is also the wrong order. On little-endian, the value 0x01020304 is stored in memory as 04,03,02,01. – paxdiablo Mar 25 '10 at 08:26
  • A small doubt, I am actually getting the values from kernel via netlink sockets .. so still big and little endian comes into picture ?? – codingfreak Mar 25 '10 at 08:28
  • Now you've moved beyond my areas of expertise, @codingfreak. All I can say is, that from empirical evidence, the mask is wrong. I've never used netlinks interface before. – paxdiablo Mar 25 '10 at 08:38
0

I also have the same problem with you. Use inet_ntop() and inet_pton() if you need it other way around. Do not use inet_ntoa(), inet_aton() and similar as they are deprecated and don't support ipv6. see link: convert Ip address int to string

Community
  • 1
  • 1
HungNM2
  • 3,101
  • 1
  • 30
  • 21