匹配子网列表

时间:2015-12-12 18:03:05

标签: c++ networking

有一个net-addr / mask形式的子网列表,例如 12.34.45.0/24 192.168.0.0/16 45.0.0.0/10 ...

想知道什么是判断给定IP地址是否在任何子网中的最佳方法。

以下是匹配的一些背景知识: 对于IP地址x,我们将其转换为整数。例如,11.12.13.14被转换为0x0b0c0d0e。对于掩码m,我们将其转换为整数,其前导(32-m)位为1,其余为0。

检查IP x是否在子网A / m中,
我们只需要检查(x&m) == (A&m)

好奇什么是快速匹配一系列子网的数据结构或功能。当然,我们可以循环浏览子网,但效率不高。

4 个答案:

答案 0 :(得分:1)

创建一个树,其中每个级别代表IP地址的n位。在每个级别存储子网,以使掩码位数在n * leveln * (level +1)之间。因此,例如,当n = 4时,每个节点有16个子节点。因此,如果您正在测试11.12.13.14(== 0x0b0c0d0e),您可以像这样走树:

0 -> b -> 0 -> c -> 0 -> d -> 0 -> e

在节点上,您可以跟踪具有相应大小的子网。我的意思是:0级应该有子网/ 1到/ 4(含),1级应该有子网/ 5到/ 8,依此类推到/ 29到/ 32。请注意,/ 0匹配所有内容,因此在数据结构中没用。

要在树中搜索,请将IP分组为n位(在我的示例4中)。下降到与前n位匹配的第一级并测试该级别上的所有子网。如果未找到,则下降到与下一个n位匹配的下一级别。

这样,您必须测试每个2 ^ n子网的最大32 / n级别。对于n = 4,您必须测试8个级别,每个级别最多16个子网。这很快就完成了。

澄清:节点是一个子网,例如(十六进制,一位是半字节,即4位):0a.5a.00.00 / 16。此节点的父节点将是包含此子网的子网:例如:0a.50.00.00 / 12。朝向子节点的边缘可以解释为:"包含",如:"该(父)子网包含由子节点"表示的子网。要使此树包含所需的所有子网,您可能必须插入节点,这些节点表示不在列表中的子网。因此,请将这些节点标记为辅助节点,以便您知道在搜索此树时,您知道其后面有更多特定的子网,但节点本身不是您要检查的子网列表的一部分。您只应添加直接在列表中的这些节点,以及所有父节点,以使节点在树结构中可访问。

以下是关于我如何看待它的struct

struct subnet_tree_node
{
    uint_32 ip;  // 32 bit IP address
    subnet_tree_node *children;
    uint_8 number_of_children;
    uint_8 mask; // number of bits for this subnet
    uint_8 valid; // wether this node is valid or auxiliary
}

答案 1 :(得分:1)

因此,您已确定的性能 是一个问题。

  • 将每个netmask / addr对视为一对IP地址:First valid,last-valid。
  • 让我们假设last-valid总是很奇怪(不确定这对于/ 32网络是否真实 - 但这真的很奇怪)。
  • 构造这些IP地址的排序向量。 (如果网络重叠或任何愚蠢的事情,请进行投诉。)
  • 使用某种二进制文件在向量中搜索目标IP地址。
  • 如果IP地址在向量中,则a)wierd; b)在其中一个子网中。
  • 如果IP地址不在向量中且下面的值是偶数 - 它在子网中。如果下面的值是奇数,则它不在子网中。

答案 2 :(得分:0)

您是否有任何证据表明性能存在问题? 只有2 ^ 24个子网(嗯,你可以拥有/ 28个子网,但它们通常是组织内部的,所以即使组织有A类网络,仍然只有2 ^ 24他们)。

进行1600万and次比较并且不需要时间。

保持简单(直到你真的必须做得更好)。

答案 3 :(得分:0)

感谢这里的讨论,他们从这个解决方案中获得了灵感。

首先,由于失去了一般性,我们假设子网中没有一个覆盖另一个子网(或者我们只删除较小的子网)。

每个子网都被视为一个区间[subnet_min,subnet_max]。

我们只需要将所有子网组织成二叉树,每个节点都是一对(subnet_min,subnet_max)。当搜索IP时,它就像仅基于subnet_min的常规二进制搜索一样遍历树,目的是找到具有subnet_min的节点在< =给定IP的所有subnet_min中最大。找到此节点后,我们检查节点的subnet_max是否大于给定的IP。如果是这样,子网将覆盖给定的IP,否则,我们可以说此节点中的子网不包含此IP,任何子网也不会覆盖该IP。

假设两个子网中没有一个相互包含,保证最后一点。