在进行网络程序的时候避免不了对给定IP是否跨子网段进行判断。相关原理倒是简单, 贴出相关代码:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define ALL_BIT 32 /* ip address have 32 bits */
/*
** description: juge the ip_a and ip_b is in the same subnet or not
** this functio is used IPv4 only, and did not check the input parameter's
** correctness, so make sure the value of parameter before call it
** para: sub_mask is a decimal subnet mask , not dotted decimal
** ip_a/ip_b: the ip address string, in dotted decimal
** return: 0 for the same, -1 for the not
*/
int same_subnet (int sub_mask, char *ip_a, char *ip_b)
{
int mask = 0xFFFFFFFF;
mask = mask << (ALL_BIT - sub_mask);
double cnt_a = 0.0;
double cnt_b = 0.0;
double tmp = 0.0;
char *token = NULL;
int i = 3;
for (token = strtok (ip_a, "."); token != NULL; token = strtok (NULL, ".")) {
tmp = atoi (token);
tmp = tmp * pow (256, i--); /* what dose this mean? do you understand */
cnt_a += tmp;
}
i = 3; /* reset i */
for (token = strtok (ip_b, "."); token != NULL; token = strtok (NULL, ".")) {
tmp = atoi (token);
tmp = tmp * pow (256, i--);
cnt_b += tmp;
}
unsigned long mask_a = (unsigned long)cnt_a;
unsigned long mask_b = (unsigned long)cnt_b;
//printf ("mask_a %u\tmask_b %u\n", mask_a, mask_b);
mask_a &= mask; /* get the ip's netmask for compare */
mask_b &= mask;
//printf ("mask_a %u\tmask_b %u\n", mask_a, mask_b);
if (mask_a == mask_b)
return 0;
else
return -1;
}
/*
** test code
*/
int main (int argc, char **argv)
{
int i = same_subnet (atoi (argv[1]), argv[2], argv[3]);
printf ("%s subnet\n", i == 0? "same":"not same");
return 0;
}
代码在gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)编译通过。