首先,看看我的代码,似乎我应该有它,但较小的子网掩码似乎总是返回true:
[root@hypervisor test]# ./test "99.99.99.99/8" 25.25.25.25
The given address is in the given cidr address
[root@hypervisor test]# ./test "99.99.99.99/16" 25.25.25.25
The given address is not in the given cidr address
[root@hypervisor test]# ./test "99.99.99.99/24" 25.25.25.25
The given address is not in the given cidr address
显然,最后两项检查是理想的。没有意外的阴性,只有假阳性。只有当我指定的子网掩码低于10时,它似乎才会失败:
[root@hypervisor test]# ./test "99.99.99.99/9" 25.25.25.25
The given address is in the given cidr address
[root@hypervisor test]# ./test "99.99.99.99/10" 25.25.25.25
The given address is not in the given cidr address
[root@hypervisor test]#
这是我定义的函数来完成工作(程序的其余部分基本上是返回代码的if/else, 1表示"给定IP在子网内"0表示"给定IP在子网外"):
int inSubnet(const char *cidrNotation, const char *needleAddress){
char subnetDesignation[25], strPad[25];
unsigned short int maskSize;
unsigned int startOfCidr=strlen(cidrNotation)-3;
unsigned long int subnetMask=0, givenIP, subnetAddress;
unsigned short int iter=0;
/* BEGIN sanitization of arguments */
// If they gave real CIDR clip it off the end and save it.
if (strstr(cidrNotation, "/")){
strcpy(strPad, cidrNotation);
maskSize=atoi( (strPad+startOfCidr+1) );
*(strPad+startOfCidr) = ' ';
strcpy(subnetDesignation, strPad);
// Otherwise assume 32-bit mask (effectively equates two specific addys)
} else {
strcpy(subnetDesignation, cidrNotation);
maskSize=32;
} /* END SANITIZATION */
// Generate subnet mask in network byte order
for (iter=1; iter<maskSize; iter++){
subnetMask=subnetMask<<1; // move mask right by one, fill LSB with zero
subnetMask++; // flip the one bit on
}
// Get subnetDesignation into binary form and
inet_pton(AF_INET, subnetDesignation, &subnetAddress);
subnetAddress=subnetAddress & subnetMask; // Ensure it matches the subnet's prefix no matter how it was given
inet_pton(AF_INET, needleAddress, &givenIP);
// Since all non-subnet bits are flipped, the result of an AND should be identical to the subnet address.
if ( (givenIP & subnetAddress) == subnetAddress)
return 1;
else
return 0;
}
看起来我非常接近完成项目的这一部分,我只是做了一些疏忽,我只是不知道为什么。
我不认为你可以安全地假设网络掩码总是占据字符串末尾的三个字符:
unsigned int startOfCidr=strlen(cidrNotation)-3;
例如,当您有/8
掩码时,您只需使用两个字符来指定它。(这可能也是为什么它适用于>= 10的所有内容。)尝试搜索/
字符,并解析从那里开始的网络掩码。