ORACLE 中記錄客戶端MAC地址

guoge發表於2014-11-08

群裡有人提到,想在系統登入資料庫中不僅記錄客戶端的IP地址,還想記錄MAC地址。我網上搜了些資料,初步小結如下。

ORACLE 使用SYS_CONTEXT ('USERENV', 'IP_ADDRESS') ,可以獲得客戶端的IP地址,而從IP地址轉為MAC地址沒有現成的PL/SQL函式。網上的一個例子就是透過呼叫nbtstat -A  ,分析返回結果得到MAC 地址,這個方法適合Oracle 安裝在Windows 上,其實類UNIX 機器也可以實現,思路差不多。

整個方法其實就是使用JAVA儲存過程。

第一步: 建立GetMacFromIP.JAVA 檔案,內容如下:

 

注意,這個JAVA 檔名必須和類名一致。

點選(此處)摺疊或開啟

  1. import java.io.*;
  2.  public class GetMacFromIP{
  3.     /**
  4.      * 獲取MAC地址
  5.      */
  6.     public static String getMac(String ip) {
  7.     String str = “”;
  8.     String macAddress = “”;
  9.     try {
  10.         Process p = Runtime.getRuntime().exec(“nbtstat -A ” + ip);
  11.         InputStreamReader ir = new InputStreamReader(p.getInputStream());
  12.         LineNumberReader input = new LineNumberReader(ir);
  13.         for (int i = 1; i < 100; i++) {
  14.             str = input.readLine();
  15.             if (str != null) {
  16.                 if (str.indexOf(“MAC Address”) > 1) {
  17.                     macAddress = str.substring(str.indexOf(“MAC Address”) + 14, str.length());
  18.                     break;
  19.                 }
  20.             }
  21.         }
  22.     } catch (IOException e) {
  23.         e.printStackTrace(System.out);
  24.     }
  25.     return macAddress;
  26. }


第二步: 編譯JAVA檔案

javac GetMacFromIP.java

 

這個命令在作業系統命令列下執行,確保你安裝了JDK , 如果javac 不在PATH 路徑中,則使用帶路徑名的javac。  執行後生產GetMacFromIP.class

 

第三步:  把JAVA類裝載到資料庫。

loadjava -user sys/oracle GetMacFromIP.class

 

使用SYS 使用者主要是簡單考慮,不用賦權。但實際中,最好不用SYS 使用者

 

第四步: 建立ORACLE 函式:


點選(此處)摺疊或開啟

  1. CREATE OR REPLACE FUNCTION GetMac(IP VARCHAR2) RETURN VARCHAR2
  2.  AS LANGUAGE JAVA
  3.  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.

 

第六步:具體操作。


點選(此處)摺疊或開啟

  1. -- 先建立日誌表
  2. Create table logon_log
  3. ( logon_time date ,
  4.   logon_ip varchar2(15),
  5.   logon_mac varchar2(17)
  6.  );
  7.  
  8. -- 建立登入觸發器
  9. CREATE OR REPLACE TRIGGER SYS.trg_work_log
  10.    AFTER LOGON
  11.    ON DATABASE
  12. BEGIN
  13.    IF SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\') IS NOT NULL
  14.    THEN
  15.       INSERT INTO logon_log
  16.            VALUES (
  17.                      SYSDATE,
  18.                      SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\'),
  19.                      GetMac (SYS_CONTEXT (\'USERENV\', \'IP_ADDRESS\')));
  20.  
  21.       COMMIT;
  22.    END IF;
  23. 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.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9036/viewspace-1325636/,如需轉載,請註明出處,否則將追究法律責任。

相關文章