服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > 数据库技术 > Oracle技术 > Oracle开发 > 查看文档

用utl_inaddr包获取已经连接用户的ip地址

【赛迪网-it技术报道】许多人都知道,通过sys_context函数可以获得部分信息,当前用户的ip等信息则可以通过下面的命令来进行获取:

sql> select sys_context('userenv','host') from dual; 
sys_context('userenv','host')
---------------------------------------------------
workgroup\gqgai

sql> select sys_context('userenv','ip_address') from dual;

sys_context('userenv','ip_addr
---------------------------------------------------
172.16.34.20

假如你需要获取其它session的地址等信息,sys_context函数则只能通过logon触发器来完成。

在没有触发器记录的前提下,你可以通过utl_inaddr package来实现。

下面具体介绍一下utl_inaddr包获取ip等信息的工作原理。

首先,在数据库中进行下面的查询:

[oracle@jumper oracle]$ sqlplus "/ as sysdba"

sql*plus: release 9.2.0.4.0 - production on wed oct 25 11:24:22 2006

copyright (c) 1982, 2002, oracle corporation. all rights reserved.


connected to:
oracle9i enterprise edition release 9.2.0.4.0 - production
with the partitioning option
jserver release 9.2.0.4.0 - production

sql> !
[oracle@jumper oracle]$ ps -ef|grep sql
oracle 14700 14663 1 11:24 pts/0 00:00:00 sqlplus 
oracle 14732 14702 0 11:24 pts/0 00:00:00 grep sql
[oracle@jumper oracle]$ ps -ef|grep lo
oracle 14701 14700 0 11:24 ? 00:00:00 oracleeygle 

(description=(local=yes)(address=(protocol=beq)))
oracle 14734 14702 0 11:24 pts/0 00:00:00 grep lo
[oracle@jumper oracle]$ exit
exit

sql> select utl_inaddr.get_host_address('www.anysql.net') from dual;

utl_inaddr.get_host_address('www.anysql.net')
---------------------------------------------------------
208.113.151.109

linux系统中,你可以通过strace跟踪此进程,得到下面的堆栈信息:

[oracle@jumper oracle]$ strace -p 14701
process 14701 attached - interrupt to quit
read(7, "\0\313\0\0\6\0\0\0\0\0\3^
\10a\200\0\0\0\0\0\0@\342\22\10"..., 2064) = 203
gettimeofday({1161746697, 269895}, null) = 0
getrusage(rusage_self, {ru_utime={0, 30000}, 
ru_stime={0, 10000}, ...}) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
gettimeofday({1161746697, 270542}, null) = 0
gettimeofday({1161746697, 270670}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
gettimeofday({1161746697, 271614}, null) = 0
gettimeofday({1161746697, 271748}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
gettimeofday({1161746697, 272347}, null) = 0
gettimeofday({1161746697, 272699}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
gettimeofday({1161746697, 272989}, null) = 0
gettimeofday({1161746697, 273140}, null) = 0
gettimeofday({1161746697, 273273}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 10000}, ...}) = 0
gettimeofday({1161746697, 273771}, null) = 0
gettimeofday({1161746697, 275526}, null) = 0
getpid() = 14701
open("/etc/resolv.conf", o_rdonly) = 12
fstat64(12, {st_mode=s_ifreg|0644, st_size=46, ...}) = 0
mmap2(null, 4096, prot_read|prot_write, 
map_private|map_anonymous, -1, 0) = 0xb6fba000
read(12, "search hurray.com.cn\nnameserver "..., 4096) = 46
read(12, "", 4096) = 0
close(12) = 0
munmap(0xb6fba000, 4096) = 0
socket(pf_unix, sock_stream, 0) = 12
connect(12, {sa_family=af_unix, 
path="/var/run/.nscd_socket"}, 
110) = -1 enoent (no such file or directory)
close(12) = 0
open("/etc/host.conf", o_rdonly) = 12
fstat64(12, {st_mode=s_ifreg|0644, st_size=17, ...}) = 0
mmap2(null, 4096, prot_read|prot_write, 
map_private|map_anonymous, -1, 0) = 0xb6fba000
read(12, "order hosts,bind\n", 4096) = 17
read(12, "", 4096) = 0
close(12) = 0
munmap(0xb6fba000, 4096) = 0
futex(0xb71a1a20, futex_wake, 2147483647) = 0
open("/etc/hosts", o_rdonly) = 12
fcntl64(12, f_getfd) = 0
fcntl64(12, f_setfd, fd_cloexec) = 0
fstat64(12, {st_mode=s_ifreg|0644, st_size=175, ...}) = 0
mmap2(null, 4096, 
prot_read|prot_write, 
map_private|map_anonymous, -1, 0) = 0xb6fba000

read(12, "# do not remove the following li"..., 4096) = 175

read(12, "", 4096) = 0
close(12) = 0
munmap(0xb6fba000, 4096) = 0
open("/opt/oracle/product/9.2.0/lib/libnss_dns.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/tls/libnss_dns.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/i686/libnss_dns.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/libnss_dns.so.2", o_rdonly) = 12
read(12, "\177elf\1\1\1\0\0\0\0\0\0\0\0
\0\3\0\3\0\1\0\0\0\240\16"..., 512) = 512
fstat64(12, {st_mode=s_ifreg|0755, st_size=18632, ...}) = 0
old_mmap(null, 17100, prot_read
|prot_exec, map_private, 12, 0) = 0xb6fb6000
old_mmap(0xb6fba000, 4096, prot_read|prot_write, 
map_private|map_fixed, 12, 0x3000) = 0xb6fba000
close(12) = 0
open("/opt/oracle/product/9.2.0/lib/libresolv.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/tls/libresolv.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/i686/libresolv.so.2", 
o_rdonly) = -1 enoent (no such file or directory)
open("/lib/libresolv.so.2", o_rdonly) = 12
read(12, "\177elf\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320
(\0"..., 512) = 512
fstat64(12, {st_mode=s_ifreg|0755, st_size=76508, ...}) = 0
old_mmap(null, 73604, 
prot_read|prot_exec, map_private, 12, 0) = 0xb6fa4000
old_mmap(0xb6fb3000, 4096, prot_read|prot_write, 
map_private|map_fixed, 12, 0xf000) = 0xb6fb3000
old_mmap(0xb6fb4000, 8068, prot_read|prot_write, 
map_private|map_fixed|map_anonymous, -1, 0) = 0xb6fb4000
close(12) = 0
socket(pf_inet, sock_dgram, ipproto_ip) = 12
connect(12, {sa_family=af_inet, sin_port=htons(53), 
sin_addr=inet_addr("208.113.151.109")}, 28) = 0
send(12, "\324#\1\0\0\1\0\0\0\0\0\0\3www
\5anysql\3com\0\0\1\0\1", 31, 0) = 31
gettimeofday({1161746697, 286025}, null) = 0
poll([{fd=12, events=pollin, revents=pollin}], 1, 5000) = 1
ioctl(12, fionread, [74]) = 0
recvfrom(12, "\324#\
201\200\0\1\0\1\0\1\0\0\3www\5anysql\3com\0\0\1\0"..., 1024, 0, 
{sa_family=af_inet, sin_port=htons(53), 
sin_addr=inet_addr("208.113.151.109")}, [16]) = 74
close(12) = 0
gettimeofday({1161746697, 290245}, null) = 0
getrusage(rusage_self, 
{ru_utime={0, 40000}, ru_stime={0, 20000}, ...}) = 0
getrusage(rusage_self, 
{ru_utime={0, 40000}, ru_stime={0, 20000}, ...}) = 0
gettimeofday({1161746697, 291553}, null) = 0
write(10, "\2\275\0\0\6\0\0\0\0\0\20\31\266\344\217\
3700\320\341s"..., 701) = 701
read(7, "\0\215\0\0\6\0\0\0\0\0\3^\t@\0\0\0\1\0\0\0
\0\0\0\0\0\0"..., 2064) = 141
gettimeofday({1161746697, 294898}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 20000}, ...}) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 20000}, ...}) = 0
gettimeofday({1161746697, 295496}, null) = 0
getrusage(rusage_self, {ru_utime={0, 40000}, 
ru_stime={0, 20000}, ...}) = 0
gettimeofday({1161746697, 295847}, null) = 0
gettimeofday({1161746697, 295981}, null) = 0
lseek(9, 1024, seek_set) = 1024
read(9, "\30\0$\0007\0@\0j\0v\0`\0i\0t\0~\0\
232\0\245\0\320\0\330"..., 512) = 512
lseek(9, 47104, seek_set) = 47104
read(9, "\f\0^\5\0\0p\0x\5\0\0\214\0y\5\0\0\
250\0z\5\0\0\313\0{"..., 512) = 512
gettimeofday({1161746697, 297024}, null) = 0
write(10, "\0\202\0\0\6\0\0\0\0\0\4\1\0\0\0\1\
1\0\0\0{\5\0\0\0\0\1"..., 130) = 130
read(7, 
process 14701 detached

在此信息中,你可以发现oracle顺序访问了下面的文件来完成地址定位:

open("/etc/resolv.conf", o_rdonly) = 12
open("/etc/host.conf", o_rdonly) = 12
open("/etc/hosts", o_rdonly) = 12

首先,需要获取域名解析服务器,然后再根据host.conf文件确定解析顺序,因为缺省hosts文件是优先的,又继续读取/etc/hosts文件。

假如hosts文件存在解析关系,就会返回信息;假如不存在的话,则继续问询dns服务器,获得解析地址,如果不能解析,则会出现错误:

sql> select utl_inaddr.get_host_address('www.a.com') from dual;
select utl_inaddr.get_host_address('www.a.com') from dual
*
error at line 1:
ora-29257: host www.a.com unknown
ora-06512: at "sys.utl_inaddr", line 35
ora-06512: at "sys.utl_inaddr", line 40
ora-06512: at line 1

综上所述,大家可以发现utl_inaddr的数据获取已经不再依赖数据库信息,而sys_context的信息获取依然来自数据库的内部。

扫描关注微信公众号