荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: lczhong (lcz), 信区: Program
标  题: 利用“侦听-转发”程序破译网管协议
发信站: BBS 荔园晨风站 (Thu Mar 15 18:27:38 2001), 站内信件

发信人: Smile (呵呵~~我的昵称不见了), 信区: SOCKET
标  题: 利用“侦听-转发”程序破译网管协议
发信站: 武汉白云黄鹤站 (2001年03月14日07:37:13 星期三), 站内信件

利用“侦听-转发”程序破译网管协议
深圳市芯络实业有限公司
chenjun
一, 开发目的及原理
---- 本公司在产品开发过程中,需要研究多种以太网交换机(又称智能集线器)的内部
网管信息结构,为此, 必须编写出一个“窃听”程序,把网管程序和交换机的通讯内容
记录下来加以分析。本人在Visual C++ 6.0下用MFC Socket类编出程序,成功地实现了
上述目的。
---- 目前,标准的网络管理程序与支持网管的网络设备之间大多采用标准的简单网络管
理协议(SNMP)进行 通讯。SNMP是一种高层协议,建立于UDP/IP之上。通讯双方按照S
NMP格式来传递各种网管信息和控制信息, 并能进行事件实时报告或报警,从而使网络
管理员能方便及时地控制网络当前的运行情况。
---- 网管信息的范围十分广泛,如网络流量,连接状态等,因被管设备的不同而不同,
厂家也能依照有关的 国际标准自定义自家产品的网管信息。网管信息集中定义于管理信
息库(MIB)中,整个体系是一个可扩展 的树状结构。一条条的网管信息被包装在SNMP
协议包内,再往下传给传输层,转成UDP包,然后通过Socket 机制发送出去。
---- 本程序的基本原理是:插到网管程序和被管设备之间“欺上瞒下”,与网管程序通
讯时冒充被管设备; 与被管设备通讯时冒充网管程序,使二者对本程序“无话不谈”;
本程序则暗中有序地记录下谈话内容, 然后再“上传下达”,将收到的内容转发给真正
的接收者,使谈话继续下去,如此循环不已。
二, 编程的思路和具体过程
---- 本程序不需要复杂的图形界面,因此,只需用Project Wizard开出一个支持Socke
t而基于对话框的MFC 应用程序即可。对话框的类名为CChatDlg,然后再用资源编辑器在
这个对话框上加上一个按钮,面上文字 为“Listen”。接收到的所有信息将在Visual
C++集成环境的Output窗口中用TRACE语句打出,这样做的目 的是能方便及时地看到各种
数据,当然也可用别的方法。在本程序中,Client指网管程序,Server指交换 机。
---- 接着给本项目添加两个类,它们都衍生自CSocket,可调用ClassWizard工具生成。
CClientSocket用于 接收来自网管程序的UDP数据,而CServerSocket则用于接收来自交
换机的UDP数据。这两个类的定义如下:
 class CClientSocket
        : public CSocket { // Attributes public: // Operations public: CClie
ntSocket(CChatDlg*
        pdlg); virtual ~CClientSocket(); // Overrides public: BOOL m_bFirst;
 CChatDlg*
        pDlg; // ClassWizard generated virtual function overrides //{{AFX_VI
RTUAL(CClientSocket)
        public: virtual void OnReceive(int nErrorCode); //}}AFX_VIRTUAL // G
enerated
        message map functions //{{AFX_MSG(CClientSocket) // NOTE - the Class
Wizard
        will add and remove member functions here. //}}AFX_MSG // Implementa
tion
        protected: }; m_bFirst和pDlg是自定义的两个类别成员, 其作用见下文。
class CServerSocket :
        public CSocket { // Attributes public: // Operations public: CServer
Socket(CChatDlg*
        pdlg); virtual ~CServerSocket(); // Overrides public: CChatDlg* pDlg
;
        // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(
CServerSocket)
        public: virtual void OnReceive(int nErrorCode); //}}AFX_VIRTUAL // G
enerated
        message map functions //{{AFX_MSG(CServerSocket) // NOTE - the Class
Wizard
        will add and remove member functions here. //}}AFX_MSG // Implementa
tion
        protected: }; 然后,在CChatDlg类中加入对 按钮Listen的处理函数如下:
void CChatDlg::OnListen()
        { pClientSocket = new CClientSocket(this); if(pClientSocket != NULL)
 {
        if(!pClientSocket->Create(SNMP_SOCKET_PORT, SOCK_DGRAM)) AfxMessageB
ox("Can
        not create ClientSocket !"); else ::EnableWindow(GetDlgItem(IDC_LIST
EN)->
        m_hWnd,FALSE); } else { AfxMessageBox("Can not new ClientSocket !");
 }
        } 注意:SNMP_SOCKET_PORT应设为161。 然后,在CClientSocket中加入 虚函
数OnReceive的实作内容: void
        CClientSocket::OnReceive(int nErrorCode) { CSocket::OnReceive(nError
Code);
        unsigned char tmp[MAXTMPSIZE]; //MAXTMPSIZE是自定义宏,可为1024; in
t i; int RecNum;
        UINT ClientPort; CString ClientAddress; if(m_bFirst) { m_bFirst = fa
lse;
        RecNum = ReceiveFrom(tmp, MAXTMPSIZE, ClientAddress, ClientPort); if
(RecNum
        > 0) { TRACE("Received from client, %d bytes :\n", RecNum); for(i=0;
 i<RecNum;
        i++) { if(i%10==0) TRACE("\n%5d,", tmp[i]); else TRACE("%5d,", tmp[i
]);
        } TRACE("\n\n"); pDlg->CreateServerSocket(ClientAddress, ClientPort)
;
        pDlg->Send(true, tmp, RecNum); } else AfxMessageBox("Error: fail to
Receive
        from client the first time!"); } else { RecNum = Receive(tmp, MAXTMP
SIZE);
        if(RecNum > 0) { TRACE("Received from client, %d bytes :\n", RecNum)
;
        for(i=0; i<end(true, tmp, RecNum); } else AfxMessageBox("Error: f
ail
        to Receive from client!"); } if(RecNum <= 0) { AfxMessageBox("Error:
 fail
        to Receive from client !"); return; } }
---- 本段程序的大概意思是:如果本程序首次收到来自网管程序的UDP包,则要记录下
它的Socket端口号和IP 地址,这是本程序最关键的地方之一。这样做的原因是:网管通
讯开始时一般是由网管程序首先发出SNMP 请求包,所以要先响应网管程序;另一目的是
由此获得事先未知的网管程序侦听的Socket端口号和IP地址, 然后让CChatDlg由此创建
CServerSocket。随后调用CChatDlg的Send函数将收到的UDP包转发给交换机,并 在Out
put窗口按每行10个的格式显示出收到的数据。
---- 上段程序中CChatDlg的Send和CreateServerSocket函数的内容如下:
 void CChatDlg::CreateServerSocket (CString address, UINT port) {
        m_ClientAddress = address; m_ClientPort = port; pServerSocket = new
CServerSocket(this);
        if(pServerSocket != NULL) { if(!pServerSocket->Create(m_ClientPort,
SOCK_DGRAM))
        AfxMessageBox("Can not create ServerSocket !"); } else AfxMessageBox
("Can
        not new ServerSocket !"); } void CChatDlg::Send(BOOL ToServer, unsig
ned
        char* buf, int buf_len) { if(ToServer) { if(pServerSocket != NULL) {
 if(pServerSocket->SendTo(buf,
        buf_len, SNMP_SOCKET_PORT, m_ServerAddress)==SOCKET_ERROR) AfxMessag
eBox("Error:
        fail to send data to server !"); } } else { if(pClientSocket != NULL
)
        { if(pClientSocket->SendTo(buf, buf_len, m_ClientPort, m_ClientAddre
ss)==SOCKET_ERROR)
        AfxMessageBox("Error: fail to send data to client !"); } } }
---- 注意:m_ServerAddress是交换机的IP地址,要事先在CChatDlg的OnInitDialog函
数或其他地方设定。
---- 最后,要处理接收到的来自于交换机的UDP包,将其中的数据在Output窗口中按每
行10个的格式显示出来,然后调用CChatDlg的Send函数将其转发给网管程序。这在CSer
verSocket类的OnReceive虚函数中实现:
 void CServerSocket::OnReceive(int nErrorCode) { CSocket::OnReceive(nErrorCo
de);
        unsigned char tmp[MAXTMPSIZE]; int i; int RecNum; RecNum = Receive(t
mp,
        MAXTMPSIZE); if(RecNum > 0) { TRACE("Received from server, %d bytes:
\n",
        RecNum); for(i=0; i&lt;end(false, tmp, RecNum); } else { i = GetLast
Error();
        TRACE("RecNum = %d, GetLastError() = %d\n", RecNum, i); AfxMessageBo
x("Error:
        fail to Receive from server!"); } }
---- 以上就是本程序的主要功能部分,其中有一些变量因篇幅原因未作详细解释,但不
影响对程序的理解。
三, 运行过程
---- 分别在两台机器上装上本程序和网管程序,将它们连上交换机,先运行本程序,点
Listen按钮,然后运行网管程序。一般的网管程序运行时,需要设置被管设备的IP的地
址,此时,要将其设为本程序所在机器的IP地址,使网管程序将所有的SNMP包发给本程
序。
---- 之后两程序应能正确运行(如果不行,可能要将上述过程多重复几次。),在Out
put窗口可以看到数据源源不断地显示出来,这真是对网管过程的真实记录!当数据量足
够后,结束本程序,可以看到网管程序界面上显示出“设备已断开连接!”的提示信息
。然后可以将Output窗口中的数据拷贝到文本文件中,按照SNMP的格式和编码规则进行
详细分析,网管协议就由此慢慢地破解出来了。
---- 以上程序在Visual C++ 6.0下编译通过并运行成功,实践效果很好。


--


--

    ┏━━┓┏━━┓  ☆  ┏━┓  ┏━━┓
    ┃  ━┫┃    ┃ ┏┓ ┃  ┃  ┃  ━┫
    ┣━  ┃┃┃┃┃ ┃┃ ┃  ┗┓┃  ━┫
    ┗━━┛┗┻┻┛ ┗┛ ┗━━┛┗━━┛

※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·[FROM: 211.69.197.130]

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.28.105]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店