Get.cpp
上传用户:czjinwang
上传日期:2007-01-12
资源大小:2484k
文件大小:15k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*============================================================================
  2.   Copyright (c) 1996
  3.   Hewlett-Packard Company
  4.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  5.   Permission to use, copy, modify, distribute and/or sell this software 
  6.   and/or its documentation is hereby granted without fee. User agrees 
  7.   to display the above copyright notice and this license notice in all 
  8.   copies of the software and any documentation of the software. User 
  9.   agrees to assume all liability for the use of the software; Hewlett-Packard 
  10.   makes no representations about the suitability of this software for any 
  11.   purpose. It is provided "AS-IS" without warranty of any kind,either express 
  12.   or implied. User hereby grants a royalty-free license to any and all 
  13.   derivatives based upon this software code base. 
  14. =============================================================================*/
  15. #include "stdafx.h"
  16. #include "browser.h"
  17. #include "Get.h"
  18. #include "db_cls.h"
  19. #include "tarfact.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Get dialog
  27. Get::Get(CWnd* pParent /*=NULL*/)
  28. : CDialog(Get::IDD, pParent)
  29. {
  30. //{{AFX_DATA_INIT(Get)
  31. m_mgmt_proto = _T("");
  32. m_net_proto = _T("");
  33. m_read_community = _T("");
  34. m_write_community = _T("");
  35. m_timeouts = _T("");
  36. m_retries = _T("");
  37. m_oid = _T("");
  38. m_output = _T("");
  39. //}}AFX_DATA_INIT
  40. int cstatus = Create(IDD, pParent);
  41. // create a snmp++ object
  42. int status;
  43. snmp = new Snmp( status);
  44. if ( status != SNMP_CLASS_SUCCESS)
  45. {
  46. AfxMessageBox("Unable To Create Snmp Object!");
  47. snmp = NULL;
  48. }
  49.     // load up the target list
  50.     CComboBox * target_cb = ( CComboBox *) GetDlgItem( IDC_TARGETS);
  51.     target_cb->ResetContent();
  52.     // get the db file name from the ini file
  53.     CString filename = theApp.GetProfileString( BROWSER_VALUE,DB_NAME,DEF_DB_NAME);
  54. // access the target database
  55.     Db target_db;
  56. TargetDb_Rec db_rec;
  57.     target_db.set_attributtes( filename, sizeof( TargetDb_Rec));
  58.     int nr = target_db.get_num_recs();
  59. if ( nr==0)
  60. AfxMessageBox("You Have No Targets Definedn Please Define a Target");
  61. // for all records, get and display
  62.     for (int i=1;i<=nr;i++)
  63.     {
  64.        if ((status = target_db.retrieve((long int) (i-1), &db_rec))!= DB_OK)
  65.        {
  66.           MessageBox("Unable to Read Target DB Record", ERR_MSG,MB_ICONSTOP);
  67.           return;
  68.        }
  69.    CString target_name;
  70.    if ( strcmp( db_rec.alias,"") ==0)
  71.          target_cb->AddString((char*)  db_rec.key);
  72.    else
  73.    {
  74.  target_name = db_rec.alias;
  75.  target_name += " @ ";
  76.  target_name += db_rec.key;
  77.  target_cb->AddString(target_name);
  78.    }
  79.        if ( i==1)
  80.        {
  81.           target_cb->SetCurSel(0);
  82.           load_target_attribs( db_rec);
  83.        }
  84. }
  85. }
  86. // load the current target view
  87. void Get::load_target_attribs( TargetDb_Rec db_rec)
  88. {
  89.    char buffer[20];
  90.    m_read_community = db_rec.read_community;
  91.    m_write_community = db_rec.write_community;
  92.    sprintf( buffer,"%d",db_rec.retries);
  93.    m_retries = buffer;
  94.    sprintf( buffer,"%d",db_rec.timeout);
  95.    m_timeouts = buffer;
  96.    m_mgmt_proto = (db_rec.snmp_type == SNMPV1) ? V1 :V2C;
  97.    m_net_proto =  (db_rec.address_type == IP_TYPE) ? "IP" : "IPX";
  98.    UpdateData( FALSE);
  99. };
  100. void Get::DoDataExchange(CDataExchange* pDX)
  101. {
  102. CDialog::DoDataExchange(pDX);
  103. //{{AFX_DATA_MAP(Get)
  104. DDX_Text(pDX, IDC_MGMTPROTO, m_mgmt_proto);
  105. DDX_Text(pDX, IDC_NETPROTO, m_net_proto);
  106. DDX_Text(pDX, IDC_READ_COMMUNITY, m_read_community);
  107. DDX_Text(pDX, IDC_WRITE_COMMUNITY, m_write_community);
  108. DDX_Text(pDX, IDC_TIMEOUTS, m_timeouts);
  109. DDX_Text(pDX, IDC_RETRIES, m_retries);
  110. DDX_Text(pDX, IDC_OID, m_oid);
  111. DDV_MaxChars(pDX, m_oid, 200);
  112. DDX_Text(pDX, IDC_OUTPUT, m_output);
  113. DDV_MaxChars(pDX, m_output, 1000);
  114. //}}AFX_DATA_MAP
  115. }
  116. BEGIN_MESSAGE_MAP(Get, CDialog)
  117. //{{AFX_MSG_MAP(Get)
  118. ON_CBN_SELCHANGE(IDC_TARGETS, OnSelchangeTargets)
  119. ON_WM_DESTROY()
  120. ON_BN_CLICKED(IDC_ADD, OnAdd)
  121. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  122. ON_NOTIFY(NM_DBLCLK, IDC_MIBTREE, OnDblclkMibtree)
  123. ON_BN_CLICKED(IDC_GET, OnGet)
  124. ON_BN_CLICKED(IDC_ADDOID, OnAddoid)
  125. ON_BN_CLICKED(IDC_STOP, OnStop)
  126. //}}AFX_MSG_MAP
  127. END_MESSAGE_MAP()
  128. /////////////////////////////////////////////////////////////////////////////
  129. // Get message handlers
  130. // load up the Ctree control with the MIB table
  131. void Get::load_mib_view( CTreeCtrl *tree)
  132. {
  133.  CString name;
  134.  Oid current_oid, parent_oid, next_oid,prev_parent_oid,*oid_ptr;
  135.  HTREEITEM new_node, parent_node, previous_parent;
  136.  parent_node = previous_parent = TVI_ROOT;
  137.  for (int x=0;x<MAXMIBVALS; x++)
  138.  {
  139.     name = MIBVals[x][0];   
  140. current_oid = MIBVals[x][2];   
  141. next_oid = ((x+1)==MAXMIBVALS)?"":MIBVals[x+1][2];   
  142. if ( current_oid.len() <= parent_oid.len())
  143. {
  144. parent_node = previous_parent;
  145. parent_oid = prev_parent_oid;
  146. }
  147. // add the node
  148. new_node = tree->InsertItem( name,parent_node);
  149. oid_ptr = new Oid( current_oid);
  150. if ( strcmp(MIBVals[x][1],SCALAR)==0)
  151.    (*oid_ptr)+="0";
  152. tree->SetItemData( new_node, (DWORD) oid_ptr);
  153. if ( name == "sysDescr")
  154.    tree->SelectItem( new_node);
  155. if (( current_oid.len() > parent_oid.len()) && ( current_oid.len() < next_oid.len()))
  156. {
  157.    previous_parent = parent_node;  
  158.    parent_node = new_node;         
  159.    prev_parent_oid = parent_oid;
  160.    parent_oid = current_oid;        
  161. }
  162.  };
  163. };
  164. BOOL Get::OnInitDialog() 
  165. {
  166. CDialog::OnInitDialog();
  167. // TODO: Add extra initialization here
  168. CenterWindow();
  169. // load up the MIB tree control
  170. CTreeCtrl *tree;
  171. tree = (CTreeCtrl *) GetDlgItem( IDC_MIBTREE);
  172. load_mib_view( tree);
  173. // clear the pdu table
  174. CListBox *lb;
  175. lb= ( CListBox*) GetDlgItem( IDC_PDU);
  176. lb->ResetContent();
  177. return TRUE;  // return TRUE unless you set the focus to a control
  178.               // EXCEPTION: OCX Property Pages should return FALSE
  179. }
  180. void Get::OnSelchangeTargets() 
  181. {
  182. // TODO: Add your control notification handler code here
  183. // access the target database
  184.     Db target_db;
  185. TargetDb_Rec db_rec;
  186. char key[80];
  187. char *ptr,*address;
  188. int status;
  189.  
  190.     CComboBox * target_cb = ( CComboBox *) GetDlgItem( IDC_TARGETS);
  191. target_cb->GetLBText( target_cb->GetCurSel() , key);
  192. // trim off alias, if present
  193. address = key;
  194. ptr = key;
  195. while (*ptr != 0)
  196. {
  197. if ( *ptr == '@')
  198.    address = ptr+2;
  199.    ptr++;
  200. }
  201.     // get the db file name from the ini file
  202.     CString filename = theApp.GetProfileString( BROWSER_VALUE,DB_NAME,DEF_DB_NAME);
  203. target_db.set_attributtes( filename, sizeof( TargetDb_Rec));
  204.     strcpy( db_rec.key,address);
  205.     status = target_db.read( &db_rec);
  206.     if ( status != DB_OK)
  207.     {
  208.        MessageBox( "Unable to Read Target Record",ERR_MSG,MB_ICONSTOP);
  209.        return;
  210.     }
  211.     load_target_attribs( db_rec);
  212. }
  213. // recursive delete of CtreeCtrl Items
  214. void Get::delete_nodes( CTreeCtrl *tree, HTREEITEM node)
  215. {
  216.     HTREEITEM next_node;
  217. Oid * oid_ptr;
  218.     next_node = tree->GetChildItem( node);
  219. if ( next_node != NULL)
  220. delete_nodes( tree, next_node);
  221. next_node = tree->GetNextSiblingItem( node);
  222. if ( next_node != NULL)
  223. delete_nodes( tree, next_node);
  224. oid_ptr = (Oid *) tree->GetItemData( node);
  225. if ( oid_ptr != NULL)
  226.    delete oid_ptr;
  227. }
  228. void Get::OnDestroy() 
  229. {
  230. CDialog::OnDestroy();
  231. // TODO: Add your message handler code here
  232. // need to free up CtreeCtrl's Oids
  233. CTreeCtrl *tree;
  234. tree = (CTreeCtrl *) GetDlgItem( IDC_MIBTREE);
  235. delete_nodes( tree, tree->GetRootItem());
  236. }
  237. void Get::OnAdd() 
  238. {
  239. // TODO: Add your control notification handler code here
  240. CTreeCtrl *tree;
  241. HTREEITEM node;
  242. Oid *oid_ptr;
  243. tree = (CTreeCtrl *) GetDlgItem( IDC_MIBTREE);
  244. node = tree->GetSelectedItem();
  245. oid_ptr = (Oid *) tree->GetItemData( node);
  246. if ( (*oid_ptr)[ oid_ptr->len() -1 ] != 0)
  247. {
  248. AfxMessageBox("You Must Select A Scalar MIB Object");
  249. return;
  250. }
  251. Oid addoid( oid_ptr->get_printable());
  252. CListBox *lb;
  253. lb = ( CListBox*) GetDlgItem( IDC_PDU);
  254. CString scalar;
  255. scalar = tree->GetItemText( node);
  256. scalar += " ";
  257. scalar += addoid.get_printable();
  258. lb->InsertString( lb->GetCount(),scalar);
  259. }
  260. void Get::OnRemove() 
  261. {
  262. // TODO: Add your control notification handler code here
  263. CListBox *lb;
  264. int selection;
  265. lb = ( CListBox*) GetDlgItem( IDC_PDU);
  266. if((selection = lb->GetCurSel()) != LB_ERR)
  267. lb->DeleteString( selection);
  268. }
  269. void Get::OnDblclkMibtree(NMHDR* pNMHDR, LRESULT* pResult) 
  270. {
  271. // TODO: Add your control notification handler code here
  272. OnAdd();
  273. *pResult = 0;
  274. }
  275. //====================================================================
  276. // SNMP++ callback function for async events
  277. // this callback is used for all async requests 
  278. void my_getcallback( int reason,
  279.                   Snmp* snmp,
  280.                   Pdu &pdu,
  281.                   SnmpTarget &target,
  282.                   void * callback_data)
  283.                                
  284. {  
  285.    // resolve the callback data to a MFC Get Window Handle
  286.    Get * get_window = (Get *) callback_data;
  287.    CButton * continue_mode = (CButton*) get_window->GetDlgItem( IDC_CONTINUOS);
  288.    // based on the reason handle the reason
  289.    switch ( reason)
  290.    { 
  291.   // an asynchronous response has arrived
  292.       case SNMP_CLASS_ASYNC_RESPONSE:
  293.   {
  294.   get_window->display_response( pdu, target, snmp);
  295.   // look for continuos mode
  296.           if (( continue_mode->GetCheck()) && (pdu.get_error_status()== 0))
  297.   get_window->get_another();
  298.   else
  299.   get_window->enable_controls( TRUE);
  300.   }
  301.   break;
  302.      
  303.   // a timeout has occured
  304.       case SNMP_CLASS_TIMEOUT:
  305.   get_window->display_timeout( target);
  306.   get_window->enable_controls( TRUE);
  307.   break;
  308.      
  309.    } // end switch
  310. };   
  311. // get another one
  312. void Get::get_another()
  313. {
  314. OnGet();
  315. };
  316. // display the response value
  317. void Get::display_response( Pdu &pdu, SnmpTarget &target, Snmp *snmp)
  318. {
  319.    GenAddress address;   // SNMP++ generic Address
  320.    Vb vb;
  321.    int error_status = pdu.get_error_status();
  322.    char buffer[50];
  323.    // show the result status
  324.    m_output = "Status = ";
  325.    m_output += snmp->error_msg( error_status);
  326.    m_output += "rn";
  327.    // show the details if check box is selected
  328.    CButton * all_details = (CButton*) GetDlgItem( IDC_ALL_DETAILS);
  329.    if ( all_details->GetCheck())
  330.    {
  331.       target.get_address( address);
  332.       m_output += "Response from ";
  333.   m_output += address.get_printable();
  334.   m_output += "rn";
  335.       m_output += "Error Status = ";
  336.   m_output += snmp->error_msg( error_status );
  337.   m_output += "rn";
  338.       sprintf( buffer,"Error Index  = %drn", pdu.get_error_index());
  339.       m_output += buffer;
  340.   sprintf( buffer,"Request ID  = %ldrn",pdu.get_request_id());
  341.   m_output += buffer;
  342.       sprintf( buffer,"Variable Binding Count = %drn",pdu.get_vb_count());
  343.       m_output += buffer;
  344.    }
  345.    // show the Vbs
  346.    for ( int x=0;x<pdu.get_vb_count();x++)
  347.    {
  348.       pdu.get_vb( vb,x);
  349.   sprintf( buffer,"Vb #%drn",x+1);
  350.   m_output += buffer;
  351.   m_output += "  Oid   = ";
  352.   m_output += vb.get_printable_oid();
  353.   m_output += "rn";
  354.   m_output += "  Value = ";
  355.   m_output += vb.get_printable_value();
  356.   m_output += "rn";
  357.    }
  358.    // update the output display
  359.    UpdateData( FALSE);
  360. };
  361. // display a timeout message
  362. void Get::display_timeout( SnmpTarget &target)
  363. {
  364.    m_output = "";
  365.    UpdateData( FALSE);
  366.    m_output = "Request Timed Out";
  367.    UpdateData( FALSE);
  368. };
  369. // invoke a SNMP++ Get
  370. void Get::OnGet() 
  371. {
  372. //------------------------------------------------------
  373. // Here is the real SNMP++ code !
  374. // 
  375. // Algorithm:
  376. // - build a Pdu using the Oids from the Pdu list box
  377. // - create a CTarget
  378. // - send an Asynchronous Get Request
  379. // - response will come to specified callback
  380. CListBox *lb;
  381. int count;
  382. char buffer[80],*ptr;
  383. Pdu pdu;          // SNMP++ Pdu object
  384. // get the ListBox id
  385. lb = ( CListBox*) GetDlgItem( IDC_PDU);
  386. // make sure we have something to get
  387. if ( (count=lb->GetCount()) <1)
  388. {
  389. AfxMessageBox("There are No PDU Variables to Get");
  390. return;
  391. }
  392. // build up a SNMP++ Pdu with all the Vbs requested
  393. for ( int z =0;z<count;z++)
  394. {
  395.    // get the text from the listbox
  396.    lb->GetText(z,buffer);
  397.    // get rid of the text part
  398.    ptr = buffer;
  399.    while (*ptr != ' ') ptr++;
  400.    ptr++;
  401.    // make a SNMP++ Oid with the dotted notation
  402.    Oid oid( ptr);      
  403.    // make a SNMP++ Vb with the oid
  404.    Vb vb( oid);
  405.    // add the vb to the Pdu
  406.    pdu += vb;
  407. }
  408. // make a SnmpTarget using the Target_Factory
  409. CComboBox *cb = ( CComboBox *) GetDlgItem( IDC_TARGETS);
  410. char key[80];
  411.     if ( cb->GetCurSel() == CB_ERR)
  412.     {
  413.        AfxMessageBox("No Target Selected!");
  414.        return;
  415.     }
  416. cb->GetLBText( cb->GetCurSel(), key); 
  417. // get a target from the target factory
  418. SnmpTarget *target = target_factory( key);
  419. if ( target == NULL)
  420. {
  421. AfxMessageBox("Unable To find Target");
  422. return;
  423. }
  424. // Invoke a SNMP++ Get for the Pdu requested
  425. // from the target created
  426. int status = snmp->get( pdu,
  427.                             *target,
  428.                             (snmp_callback) &my_getcallback,
  429.                             (void *) this);
  430.                                         
  431.     if ( status != SNMP_CLASS_SUCCESS)
  432. AfxMessageBox( snmp->error_msg( status));
  433. // clear the output display
  434. m_output = "SNMP++ Get In Progress...";
  435. UpdateData( FALSE);
  436. // free up the target when complete
  437. delete target;
  438. // disable all controls while get is pending
  439. enable_controls( FALSE);
  440. };
  441. // Manual Oid Specification
  442. void Get::OnAddoid() 
  443. {
  444. // TODO: Add your control notification handler code here
  445. UpdateData( TRUE);
  446. Oid oid( m_oid);
  447. if ( oid.valid())
  448. {
  449. CListBox *lb;
  450.     lb = ( CListBox*) GetDlgItem( IDC_PDU);
  451.     CString item;
  452.     item = "Custom ";
  453.     item += oid.get_printable();
  454.         lb->InsertString( lb->GetCount(),item);
  455. }
  456. else
  457. AfxMessageBox("Invalid Custom MIB Object Identifier");
  458. }
  459. // enable the controls
  460. void Get::enable_controls( int state)
  461. {
  462.    CWnd *control;
  463.    control = GetDlgItem( IDC_TARGETS);
  464.    control->EnableWindow( state ? TRUE : FALSE);
  465.    control = GetDlgItem( IDC_MIBTREE);
  466.    control->EnableWindow( state ? TRUE : FALSE);
  467.    control = GetDlgItem( IDC_ADD);
  468.    control->EnableWindow( state ? TRUE : FALSE);
  469.    control = GetDlgItem( IDC_REMOVE);
  470.    control->EnableWindow( state ? TRUE : FALSE);
  471.    control = GetDlgItem( IDC_PDU);
  472.    control->EnableWindow( state ? TRUE : FALSE);
  473.    control = GetDlgItem( IDC_OID);
  474.    control->EnableWindow( state ? TRUE : FALSE);
  475.    control = GetDlgItem( IDC_ADDOID);
  476.    control->EnableWindow( state ? TRUE : FALSE);
  477.    control = GetDlgItem( IDC_ALL_DETAILS);
  478.    control->EnableWindow( state ? TRUE : FALSE);
  479.    control = GetDlgItem( IDC_CONTINUOS);
  480.    control->EnableWindow( state ? TRUE : FALSE);
  481.   
  482. };
  483. void Get::OnStop() 
  484. {
  485. // TODO: Add your control notification handler code here
  486. CButton * continue_mode = (CButton*) GetDlgItem( IDC_CONTINUOS);
  487. continue_mode->SetCheck(0);
  488. }
  489. void Get::OnCancel() 
  490. {
  491. // TODO: Add extra cleanup here
  492. DestroyWindow();
  493. }