本文以 TP-LINK 的 TL-WR741ND 路由器(router)為例,示範如何使用各種程式語言與工具遠端控制路由器的 ADSL 連線(斷線並重新連線),自動更換網路的 IP 位址。
現在市面上大部分的路由器(或是 IP 分享器)都有網頁管理的介面,使用者可以透過網頁登入之後,管理路由器中的各種功能,而如果要更換 ADSL 的 IP 位址,最簡單的方式就是在網頁管理介面中,手動重新連線,由於非固定制的 ADSL 每次連線都會配發不同的 IP 位址,這樣自然就可以獲得一個新的 IP 位址了,這就是一般更換 IP 位址的原理。
在實際撰寫程式之前,我們要先研究一下路由器網頁管理介面的運作機制,不同廠牌的路由器可能有些差異,不過大致的運作原則都差不多。
這裡以 Google Chrome 瀏覽器做示範,首先登入路由器的網頁管理介面,找到可以進行 ADSL 斷線與連線的頁面。
然後按下 Ctrl
+ shift
+ i
鍵開啟「開發人員工具」,選擇「Network」籤頁,將舊的紀錄清除,並且確認記錄功能有開啟,這時候按下「中斷連線」的按鈕。
當您按下中斷連線的按鈕時,在下方會顯示瀏覽器送出的所有請求(Request),我們要找出用來送出斷線指令的關鍵請求,這樣的請求通常在 Request URL
欄位中會有類似 Disconnect
這樣的關鍵字:
以 TP-LINK 的路由器而言,關鍵的請求就是這個:
http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1
找到關鍵的請求之後,還要看一下認證的機制,以 TP-LINK 而言,他是使用 basic access authentication 的方式認證的,而這種認證方式很簡單,只是將帳號密碼經過 base64 編碼後,放在請求的表頭裡面而已,所以這裡只要再把 Authorization 這個表頭欄位內容複製下來,之後再放進程式中即可:
Authorization: Basic YWRtaW46YWRtaW4=
這樣事前的準備就算完成了,接著就可以開始撰寫程式。
其實只要釐清了關鍵請求的 URL 網址與它的認證機制,剩下的就是使用程式送出一個 HTTP 請求而已,這是使用 Java 送出斷線請求的程式碼:
// 建立 URL 物件 URL myUrl = new URL("http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1"); // 開啟 URLConnection URLConnection myConn = myUrl.openConnection(); // 設定帳號密碼 myConn.setRequestProperty("Authorization", "Basic YWRtaW46YWRtaW4="); // 連線 myConn.connect(); // 取回資料(資料本身沒有用,不過好像如果不加這行就無法運作) myConn.getHeaderFields();
程式本身很簡單,重點就是要把之前的關鍵請求的網址與認證表頭放進來。如果想要寫一個可以動態輸入帳號密碼的程式,就再加上一個 base64 的編碼動作,將帳號密碼編碼後再放進去即可。
執行上面這段程式碼之後,就會馬上讓路由器斷線,而如果要讓他再次重新連線,就要再送一次連線指令的請求,實作方式與斷線的情況大同小異,請自行從上面的程式修改。
如果要以 Perl 語言來實作,可以使用 HTTP::Request 與 LWP::UserAgent 兩個模組,基本上的概念都相同:
#!/usr/bin/perl use HTTP::Request; use LWP::UserAgent; # 建立請求 $request = HTTP::Request->new(GET => 'http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1'); # 設定帳號與密碼 $request->authorization_basic('admin', 'admin'); my $ua = LWP::UserAgent->new; # 送出請求 my $response = $ua->request($request);
如果要以 Python 實作,建議使用 Requests 函式庫,在 Ubuntu Linux 中可以使用 apt 安裝:
sudo apt-get install python-requests
這樣實作就會簡單很多:
#!/usr/bin/python import requests from requests.auth import HTTPBasicAuth requests.get('http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1', auth=HTTPBasicAuth('admin', 'admin'))
除了一般的程式語言之外,也有許多其他的工具可以達到相同的功能,例如 cURL:
curl --user admin:admin 'http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1'
或是 wget
:
wget -qO- --http-user=admin --http-password=admin 'http://192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1'
這兩個指令會送出請求,然後把回應的資料輸出至標準輸出(也就是直接印出來在螢幕上),如果不想看到這些輸出,可以在結尾加上 >/dev/null
(只適用於 Linux 或 Mac OS X 平台)。