在给定CIDR表示法的情况下几乎可以确定子网成员资格,但会得到意外结果

时间:2013-06-03 20:56:19

标签: c linux networking

首先,查看我的代码似乎我应该拥有它但是较小的子网掩码似乎总是返回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返回代码,一个在“给定IP在子网中”,“给定IP在子网之外”为零):< / p>

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) = '\0';
          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;

}

看起来我非常接近让项目的这一部分完成,我只是做了某种疏忽,我只是错过了某种方式。

1 个答案:

答案 0 :(得分:2)

我认为您不能安全地假设网络掩码总是占用字符串末尾的三个字符:

unsigned int startOfCidr=strlen(cidrNotation)-3;

例如,如果您有/8掩码,则只能使用两个字符来指定它。 (这也可能是它适用于所有&gt; = 10的原因。)尝试搜索/字符并从那里开始解析网络掩码。