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

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