On 2011-01-14 15:52, Michel Esber wrote:
Quote:
All,
DB2 LUW v9.5 FP 5.
Has anyone implemented or could point articles to an UDF that returns
the Subnet ID of a (IP, NetMask) pair?
Examples:
(IP = 192.168.2.70, NetMask = 255.255.255.0) -> Expected UDF result
is 192.168.2.0 / 24
(IP = 172.17.206.235, NetMask = 255.255.224.0) -> Expected UDF result
is 172.17.192.0 / 19
The UDF should return exactly what http://www.subnet-calculator.com
does.
Any links/suggestions?
Thanks, |
Michel, I tossed together a sketch, perhaps you can make something out
of it. I've used 2 helper functions:
create function mask_length(ip smallint)
returns smallint
return case ip when 255 then 8
when 254 then 7
when 252 then 6
when 248 then 5
when 240 then 4
when 224 then 3
when 192 then 2
when 128 then 1
else 0
end @
create function split_ip(ip varchar(15))
returns table (octet smallint, ipval smallint)
begin atomic
declare p1 smallint;
declare p2 smallint;
declare p3 smallint;
set p1 = locate('.', ip, 1);
set p2 = locate('.', ip, p1+1);
set p3 = locate('.', ip, p2+1);
return values(1, smallint(substr(ip,1,p1-1)))
union all
values(2, smallint(substr(ip,p1+1,p2-p1-1)))
union all
values(3, smallint(substr(ip,p2+1,p3-p2-1)))
union all
values(4, smallint(substr(ip,p3+1))) ;
end @
Example:
db2 "select * from table(split_ip('172.17.206.235')) order by octet"
OCTET IPVAL
------ ------
1 172
2 17
3 206
4 235
This would probably be a good time to dig into string aggregation via
xml functions, but I don't have the time to figure that out now:
create function subnet_id (ip varchar(15), mask varchar(15))
returns varchar (20)
return with tmp as (
select x.octet, bitand(x.ipval, y.ipval) as bitwise,
mask_length(y.ipval) as mask_length
from table(split_ip(ip)) x
join table(split_ip(mask)) y
on x.octet = y.octet
) select rtrim(char(t1.bitwise)) || '.' ||
rtrim(char(t2.bitwise)) || '.' ||
rtrim(char(t3.bitwise)) || '.' ||
rtrim(char(t4.bitwise)) || '/' ||
rtrim(char((select sum(mask_length) from tmp)))
from tmp t1, tmp t2, tmp t3, tmp t4
where t1.octet = 1
and t2.octet = 2
and t3.octet = 3
and t4.octet = 4 @
Example:
db2 "values subnet_id('172.17.206.235', '255.255.224.0')"
1
--------------------
172.17.192.0/19
1 record(s) selected.
db2 "values subnet_id('192.168.2.70', '255.255.255.0')"
1
--------------------
192.168.2.0/24
Tested on:
db2level
DB21085I Instance "db2inst1" uses "32" bits and DB2 code release
"SQL09072"
with level identifier "08030107".
Informational tokens are "DB2 v9.7.0.2", "s100514", "IP23088", and Fix Pack
"2".
Product is installed at "/opt/ibm/db2/V9.7".