模仿儀器商附的IP finder

 
使用到的工具:

  1. Wireshark
  2. MATLAB

前言:

最近拿到一台轉檯,預計要用在通道量測的系統中,必須能控制其轉向,而且要能夠知道轉檯當前角度。

仔細研究一下這轉檯的說明書,發現除了RS-485/232外,還可以用網際網路來通訊,之後一個系統會有兩個轉檯,為了讓電腦少連接一點線甚至只需要一條網路線,用網路介面來溝通當然是首選。

廠商有附一個軟體,可以尋找轉檯在區網內的IP,但我發現這個軟體使用上非常碰運氣,怎麼說呢?我執行這找IP的程式10次,可能只有1次找的到IP,重點是每次轉檯重機開IP就會跑掉,這樣對開發人員來說很麻煩。

可能看到這裡,就會有專業的人說可以指定一個IP給儀器,這樣不用每次重新開機都要搜尋。這樣說是沒有錯的,但是指定IP並非人人都會,也不是很方便交接,若能自己寫一個能順利找IP的程式,將此功能鑲嵌在未來控制轉檯的程式裡,這樣不是省去更多麻煩嗎?

要控制一個儀器,若要開一個軟體找他IP,然後再記下IP輸入進另外一個程式裡,我自己操作都覺得很麻煩了,將找IP與控制的程式整合在一起,只需要點點滑鼠,輸入轉檯座標就能控制,大家都開心。

以下正文:

首先個人對這問題的想法:
這的確是個問題,通常儀器商不會給原始碼,加上可以想像程式整合後,使用流程上會有多方便,此問題便成立。首先想想這問題該如何切入?

(開始自言自語)當然是寫一個跟附帶的軟體一樣的功能阿!但我沒原始程式碼怎麼辦呢?網路上也找不到其他人有說廠商的尋找IP程式怎麼寫。啊!這軟體是用來找IP的,那肯定跟網路有關,要能在網路上溝通,必定要發封包,對!關鍵應該就是封包!只是不知道封包的內容是甚麼。印象中我好像有學過用Wireshark截取封包來看,趕緊去載!

載好了就來看看這個軟體到底發甚麼封包才能找到儀器,先開wireshark預備好,再執行尋找轉檯的程式。


登愣~抓到!答案呼之欲出,看起來很神秘的程式,說穿了不值一文錢。

原來是直接利用UDP廣播(255.255.255.255)的方式,來找出儀器的IP是多少。第一個廣播封包是由我的電腦(192.168.0.101)發出,訊息長度是10Bytes,這訊息內容就如同「嗨,我想要找的轉檯們,你們在哪呀?我的通關密語是 "xxxx"(封包內文)」;當轉檯判斷廣播封包的通關密語正確,第二個廣播封包便由轉檯(192.168.0.100)這端發出,訊息長度是17Bytes,想當然就是回應「你好,我在這!我的通關密語是 "yyyy"(封包內文)」。這時,當軟體判斷接收到包含通關密語"yyyy"的封包之時,其封包的Source IP即為儀器的IP!

嘿嘿,短短兩個封包,說明了一切!

現在知道了這程式是如何運作的,基本上也不需要他的原始碼,只要做出一樣的功能即可。也就是說,若能寫出一個程式,發送廣播封包,讓儀器有反應,並同時會回應一個廣播封包,再去抓此封包的Source IP就可以解決這個看似困難的問題。

那現在就來看看他們之間的通關密語是甚麼吧~
先是電腦端的部分


再來是儀器端的部分


這下可更清楚了,電腦端先說「'DCUD_PING\0'」,儀器端再回覆「'DCUD_PONG\0KERNEL\0'」。雖然個人覺得儀器端的回覆訊息應該有打錯字,PONG應該為PING,但是不管這麼多了,說不定儀器商有發現,只是礙於已經賣出產品,目的能溝通正常運行達到就好,沒想到會被別人在這種情況下看到錯字XD。

到目前為止,分析的步驟已經結束,完全清楚主機和儀器們在聊什麼,可藉此抓封包來源IP得知儀器所在位置。

現在就要開始實做,因為之後控制的軟體都是以MATLAB為主,因此個人採用MATLAB來傳送與接收封包,目前知道此封包是廣播、連接埠是4930、採用UDP、包含通關密語「'DCUD_PING\0'」。

MATLB是一個很強大的Coding軟體,工程上的需求應該都有內建function能用。找到他關於封包發送接收的物件有tcpip, udp……等等,但在此只會用到udp物件。

先看看在MATLAB裡面 help udp 的介紹:
OBJ = udp('RHOST', RPORT) constructs an udp object associated with remote host, RHOST, and remote port value, RPORT.

非常簡單!只要給目的地端IP(RHOST = 255.255.255.255)和目的端的連接埠(RPORT = 4930),就能建立一個udp物件。

>> u = udp('255.255.255.255', 4930); %創建一個udp物件叫u。
>> u.Status

ans =

    'closed'

u.Status是這個udp物件現在的狀態,closed為還沒連上線,open才為連上,物件建好之後要讓其狀態為open才能通訊喔!

>> fopen(u); %用來打開通訊協定物件的連線狀態
>> u.Status

ans =

    'open'

這樣代表連線是可以的,來吧,接下來就是傳一個包含通關密語的封包出去看看。

傳送是用fwrite、fprintf與query
  1. fwrite(udp, A):將資料A用連線好的udp物件發送出去。
  2. fprintf(udp, A):與fwrite功能一樣,但不同的是會「自動」在A最後加上一個換行(LF)碼,再傳送出去。
  3. query(udp, A):包含fprintf的功能,除此之外,還會抓一個在緩存區的封包進來,若一定時間內都沒有封包能抓,query會回覆逾時的結果。
為了跟廠商軟體一樣,因此選擇不會有添加物的fwrite來實現發送封包。

>> A = ['DCUD_PING' char(0)]; %通關密語'DCUD_PING\0'
>> fwrite(u, A);

發送封包後,Wireshark竟然還是空的,難道哪裡做錯或想錯了嗎?目標IP為255.255.255.255沒錯呀,摁?這個IP是廣播IP,所以每個區網都有,但我目前沒有設定要廣播在哪個區網,會不會廣播錯網域了呢?來看看其他網域的封包。


我猜得果然沒錯,儀器是在192.168.0.0/24網域內,而這個廣播封包被送去169.254.0.0/16,儀器當然不會回應。若我想廣播在192.168.0.0/24,那我必定要以192.168.0.100的身分去做廣播,否則會像上面的情況廣播去別地方。那就看看如何設定udp物件吧!在MATLAB有一個很好用的函式叫做get(obj),他能列出物件obj的所有屬性。

>> get(u)
    ByteOrder = bigEndian
    ...
    ...
    ...
    LocalHost = 
    LocalPort = 62910
    ...
    ...
    ...

又抓到了~在此就可以設定自己的IP(LocalHost )與連接埠(LocalPort)。由於儀器廣播的連接埠是4930,因此LocalPort需要設定為4930,否則就算儀器廣播封包送出,連接埠沒對上也接收不到。再驗證一遍自己的想法。

>> u = udp('255.255.255.255', 4930, 'LocalHost', '192.168.0.101', 'LocalPort', 4930);
>> fopen(u);
>> A = ['DCUD_PING' char(0)];
>> fwrite(u, A);


有沒有!看起來跟廠商附的軟體發的封包一模一樣(其實就是模仿到一樣)。

到了現在這步,已經可以坐收儀器發出來的封包了,在MATLAB裡用fgetl、fgets、fscanf與fread來收封包,這些指令都能回傳封包的來源IP,所以都可以使用,我選擇使用fscanf。

>> [A,count,MSG,DatagramAddress] = fscanf(u);%抓封包
>> DatagramAddress

DatagramAddress =

    '192.168.0.100'

喔耶,拿到儀器的IP了,終於解決這個問題。

留言

這個網誌中的熱門文章

[Hyper-V] 讓 Windows 可以吃到超過 16TB 的硬碟!