群里有人提到,想在系统登录数据库中不仅记录客户端的IP地址,还想记录MAC地址。我网上搜了些资料,初步小结如下。
ORACLE 使用SYS_CONTEXT ('USERENV', 'IP_ADDRESS') ,可以获得客户端的IP地址,而从IP地址转为MAC地址没有现成的PL/SQL函数。网上的一个例子就是通过调用nbtstat
-A
整个方法其实就是使用JAVA存储过程。
第一步: 建立GetMacFromIP.JAVA 文件,内容如下:
注意,这个JAVA 文件名必须和类名一致。
点击(此处)折叠或打开
-
import java.io.*;
-
public class GetMacFromIP{
-
/**
-
* 获取MAC地址
-
*/
-
public static String getMac(String ip) {
-
String str = “”;
-
String macAddress = “”;
-
try {
-
Process p = Runtime.getRuntime().exec(“nbtstat -A ” + ip);
-
InputStreamReader ir = new InputStreamReader(p.getInputStream());
-
LineNumberReader input = new LineNumberReader(ir);
-
for (int i = 1; i < 100; i++) {
-
str = input.readLine();
-
if (str != null) {
-
if (str.indexOf(“MAC Address”) > 1) {
-
macAddress = str.substring(str.indexOf(“MAC Address”) + 14, str.length());
-
break;
-
}
-
}
-
}
-
} catch (IOException e) {
-
e.printStackTrace(System.out);
-
}
-
return macAddress;
- }
第二步: 编译JAVA文件
javac GetMacFromIP.java
这个命令在操作系统命令行下执行,确保你安装了JDK , 如果javac 不在PATH 路径中,则使用带路径名的javac。 执行后生产GetMacFromIP.class
第三步: 把JAVA类装载到数据库。
loadjava -user sys/oracle GetMacFromIP.class
使用SYS 用户主要是简单考虑,不用赋权。但实际中,最好不用SYS 用户
第四步: 创建ORACLE 函数:
点击(此处)折叠或打开
-
CREATE OR REPLACE FUNCTION GetMac(IP VARCHAR2) RETURN VARCHAR2
-
AS LANGUAGE JAVA
- NAME \'GetMacFromIP.getMac(java.lang.String) return java.lang.String\';
第五步:测试下这个函数是否正常运行,如:
SQL> select GetMac('21.104.129.161') from dual;
GETMAC('21.104.129.161')
-------------------------------------------------------------------
00-0C-29-15-88-5C
1 row selected.
SQL> select GetMac('21.98.6.83') from dual;
GETMAC('21.98.6.83')
-------------------------------------------------------------------
44-37-E6-4F-6D-FD
1 row selected.
第六步:具体操作。
点击(此处)折叠或打开
-
-- 先建立日志表
-
Create table logon_log
-
( logon_time date ,
-
logon_ip varchar2(15),
-
logon_mac varchar2(17)
-
);
-
-
-- 建立登录触发器
-
CREATE OR REPLACE TRIGGER SYS.trg_work_log
-
AFTER LOGON
-
ON DATABASE
-
BEGIN
-
IF SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\') IS NOT NULL
-
THEN
-
INSERT INTO logon_log
-
VALUES (
-
SYSDATE,
-
SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\'),
-
GetMac (SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\')));
-
-
COMMIT;
-
END IF;
- END;
注意:如果是不带服务名在本机登录,SYS_CONTEXT ('USERENV', 'IP_ADDRESS')返回的是空值,我假设不用记录。当然也可以修改程序去记录。
第七步: 正式测试
我选择几台机器登录后,可以查询到:
SQL> select * from logon_log;
LOGON_TIM LOGON_IP LOGON_MAC
--------- --------------- -----------------
08-NOV-14 21.104.129.160 00-0C-29-B1-EF-06
08-NOV-14 21.98.6.83 44-37-E6-4F-6D-FD
08-NOV-14 21.98.6.83 44-37-E6-4F-6D-FD
3 rows selected.