2012-12-31 145 views
2

我正在運行具有有線網絡接口的Linux設備。此接口的另一端插入另一個配置爲使用某個靜態IP地址和某個網絡掩碼的網絡感知設備。因此,我們有一個非常簡單的網絡,只包含兩個設備和一個電纜,甚至沒有它們之間的切換,什麼都不是。我可以使用靜態IP檢測配置的連接設備的網絡和網絡掩碼

的任務是開始與其他設備說話,而我們需要

  1. 將網絡上去用ifconfig等。
  2. 獲取IP地址並啓動我的程序,該程序使用此IP地址與 設備配合使用。

我知道我可以做廣播ping,並在電纜的另一端獲得設備的IP地址。這對我有用。但要激活網絡並做廣播ping,我需要知道網絡地址和網絡掩碼。我目前的bash腳本看起來像

ifconfig 192.168.100.1 netmask 255.255.255.0 up 
ping -b 192.168.100.255 

並且設備響應。不幸的是,其中一些設備可能配置有不可預知的網絡和網絡掩碼。任何人都可以提出一個想法如何自動檢索網絡設置(netbase,netmask)?即使是部分解決方案,也會感恩。自定義的C工具可以編譯並安裝在我的身邊,如果這有幫助的話。

+2

DHCP是否可用?這是處理IP設置的動態分配的正確方法。既然你願意編譯和安裝一個自定義的解決方案,我會考慮安裝DHCP。 –

+2

設備是否響應ICMP網絡掩碼請求? – Keith

+0

另一端的設備配置爲使用靜態IP地址,即使我們提供此服務也不會使用DHCP – h22

回答

3

對於您可以nmap的使用,只要你能以某種方式限制範圍,如您的評論本已應該給你的主機,你要第一部分:基於ARP

sudo nmap -PR -sn 192.168.0-255.0-255 -e <interface-to-test> 

這確實發現和如果成功的話可以通過一次額外的ICMP查找活力。這一次在一個沒有活躍的本地主機和5個有4個活動主機的系列上花了我大約一秒鐘的時間。因此,您甚至可以將其擴展到更大的範圍,但是除非您有一兩天的時間,否則不會包含完整的IPv4地址空間。在這種情況下,我只需連接wireshark或tcpdump並等待無償ARP。

編輯:爲此,您必須在要測試的子網中使用IP配置「源計算機」。我認爲在離開子網時或者沒有配置IP時,它會使用ARP的DAD模式,但它不會做任何事情。我爲下面的算法寫了一個更通用的版本,但是比簡單地使用nmap獲得這個結果要慢一些。

檢測配置的網絡掩碼有點棘手。但我認爲這個過程是可行的,主要思想是主機將發送一個ARP請求給其子網中的主機,並且不發送任何ARP請求或者其默認gw的ARP請求給不在其子網中的主機。

  1. 從第二個到最小的子網N=29開始。
  2. 從該主機的IP和子網掩碼N組成的子網中選取IP X。確保選取的IP不是主機的IP而不是網絡/廣播。還要確保這個IP不是由主機的IP和掩碼N+1組成的子網的一部分。
  3. 平安其他主機與源X(你不介意它回答,只是發出一個請求)
  4. 如果你看到X一個ARP請求,一個減少N。請返回2
  5. 如果您沒有看到X的ARP請求,N+1是搜索到的子網。

一個缺陷可能是過度的網絡堆棧實現可能會從傳入的ICMP請求中學習MAC,但我個人不知道任何以這種方式工作的終端設備堆棧。

我不知道是否有工具可以爲你做這件事,但應該很容易用ping,tcpdump和子網計算器手動執行;)。或者如果你覺得受到一些黑客攻擊,可能沒有太多的工作來實現這scapy

我一起寫了一個完整的python scapy腳本我應該工作,我測試它在我的家庭網絡上的linksys homegw ,另一個linux機器和一個android設備:

from __future__ import print_function, absolute_import, unicode_literals 
from scapy.base_classes import Net 
from scapy.config import conf 
from scapy.layers.inet import Ether, ARP, ICMP, IP 
from scapy.sendrecv import srp, debug 
import scapy.route 

iface = b'eth0' 
subnet_to_test = b'192.168.1.0/24' 
#or: 
subnet_to_test = b'192.168.1.*' 

#IP/MAC discovery 
pkt = Ether(dst=b'ff:ff:ff:ff:ff:ff')/ARP(psrc=b'0.0.0.0', pdst=subnet_to_test, hwdst=b'ff:ff:ff:ff:ff:ff') 
responses = srp(pkt, timeout=1, retry=0, verbose=0, iface=iface) 
for r in responses[0]: 
    found = r[1].getfieldval('psrc') 
    foundmac = r[1].getfieldval('hwsrc') 

n = 29 
conf.debug_match = 1 
while n > -1: 
    net = Net("{}/{}".format(found, n)) 
    my_src = net.choice() 
    while my_src in Net("{}/{}".format(found, n + 1)): 
     my_src = net.choice() 
    pkt = Ether(dst=foundmac)/IP(dst=found, src=my_src)/ICMP(type=8) 
    resp = srp(pkt, timeout=1, retry=0, verbose=0, iface=iface, filter=b'ether dst FF:FF:FF:FF:FF:FF and arp') 
    received = [x for x in debug.recv if x.haslayer(ARP) and x.getfieldval('pdst') == my_src] 
    received.extend(x[1] for x in resp[0] if x[1].haslayer(ARP) and x[1].getfieldval('pdst') == my_src) 
    if len(received) == 0: 
     print("Found host: {}/{} on mac {}".format(found, n + 1, foundmac)) 
     break 
    n -= 1 
+0

當界面上還沒有IP地址時,nmap將不起作用。此外,您的掩碼檢測算法不起作用。它會返回您可以分配地址的最大遮罩,但這並不意味着您具有與鄰近設備相同的遮罩。 –

+0

@將c。整個觀點是,有一個配置但未知的地址。而我的算法與分配無關:S,唯一的缺點是目標主機可能從入局icmp學到Mac,根本不會ARP,但在這種情況下,您只需更改觸發器即可檢測數據包到另一個ip(即默認gw)。 – KillianDS

+0

*目標*機器上有一個配置但未知的地址,但* source *機器上沒有IP地址。在源機器上沒有IP地址的情況下,您無法使用nmap,所有的ARP回覆將被丟棄到目標機器上。當我說分配時,我的意思是從該塊中取出一個IP地址並將其放在源接口上。 –

-1

你所要求的是不可能的。

最初,你有一個沒有IP地址的接口。因此,您發出的任何數據包都不知道應答的發送位置(ICMP或ARP請求因此不起作用)。

由於發件人不知道如何到達此接口,因此您可以在接口上偵聽任何廣播ARP請求(使用tcpdump,wireshark等)。這將顯示您在網絡中解析了哪些IP地址,但它不會給你網絡掩碼(也就是網絡地址)。此外,它不會只有爲您提供直接連接的鄰居的IP地址,它會給你所有的ARP請求在這個廣播域內(所以你可能會看到很多的IP地址)。

現在,至於確定設備正在使用的網絡掩碼,使用CIDR時不可能(前綴可能在/ 16到/ 32之間的任何地方,並且無法準確地知道哪一個是鄰居設備正在使用。)

這就是說,你可能想看看鏈路本地IPv4地址。在Linux上,有一個名爲AVAHI的程序,在Windows上稱爲APIPA。都實現RFC 3927:http://tools.ietf.org/html/rfc3927

鏈路本地地址只能使用相同的物理或邏輯鏈路上的設備進行通信,所以如果你真的希望此設備在同一子網內,則必須手動配置界面。

+0

測試機器在他的控制下,他總是可以用一些地址來配置它。但是,ARP可以在沒有配置地址(DAD模式)的情況下完成,甚至更多,這是在實際應用地址之前執行*的推薦步驟。沒有其他設備和可能的其他IP,問題清楚地表明它是一個點對點鏈接。我在答案中提供了一個算法,如何檢測工作正常的網絡掩碼(測試)。 – KillianDS

+0

同意,我從更廣泛的意義上考慮這個問題(多設備,多個子網,共享相同的衝突域)。我仍然認爲使用鏈接本地地址是解決這個問題的簡單方法。 –