isc-dhcp-server的分配的地址列表在哪,linux/樹莓派做無線路由器怎么查看已連接設備


標題問題答案

/var/lib/dhcp/dhcpd.leases,這個文件記錄了所有isc-dhcp-server分配的IP地址信息

 

dhcpd.leases文件詳解:

# 推薦用 $ man dhcpd.leases 指令 查看詳細含義

lease 192.168.8.24 {
  starts 3 2016/05/18 10:48:59; # 分配地址的時間
  ends 3 2016/05/18 10:58:59; # 租約到期時間
  tstp 3 2016/05/18 10:58:59; # 租約到期時間
  cltt 3 2016/05/18 10:49:04; # 客戶端最后訪問時間
  binding state free; # 租約綁定狀態 狀態分別是 free 和 active
  hardware ethernet 30:3a:64:50:2d:32; # 客戶端mac地址
  uid "\0010:dP-2"; # 客戶端識別id
  set vendor-class-identifier = "MSFT 5.0";
}
lease 192.168.8.25 {
  starts 2 2016/06/14 04:23:16;
  ends 2 2016/06/14 04:33:16;
  cltt 2 2016/06/14 04:23:16;
  binding state free;
  next binding state free;
  rewind binding state free;
  hardware ethernet c0:ee:fb:25:82:92;
  client-hostname "android-50efd8d429a1278b"; # 客戶端主機名
}
lease 192.168.8.25 {
  starts 2 2016/06/14 04:28:08;
  ends 2 2016/06/14 04:38:08;
  cltt 2 2016/06/14 04:28:08;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet c0:ee:fb:25:82:92;
  client-hostname "android-50efd8d429a1278b";
}

 

 

你若對如何找這類文件感興趣,可以接着往下看v

軟件:isc-dhcp-server(以下簡稱IDS), python flask, hostapd 
平台:debian8 for arm(raspberry pi 樹莓派)
硬件:EP-N8508GS USB無線網卡(以下簡稱為無線網卡),樹莓派2B(以下簡稱PI)

目的:

         學習LINUX,制作一個基於網頁端管理的無線路由器(本文主要講怎么找DHCP的客戶端列表)。

         選修課大作業,非常感謝萬老師開這門課,讓我學到了很多linux的知識。

         主要思路:

      PI以任意方式通過有線網卡連接外網;

      PI通過無線網卡作為Wireless Access Point,用到軟件hostapd;

      PI安裝isc-dhcp-server作為DHCP服務器分配IPV4地址;

      PI配置IP table使通過AP連接可以訪問外網;

      配置網頁大部分已經完成,只是做功能補充,添加查看DHCP客戶端列表功能。

 

分析:

  DHCP由isc-dhcp-server控制,linux不自帶DHCP服務器,所以猜測,DHCP的客戶端都是由IDS記錄的。

  第一種情況,所有的記錄文件直接以文本文件的形式保存,文件命名是isc-dhcp-*,這種方法我們讀取查找起來最簡單;

  第二種情況,文本文件記錄,存放在*/isc-dhcp/*,讀取起來和上一種情況類似;

  第三種情況,用了sqlite存儲信息,被保存成*.db文件,這是讀取起來最麻煩的;

  第四種情況,DHCP客戶端信息放在內存中,其他程序無法讀取,如果是這樣的,那就基本無解了,但是想到世面上的路由器都有查看DHCP客戶端的功能,IDS這個軟件應該會把這信息記錄到本地文件吧。

 

無論是什么情況,首先得把存儲信息的文件找出來,執行以下查找文件的指令:

$ sudo find / -name 'isc-dhcp*' -type f

查找結果:  

pi@raspberrypi:~ $ sudo find / -name 'isc-dhcp*' -type f
/var/lib/dpkg/info/isc-dhcp-client.conffiles
/var/lib/dpkg/info/isc-dhcp-client.postrm
/var/lib/dpkg/info/isc-dhcp-server.postrm
/var/lib/dpkg/info/isc-dhcp-server.conffiles
/var/lib/dpkg/info/isc-dhcp-server.prerm
/var/lib/dpkg/info/isc-dhcp-server.list
/var/lib/dpkg/info/isc-dhcp-server.config
/var/lib/dpkg/info/isc-dhcp-client.md5sums
/var/lib/dpkg/info/isc-dhcp-server.templates
/var/lib/dpkg/info/isc-dhcp-server.postinst
/var/lib/dpkg/info/isc-dhcp-common.list
/var/lib/dpkg/info/isc-dhcp-client.list
/var/lib/dpkg/info/isc-dhcp-server.md5sums
/var/lib/dpkg/info/isc-dhcp-client.postinst
/var/lib/dpkg/info/isc-dhcp-client.preinst
/var/lib/dpkg/info/isc-dhcp-common.md5sums
/run/systemd/generator.late/isc-dhcp-server.service

看到’isc-dhcp-client.list’這個文件,欣喜若狂,莫非就這么被我找到了,查看了一下結果…

pi@raspberrypi:/var/lib/dpkg/info $ cat isc-dhcp-client.list 
/.
/var
/var/lib
/var/lib/dhcp
/sbin
/sbin/dhclient-script
/sbin/dhclient
/etc
/etc/dhcp
/etc/dhcp/dhclient.conf
/etc/dhcp/dhclient-exit-hooks.d
/etc/dhcp/dhclient-exit-hooks.d/debug
/etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes
/etc/dhcp/dhclient-enter-hooks.d
/etc/dhcp/dhclient-enter-hooks.d/debug
/usr
/usr/share
/usr/share/doc
/usr/share/doc/isc-dhcp-client
/usr/share/doc/isc-dhcp-client/copyright
/usr/share/doc/isc-dhcp-client/changelog.Debian.gz
/usr/share/doc/isc-dhcp-client/NEWS.Debian.gz
/usr/share/man
/usr/share/man/man5
/usr/share/man/man5/dhclient.conf.5.gz
/usr/share/man/man5/dhclient.leases.5.gz
/usr/share/man/man8
/usr/share/man/man8/dhclient-script.8.gz
/usr/share/man/man8/dhclient.8.gz

繼續,當查看到isc-dhcp-client.postrm這個文件時,漸漸開始明朗了起來,紅色的語句,應該就是初始化dhcp服務時,需要刪除的文件,那么就是本次dhcp服務的記錄文件,接下來就是查看這些文件。

pi@raspberrypi:/var/lib/dpkg/info $ cat isc-dhcp-client.postrm 
#!/bin/sh -e
#
#

if [ "$1" = "purge" ]; then
    # Remove lease database
    rm -f /var/lib/dhcp/dhclient*.leases
    rm -f /var/lib/dhcp/dhclient*.lease

    # Try to remove directory
    if [ -d /var/lib/dhcp ]; then
        rmdir --ignore-fail-on-non-empty /var/lib/dhcp/
    fi

    rmdir --ignore-fail-on-non-empty /etc/dhcp

fi

轉到 /var/lib/dhcp/ 可以看到有這樣一個文件,翻譯過來是dh客戶端.租約,猜想應該就是這個文件了:

pi@raspberrypi:/var/lib/dhcp $ ls -la dhclient*.leases 
-rw-r--r-- 1 root root 0 Mar 18 08:08 dhclient.leases
pi@raspberrypi:/var/lib/dhcp $ cat dhclient.leases 
pi@raspberrypi:/var/lib/dhcp $ 

查看了一下 空歡喜,什么都沒有,

那就看看這個路徑還有些什么文件:

pi@raspberrypi:/var/lib/dhcp $ ls -la
total 20
drwxr-xr-x  2 root root 4096 Jun 14 16:16 .
drwxr-xr-x 47 root root 4096 May 18 10:32 ..
-rw-r--r--  1 root root    0 Mar 18 08:08 dhclient.leases
-rw-r--r--  1 root root 5535 Jun 14 16:50 dhcpd.leases
-rw-r--r--  1 root root 3015 Jun 14 16:16 dhcpd.leases~

文件數量不多,逐個查看,dhcpd.leases這個文件,沒錯就是他 運氣不錯,記錄了DHCP客戶端的連接日志:

pi@raspberrypi:/var/lib/dhcp $ cat dhcpd.leases
# The format of this file is documented in the dhcpd.leases(5) manual page.
# This lease file was written by isc-dhcp-4.3.1

lease 192.168.8.22 {
  starts 1 2016/06/14 16:55:13;
  ends 2 2016/06/14 17:05:13;
  cltt 2 2016/06/14 16:55:13;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet 0c:1d:af:e3:ab:e0;
  client-hostname "android-33afb4dbee873a4b";
}

# The format of this file is documented in the dhcpd.leases(5) manual page.

第一句注釋說,這個格式在dhcpd.leases(5)的用戶手冊,用戶手冊中記錄了每個項的詳細含義

$ man dhcpd.leases

這是我們需要用到的內容

lease 192.168.8.22 {
  starts 1 2016/06/14 16:55:13; # 租約開始時間
  ends 2 2016/06/14 17:05:13; # 租約結束時間
  cltt 2 2016/06/14 16:55:13;  # 客戶端最后訪問時間
  binding state active; # 綁定狀態
  next binding state free;
  rewind binding state free;
  hardware ethernet 0c:1d:af:e3:ab:e0; # 客戶端mac地址
  client-hostname "android-33afb4dbee873a4b"; # 客戶端主機名
}

接下來就是在python中寫獲取這些內容的方法,源代碼如下:

def getDhcpClientMap():
    dhcp_client_filepath = "/var/lib/dhcp/dhcpd.leases"
    #dhcp_client_filepath = "dhcpd.leases"
    # 打開文件
    dhcp_client_file = open(dhcp_client_filepath)
    # 創建list用於存放
    dhcpClientList = {}
    rline = dhcp_client_file.readline()
    while(rline):
    #     檢查地址位置
        pos192 = rline.find('192.168')
        if(pos192 >= 0):
    #         如果找到 創建對象
            posdkh = rline.find('{')
            rIpAddr = rline[pos192:posdkh - 1]
            rstartTime = ''
            rendTime = ''
            rBindState = ''
            rMacAddr = ''
            rHostName = ''
    # 查找其他內容
            while(True):
                rline = dhcp_client_file.readline()
                if(rline.find('}') >= 0):
                    break;
                if(rline.find('starts') >= 0):
                    rstartTime = rline[rline.find('starts') + 9:].replace(';\n', '')
                    continue;
                if(rline.find('ends') >= 0):
                    rendTime = rline[rline.find('ends') + 7:].replace(';\n', '')
                    continue;
                if(rline.find('  binding state') >= 0):
                    rBindState = rline[rline.find('  binding state') + 15:].replace(';\n', '').replace(' ', '') 
                    continue;
                if(rline.find('hardware ethernet') >= 0):
                    rMacAddr = rline[rline.find('hardware ethernet') + 17:].replace(';\n', '').replace(' ', '') 
                    continue;
                if(rline.find('client-hostname') >= 0):
                    rHostName = rline[rline.find('client-hostname') + 15:].replace(';\n', '').replace(' ', '').replace('"', '') 
                    continue;
            dxbDhcpClient = {}
            dxbDhcpClient['ipAddr'] = rIpAddr
            dxbDhcpClient['satrtTime'] = rstartTime
            dxbDhcpClient['endTime'] = rendTime
            dxbDhcpClient['bindState'] = rBindState
            dxbDhcpClient['macAddr'] = rMacAddr
            dxbDhcpClient['hostName'] = rHostName
    #         添加到存放的list
            dhcpClientList[rMacAddr] = dxbDhcpClient
    # 接着下一個循環
        rline = dhcp_client_file.readline()
    return dhcpClientList
View Code

把狀態為active 的設備放入到一個list中,供前端顯示:

# 清除非連接狀態的客戶端
def clearDhcpClientFreeAndToList(dhcpClientMap):
    for tk in dhcpClientMap.keys():
        if(dhcpClientMap[tk]["bindState"] == 'free'):
            dhcpClientMap.pop(tk)
    changeList = []
    for tk in dhcpClientMap.keys():
        changeList.append(dhcpClientMap[tk])
    return changeList
View Code

控制器方法源代碼如下:

@app.route("/wirelessClientList")
def dhcpClientPage():
    # 獲取DHCP客戶端列表方法
    deviceList = clearDhcpClientFreeAndToList(getDhcpClientMap())
    print deviceList
    return render_template('dhcpclient.html', dlist=deviceList)
View Code

頁面中遍歷(for endfor)獲取到的客戶端代碼如下:

{% for dev in dlist %}
      <tr>
          <td>{{dev.hostName}}</td>
          <td>{{dev.ipAddr}}</td>
          <td>{{dev.macAddr}}</td>
          <td>{{dev.satrtTime}}</td>
          <td>{{dev.endTime}}</td>
      </tr>
{% endfor %}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM