/* This segment of code is capable, when supplied with the ip address
of the current interface (normally eth0)
a) finding the netmask and the braodcast of the interface
b) finding the locically available range of machines in the current network
c) building a structure of the current net segment layout
*/
d = (number >> 0) | 0xFFFFFF00;
c = (number >> 8) | 0xFFFFFF00;
b = (number >> 16) | 0xFFFFFF00;
a = (number >> 24) | 0xFFFFFF00;
/* now mask out the high 0xFFFFFF-- bits */
d -= 0xFFFFFF00;
c -= 0xFFFFFF00;
b -= 0xFFFFFF00;
a -= 0xFFFFFF00;
switch (place) {
case 1 : return (a); break;
case 2 : return (b); break;
case 3 : return (c); break;
case 4 : return (d); break;
default : perror("In decode, invalid arg[2]"); exit(1);
};
return(0); /* this is to shut up gcc -Wall
as we never actually get here */
}
struct range * calc(unsigned int ip, unsigned int netmask, unsigned int broadcast)
{
/* this is all bit pattern related */
unsigned int loop, copy, max_range, start, finish;
struct range *block;
block = (struct range *) calloc(1,sizeof(block));
/* work out how many 0's are in the netmask, some of my better logic 8) */
copy = netmask;
loop = 0 ;
while (copy % 2 != 1) {
copy = copy >> 1 ;
loop++;
}
loop--; /* went around the loop once to often */
max_range = 2 << loop;
start = (ip / max_range) * max_range;
finish = start + (max_range -1); /* blame the arabics! they invented the zero! */
#ifdef DEBUG
printf("start of network range is = (0x%x)\n", start);
printf("finish of network range is = (0x%x)\n", finish);
#endif
block -> start = start;
block -> finish = finish;
return (block);
}
char * ip_to_str(int encoded_ip)
{
/* damn,.. why isn't there a reverse for atoi? like itoa? */
char buffer[12]; /* just make sure it's big enuogh */
static char string[20];
struct range * describe_net(struct net_attrib *node)
{
struct range *range;
#ifdef DEBUG
char start[20]="", finish[20]=""; /* debugging at the end needs these */
/* allocate some memory for range even though it should
already be allocated when we attempt to access it */
range = (struct range *) calloc(1, sizeof(range));
range = calc(node -> ip,
node -> netmask,
node -> broadcast); /* find me the range of addresses for that network */
#ifdef DEBUG
printf("The ip range spans (%d) ip addresses\n", (range->finish - range->start));
printf("Running from (%s) - the network addreess (unusable)) to\n to (%s) - the network broadcast ip (unusable))\n",
ip_to_str(range->start), ip_to_str(range->finish));
#endif
return (range);
}
/* this #ifdef is is so I can link in these other code segments */
#ifndef NOMAIN
int main()
{
struct range *range;
struct net_attrib *net_desc;
unsigned int loop = 0;
char start[20], finish[20], test[20];
/* these would be supplied by a routine, which has used encode_ip */
/* to pass three int arguments */
/* here, we'll hard code it into the net_attrib struct */
/* now we call desc_net(net_desc) which will return the range structure */
/* which will also need decoding though -DDEBUG will force it to tell tales */
range = describe_net(net_desc);
printf("Start was (%s) and the finish is (%s)\n",
ip_to_str(range->start), ip_to_str(range->finish));
printf("-----------------------------------------------------------\n");
/* note the starting +1, you can not ping a network boundry, bad things happen */
/* this loop also shows very strongly the case for encoding the ip as an int */
for(loop = (range->start) +1 ; loop < (range->finish); loop++) {
translate(test, loop);
printf("test ip (%s) with ping packet\n", test);
}