随笔 - 117  文章 - 72  trackbacks - 0

声明:原创作品(标有[原]字样)转载时请注明出处,谢谢。

常用链接

常用设置
常用软件
常用命令
 

订阅

订阅

留言簿(7)

随笔分类(130)

随笔档案(123)

搜索

  •  

积分与排名

  • 积分 - 152591
  • 排名 - 390

最新评论

[标题]:[原]VC实现重启路由器
[时间]:2009-5-28
[摘要]:使用VC发送一个HTTP请求给路由器,实现重启TP-LINK路由器功能。
[关键字]:TP-LINK,Basic Authorization,Base64,GET,HTTP
[环境]:TP-LINK TL-R402M SOHO 宽带路由器 , VC6 , HttpFox,Firebug
[作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys

[正文]:
    在浏览器里输入地址:192.168.1.1,它会弹出一个窗口, 要求输入密码。这是因为服务器要求HTTP Basic access authentication(http://en.wikipedia.org/wiki/Basic_access_authentication)。输入用户名和密码就可以进入路由器管理界面了,点击"重启路由器"按键即可重启路由器。如何编程实现向路由器发送重启的请求?

    (1)、打开Windows命令行,将以下命令粘贴到命令行里(注意,最后有一个空行)。
telnet 192.168.1.1 80
GET / HTTP/1.1
Host:192.168.1.1

    服务器会返回如下信息:
HTTP/1.1 401 N/A
Server: TP-LINK Router
Connection: close
WWW-Authenticate: Basic realm="TP-LINK SOHO Router R402M"
Content-Type: text/html

Web Server Error Report:<HR>
                            <H1>Server Error: 401 N/A</H1>
<P><HR><H2>Access denied</H2><P><P><HR><H1>/userRpm/index.htm</H1><P><HR>please
mail problems to support@tp-link.com.cn
    路由器会返回状态码:401。这说明,本次访问是未经授权的,服务器拒绝了。同时,还可以看到:WWW-Authenticate: Basic realm="TP-LINK SOHO Router R402M",这说明路由器确实需要Basic验证。


    (2)、再使用Firebug和Httpfox分析出点击"重启路由器"时,浏览器向路由器发送的请求。发现,主要请求内容如下:
GET /userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7 HTTP/1.1
Host:192.168.1.1
Authorization:Basic YWRtaW46YWRtaW4=
    其中,Authorization请求头的内容中,"Basic"表示"Basic authorization验证" ;"YWRtaW46YWRtaW4="是使用Base64编码后的用户名和密码,解密后是"admin:admin"。使用Base64编码有两个目的:a、使用户名和密码不能直接被肉眼识别;b、使传送的内容中无非法字符,即使用户名或密码中有不适于直接使用HTTP协议传送的字符,使用Base64编码后,就符合了协议要求。Base64能被轻易解密,所以不能依赖它来实现安全的访问控制。

    同样,也可以自己在命令行输入以下内容,实现以上的HTTP请求,从而实现重启路由器功能(最后有一个空行):
telnet 192.168.1.1 80
GET /userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7 HTTP/1.1
Host:192.168.1.1
Authorization:Basic YWRtaW46YWRtaW4=

    (3)、用VC6发送GET请求:
void CUtil::RestartRouter(CString& strHost)
{
    CInternetSession session("Winty's Session");
    CHttpFile* pHttpFile;
    //路由器要求Basic Authorization:用户名:admin,密码:admin
    CString strHeaders = _T("Authorization:Basic YWRtaW46YWRtaW4="); // 请求头
    
    try
    {
        INTERNET_PORT nPort; //端口
        CString strRelativeRequestURL;
        nPort = 80;
        strRelativeRequestURL = "/userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7";
        
        CHttpConnection* pServer = session.GetHttpConnection(strHost, nPort);
        
        pHttpFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,strRelativeRequestURL);
        pHttpFile->AddRequestHeaders(strHeaders);
        pHttpFile->SendRequest();
        
        //判断请求是否成功
        DWORD dwStatusCode;
        BOOL bSuccess;
        bSuccess = pHttpFile->QueryInfoStatusCode( dwStatusCode );
        CString strMsg;
        strMsg.Format("登陆失败! 错误信息:HttpStatusCode=%d" , dwStatusCode);
        if(!bSuccess || !(dwStatusCode>=200 && dwStatusCode<300)){
            AfxMessageBox(strMsg);
        }
    }
    catch(CException* e)
    {
        pHttpFile = NULL;
        throw;
    }
    pHttpFile->Close();
    delete pHttpFile;

    session.Close();
}
    调用函数:RestartRouter("192.168.1.1");,即可实现重启路由器功能。

[参考资料]:
Basic access authentication :http://en.wikipedia.org/wiki/Basic_access_authentication
原创作品,转载请注明出处。
作者:Winty (wintys@gmail.com)
博客:http://www.blogjava.net/wintys

posted on 2009-05-29 23:36 天堂露珠 阅读(4989) 评论(8)  编辑  收藏 所属分类: C++

FeedBack:
# re: [原]VC实现重启路由器 2009-05-29 23:53 事发当时
这种情况下,不止vc,所有httpcliet都可以实现吧!!!  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-05-30 09:41 天堂露珠
@事发当时
在命令行直接输入HTTP GET请求都可以,其它的编程语言或工具当然也可以。  回复  更多评论
  
# re: [原]VC实现重启路由器[未登录] 2009-05-31 22:41 java
一年能在做搜索引擎时,去访问百度,google,太平凡了,老被封IP,总要重启路由器,来重新获取新IP,后来自己就用C#写了一个,原理和实现方法跟你一样,,当然感觉很牛B,现在想想真SB.
  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-06-01 12:00 天堂露珠
@java
上网掉线后,需要重启路由器,所以写了一个重启路由器的实用工具而已。  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-11-06 02:18 真陈
达人,你好
关于你的这段代码,我也看过,试着自己整,有点问题
我的路由器(R402M VER070605)不支持TELNET
我试过,http://192.168.1.1/userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7
如果把用户名密码写好进入主界面后,用以上链接可以成功
现在的关键是
我想直接通过做一个HTML网页,让它一运行就能全自动重启路由器,而不用每次都去输入用户名密码,就是你的那个basic验证,怎么做?希望指教,谢谢  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-11-06 02:23 真陈
天堂露珠大大
最好是希望你能写一个界面,有两个INPUT,一个用户名,一个是密码
然后有一个JAVA的bASIC加密(当别人的密码不是默认的时候,可以方便改)
然后,用这个绕过输入用户名密码这一步,再http://192.168.1.1/userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7 是不是就可以达到重启的目的了?我的想法对吗?

那么,那个怎么写呢?我是菜鸟,希望得到你的指望  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-11-06 10:14 天堂露珠
我的代码移植性并不高,就是没有把密码等作为参数传入。但是这样对我来说已经够了,实现功能就行了,自己用用很方便,也不用Base64加密了(因为使用的用户名密码都已加密YWRtaW46YWRtaW4=)。
我的TELNET例子只是为了方便手动调试。支不支持并不重要。
你的想法是对的。无论是用Java、VC还是浏览器,只要能向路由器发送HTTP GET请求就可以了。具体的向服务器发送HTTP请求并设置请求头的Java例子可以在网上找找,然后再改一下就可以了。  回复  更多评论
  
# re: [原]VC实现重启路由器 2009-11-06 10:17 天堂露珠
Form形式的HTTP Basic Authentication
参考:http://hi.baidu.com/thinkinginlamp/blog/item/16f6d933f131b644ad4b5f98.html
如(将文件保存为reboot.hta):
<html>
<head>
<title>login</title>
<script>
var xmlHttp;

function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}

function login() {
createXMLHttpRequest();

var username = document.getElementById("username").value;
var password = document.getElementById("password").value;

xmlHttp.open("GET", "http://192.168.1.1/userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7", false, username, password);
//xmlHttp.setRequestHeader("Content-Type","...");
xmlHttp.send(null);

if(xmlHttp.status!=200)
alert(xmlHttp.status);
else
alert("OK");

return xmlHttp.status == 200;
}
</script>
</head>
<body>
<form action="#" method="post" onsubmit="return login();">
<fieldset>
<legend>Login</legend>
<label for="username">username:</label>
<input type="text" id="username" name="username" value="admin">

<label for="password">password:</label>
<input type="password" id="password" name="password" value="admin">

<input type="submit" value="submit">
</fieldset>
</form>
</body>
</html>
由于Firefox不支持跨域访问,所以,上述代码只能在IE中运行。由于是保存为.hta,那么双击就可以运行了。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: