UTLINET - pure PL/SQL IP address object implementation in Oracle database.

Download
It supports IPv4 and IPv6 address scheme.
If you familiar with PostgreSQL inet/cidr types, you will find this code functionality repeating those. Please see PostgreSQL documentation regarding function descriptions.
Here some examples:
SQL> select inet('10.0.0.1') from dual;

INET('10.0.0.1')(HOST_LO, HOST_HI, MASKLEN, VERSION)
----------------------------------------------------------------------------------------------------
INET(167772161, 0, 32, 4)

SQL> select inet('af:67a0:1299::7800:650a:5/120') from dual;

INET('AF:67A0:1299::7800:650A:5/120')(HOST_LO, HOST_HI, MASKLEN, VERSION)
----------------------------------------------------------------------------------------------------
INET(1.3194E+14, 4.9372E+16, 120, 6)

SQL> select inet('81.25.6.60/12').netmask().to_string() from dual;

INET('81.25.6.60/12').NETMASK().TO_STRING()
----------------------------------------------------------------------------------------------------
255.240.0.0

SQL> select inet('80.250.12.50/22').broadcast().to_string() from dual;

INET('80.250.12.50/22').BROADCAST().TO_STRING()
----------------------------------------------------------------------------------------------------
80.250.15.255/22

To speed up select queries with widely used operations "contains" and "contained_within" one can use index type provided:
SQL> create table tab (val inet);

Table created.

SQL> set timin on
SQL> begin
    -- some example data
    for i in 1..10000 loop
    if trunc (dbms_random.value (1,25)) != 1 then
        execute immediate 'insert into tab values (:v)' using inet (
        trunc (dbms_random.value (1, 256)) || '.' ||
        trunc (dbms_random.value (1, 256)) || '.' ||
        trunc (dbms_random.value (1, 256)) || '.' ||
        trunc (dbms_random.value (1, 256)));
    else
        execute immediate 'insert into tab values (null)';
    end if;
    end loop;
end;
  2    3    4    5    6    7    8    9   10   11   12   13   14
 15  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:05.57
SQL> create index ind on tab (val) indextype is inet_idxtype;

Index created.

Elapsed: 00:00:09.33
SQL> set autotrace on explain
SQL> set linesize 100
SQL> select t.val.to_string() from tab t where inet_contained_within (t.val, inet ('10.0.0.0/8'))=1;

T.VAL.TO_STRING()
----------------------------------------------------------------------------------------------------
10.104.188.139
10.159.33.67
10.110.94.144
10.197.61.168
10.149.158.71
10.211.228.79
10.140.44.85
10.137.194.215
10.197.41.230
10.135.158.247
10.255.223.191

T.VAL.TO_STRING()
----------------------------------------------------------------------------------------------------
10.25.95.141
10.206.181.92
10.104.23.171
10.169.17.151
10.73.231.192
10.168.111.110
10.205.220.146
10.107.7.136
10.11.58.60
10.77.196.202
10.251.254.27

T.VAL.TO_STRING()
----------------------------------------------------------------------------------------------------
10.70.9.9
10.102.242.243
10.102.145.213
10.92.124.106
10.108.225.225
10.91.235.39
10.152.228.100
10.162.41.178
10.90.100.103
10.255.186.114
10.159.223.110

T.VAL.TO_STRING()
----------------------------------------------------------------------------------------------------
10.40.242.239
10.147.129.61
10.89.140.116
10.154.82.124

37 rows selected.

Elapsed: 00:00:00.04

Execution Plan
----------------------------------------------------------
Plan hash value: 667269868

------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |   100 |  5400 |     9   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB  |   100 |  5400 |     9   (0)| 00:00:01 |
|*  2 |   DOMAIN INDEX              | IND  |       |       |            |          |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SVA"."INET_CONTAINED_WITHIN"("T"."VAL","INET"."INET"('10.0.0.
              0/8'))=1)

Note
-----
   - dynamic sampling used for this statement

SQL>
Knowed issues:

1. Oracle BITAND function has black background, look at this:
SQL> select bitand (power (2, 64), power (2, 32) - 1) from dual;

BITAND(POWER(2,64),POWER(2,32)-1)
---------------------------------
                       4294967295
it should returns in 0, so because this function is widely used in this library, you can get unexpected results. This is spotted on some 9i and 10g databases.

2. If you get this:
SQL> create index ind on tab (val) indextype is inet_idxtype;
create index ind on tab (val) indextype is inet_idxtype
*
ERROR at line 1:
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-01031: insufficient privileges
ORA-06512: at "SVA.INET_IDXTYPE_IM", line 14
Try invoke "grant create table" on user.
And also for you to know: INET type functions add_, sub_ still not implemented.
Project's license is BSD license.
(c) telelvis {at} gmail.com
SourceForge.net Logo