« May 2008
SunMonTueWedThuFriSat
    
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
       
Today
XML

Tom Haynes

loghyr.com
excfb.com

Blogs to Gander At

Navigation

Editing

AllMarks

Referers

Today's Page Hits: 211

Powered by Roller Weblogger.

statcounter.com

clustrmaps.com

Locations of visitors to this page

technorati.com

www.alesti.org

Add to Alesti RSS Reader

South Park as I was 10 years ago

South Park Fantasy

South Park today

South Park Reality

I have more hair and it isn't so grey. :->

10 years ago, really

Toon Tom

Today, literally

Tom Today

Site notes

This page validates as XHTML 1.0, and will look much better in a browser that supports web standards, but it is accessible to any browser or Internet device. It was created using techniques detailed at glish.com/css/.

« Wrapping up the... | Main | Simple policy evalua... »
20080121 Monday January 21, 2008
theShepler asks about inet_ntoa

theShepler asked me offline why I wasn't looking at inet_ntoa(3SOCKET) for Reversing a network address from an uint_t. His email was dry, but I think there was a "D'oh!" in there somewhere.

I had considered those routines, but I went with the stuff in mountd because for the standalone, we don't have sockets being attached. In the finished product, I'll be looking at this. Also, since I will need to support IPv6, I'll have more need to not be doing my own parsing. But for right now, I'm going to proceed without IPv6 and without inet_aton(3SOCKET).

Okay, I did two things with the little network parsing code:

And here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*
 * http://infolab.stanford.edu/~manku/bitcount/bitcount.html
 */
int
spe_bitcount (unsigned int n)     
{
        int count = 8 * sizeof(int) ;
        n ^= (unsigned int) -1 ;
        while (n) {
                count-- ;
                n &= (n - 1) ;
        }

        return (count);
}


int
main (int argc, char *argv[])
{
        char    *p = argv[1];
        char    *junk;
        uint_t  addr = 0, mask = 0;
        uint_t  rev;
        int     i;
        int     shift;
        int     t;
        char    sep = ' ';

        unsigned char   b = 0;

        for (i = 0; i < 4; i++) {
                t = strtol(p, &junk, 10);
                if (junk && junk[0] == '/' && i == 3) {
                        b = 1;
                } else if (junk && junk[0] != '.' && junk[0] != '\0') {
                        fprintf(stderr, "%s is wrong in the %d octet,"
                                " %s has non-digits as |%s|\n", argv[1],
                                i+1, p, junk);
                        exit (-1);
                } else if (t > 255 || t < 0) {
                        fprintf(stderr, "%s is wrong in the %d octet,"
                                " %d is out of range\n", argv[1],
                                i+1, t);
                        exit (-1);
                }

                addr |= t << ((3-i) * 8);
                p = strchr(p, '.');
                if (p == NULL)
                        break;
                p++;
        }

        if (b) {
                p = &junk[1];   /* advance over '/' */
                t = strtol(p, &junk, 10);

                if (junk && junk[0] != '\0') {
                        fprintf(stderr, "%s is wrong in the netmask,"
                                " %s has non-digits as |%s|\n", argv[1],
                                p, junk);
                        exit (-1);
                } else if (t < 0 || t > 32) {
                        fprintf(stderr, "%s is wrong in the netmask,"
                                " %d is out of range\n", argv[1], t);
                        exit (-1);
                }

                mask = t ? ~0 << ((sizeof (struct in_addr) * NBBY) - t) : 0;
        } else {
                if ((addr & 0x00ffffff) == 0)
                        mask = 0xff000000;
                else if ((addr & 0x0000ffff) == 0)
                        mask = 0xffff0000;
                else if ((addr & 0x000000ff) == 0)
                        mask = 0xffffff00;
                else
                        mask = 0xffffffff;
        }

        printf("%s yields %u (%u) and that reverse maps to ", argv[1],
                addr, mask);

        for (i = 0; i < 4; i++) {
                shift = ((3-i) * 8);

                rev = (addr & (0xff << shift)) >> shift;

                printf("%c%u", sep, rev);
                sep = '.';
        }

        sep = '(';
        t = 0;
        for (i = 0; i < 4; i++) {
                shift = ((3-i) * 8);

                rev = (mask & (0xff << shift)) >> shift;

                printf("%c%u", sep, rev);
                sep = '.';
        }

        t = spe_bitcount(mask);
        printf(" - %u)\n", t);

        return (0);
}

And some test runs:

% ./a.out 192.168.2.0/23
192.168.2.0/23 yields 3232236032 (4294966784) and that reverse maps to  192.168.2.0(255.255.254.0 - 23)
% ./a.out 192.168.2.0/24
192.168.2.0/24 yields 3232236032 (4294967040) and that reverse maps to  192.168.2.0(255.255.255.0 - 24)
% ./a.out 192.168.2.0/31
192.168.2.0/31 yields 3232236032 (4294967294) and that reverse maps to  192.168.2.0(255.255.255.254 - 31)
% ./a.out 192.168.2.0/32
192.168.2.0/32 yields 3232236032 (4294967295) and that reverse maps to  192.168.2.0(255.255.255.255 - 32)
% ./a.out 192.168.2.0/0
192.168.2.0/0 yields 3232236032 (0) and that reverse maps to  192.168.2.0(0.0.0.0 - 0)
% ./a.out 192.168.2.0/1
192.168.2.0/1 yields 3232236032 (2147483648) and that reverse maps to  192.168.2.0(128.0.0.0 - 1)
% ./a.out 192.168.2.0/8
192.168.2.0/8 yields 3232236032 (4278190080) and that reverse maps to  192.168.2.0(255.0.0.0 - 8)
% ./a.out 192.168.2.0/33
192.168.2.0/33 is wrong in the netmask, 33 is out of range

I just need to stuff this code into my prototype.


Originally posted on Kool Aid Served Daily
Copyright (C) 2008, Kool Aid Served Daily

Trackback URL: http://blogs.sun.com/tdh/entry/theshepler_asks_about_inet_ntoa
Comments:

If the interfaces unsatisfactory, you could have
copied the source and made updates instead of
starting from scratch. :-)

Posted by Spencer on January 22, 2008 at 03:01 PM CST #

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed
Copyright (C) 2007, Kool Aid Served Daily