【发布时间】:2015-04-20 04:11:35
【问题描述】:
我一直致力于使用在 SQL Server 2012 实例上运行的 T-SQL 从 IPv4 和 IPv6 地址范围生成 CIDR。通常我们的应用程序(在数据库之外)负责计算 CIDR,但我目前需要在数据库中进行 CIDR 计算。由于 IPv6 太大而无法存储在 bigint 数据类型中,我们将 IP 地址存储为 binary(4) 或 binary(16)。
计算 IPv4 范围的路由前缀虽然有点难看,但相对简单:
declare @ipv4_begin binary(4)
,@ipv4_end binary(4)
set @ipv4_begin = 0xC0A80000 -- '192.168.000.000'
set @ipv4_end = 0xC0A8FFFF -- '192.168.255.255'
select 32 - LOG(
Cast(@ipv4_end As bigint)
- Cast(@ipv4_begin As bigint) + 1, 2
) as ipv4_route_prefix
遗憾的是,为 IPv6 修改的相同查询不起作用。它不起作用的原因是因为 IPv6 收件人大于 bigint 数据类型中可以存储的内容(我们使用 binary(4) 和 binary(16) 进行存储的原因):
declare @ipv6_begin binary(16)
,@ipv6_end binary(16)
set @ipv6_begin = 0xFC000000000000000000000000000000 -- fc00::
set @ipv6_end = 0xFC00000000000000FFFFFFFFFFFFFFFF -- fc00::ffff:ffff:ffff:ffff
-- This will cause error: 'An invalid floating point operation occurred.'
select 128 - LOG(
Cast(@ipv6_end As bigint)
- Cast(@ipv6_begin As bigint) + 1, 2
) as ipv6_route_prefix
除了不可靠的按位运算(最终不起作用)之外,我还没有想出任何可以在数据库中进行此计算的方法。
是否可以根据 T-SQL 中的 IPv6 地址范围计算 IPv6 CIDR 的路由前缀?
【问题讨论】:
-
虽然上述示例是简单的选择语句,但我对 SQL 服务器函数、公用表表达式、按位运算或任何其他可行的解决方案完全开放。
-
也许您可以查看一些 C# 解决方案(ipnetwork.codeplex.com 和 stackoverflow.com/q/310599/1080354)并尝试使用 CLR 函数在 SQL Server 中实现它们?
-
@gotqn 我正在使用共享数据库服务器实例。因此,我的 DBA 对添加 CLR 类型犹豫不决(这是理所当然的)。那就是说IPNetwork Utility 虽然有用(我以前用过)不支持 IPv6。
标签: sql-server tsql sql-server-2012 network-programming ipv6