snmpmsg.cpp
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:23k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*_############################################################################
  2.   _## 
  3.   _##  snmpmsg.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.22
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2007 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Wed May  2 23:22:30 CEST 2007 
  27.   _##  
  28.   _##########################################################################*/
  29. /*===================================================================
  30.   Copyright (c) 1996
  31.   Hewlett-Packard Company
  32.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  33.   Permission to use, copy, modify, distribute and/or sell this software
  34.   and/or its documentation is hereby granted without fee. User agrees
  35.   to display the above copyright notice and this license notice in all
  36.   copies of the software and any documentation of the software. User
  37.   agrees to assume all liability for the use of the software; Hewlett-Packard
  38.   makes no representations about the suitability of this software for any
  39.   purpose. It is provided "AS-IS" without warranty of any kind,either express
  40.   or implied. User hereby grants a royalty-free license to any and all
  41.   derivatives based upon this software code base.
  42.   SNMP++ S N M P M S G . C P P
  43.   SNMPMESSAGE CLASS DEFINITION
  44.   DESIGN + AUTHOR:  Peter E Mellquist
  45.   LANGUAGE:         ANSI C++
  46.   DESCRIPTION:      ASN.1 encoding / decoding class
  47. =====================================================================*/
  48. char snmpmsg_cpp_version[]="#(@) SNMP++ $Id: snmpmsg.cpp 284 2007-03-22 22:09:46Z katz $";
  49. #ifdef WIN32
  50. #include <winsock.h>
  51. #elif defined(_AIX)
  52. #include <unistd.h>
  53. #endif
  54. #include <stdio.h>                      // standard io file
  55. #include "snmp_pp/snmpmsg.h"                    // header file for SnmpMessage
  56. #include "snmp_pp/oid_def.h"                    // changed (Frank Fock)
  57. #include "snmp_pp/log.h"
  58. #include "snmp_pp/vb.h"
  59. #ifdef SNMP_PP_NAMESPACE
  60. namespace Snmp_pp {
  61. #endif
  62. #define MAX_LEN_COMMUNITY 254
  63. const coldStartOid coldStart;
  64. const warmStartOid warmStart;
  65. const linkDownOid linkDown;
  66. const linkUpOid linkUp;
  67. const authenticationFailureOid authenticationFailure;
  68. const egpNeighborLossOid egpNeighborLoss;
  69. const snmpTrapEnterpriseOid snmpTrapEnterprise;
  70. //------------[ convert SNMP++ VB to WinSNMP smiVALUE ]----------------
  71. int convertVbToSmival( const Vb &tempvb, SmiVALUE *smival )
  72. {
  73.   smival->syntax = tempvb.get_syntax();
  74.   switch ( smival->syntax ) {
  75.     // case sNMP_SYNTAX_NULL
  76.   case sNMP_SYNTAX_NULL:
  77.   case sNMP_SYNTAX_NOSUCHOBJECT:
  78.   case sNMP_SYNTAX_NOSUCHINSTANCE:
  79.   case sNMP_SYNTAX_ENDOFMIBVIEW:
  80.     break;
  81.     // case sNMP_SYNTAX_INT32:
  82.   case sNMP_SYNTAX_INT:
  83.     tempvb.get_value(smival->value.sNumber);
  84.     break;
  85.     //    case sNMP_SYNTAX_UINT32:
  86.   case sNMP_SYNTAX_GAUGE32:
  87.   case sNMP_SYNTAX_CNTR32:
  88.   case sNMP_SYNTAX_TIMETICKS:
  89.     //  case sNMP_SYNTAX_UINT32:
  90.     tempvb.get_value(smival->value.uNumber);
  91.     break;
  92.     // case Counter64
  93.   case sNMP_SYNTAX_CNTR64:
  94.     {
  95.       Counter64 c64;
  96.       tempvb.get_value(c64);
  97.       smival->value.hNumber.hipart = c64.high();
  98.       smival->value.hNumber.lopart = c64.low();
  99.     }
  100.     break;
  101.   case sNMP_SYNTAX_BITS:
  102.   case sNMP_SYNTAX_OCTETS:
  103.   case sNMP_SYNTAX_OPAQUE:
  104.   case sNMP_SYNTAX_IPADDR:
  105.     {
  106.       OctetStr os;
  107.       tempvb.get_value(os);
  108.       smival->value.string.ptr = NULL;
  109.       smival->value.string.len = os.len();
  110.       if ( smival->value.string.len > 0 )
  111.       {
  112.         smival->value.string.ptr
  113.           = (SmiLPBYTE) new  unsigned char [smival->value.string.len];
  114.         if ( smival->value.string.ptr )
  115.         {
  116.           for (int i=0; i<(int) smival->value.string.len ; i++)
  117.             smival->value.string.ptr[i] = os[i];
  118.         }
  119.         else
  120.         {
  121.           smival->syntax = sNMP_SYNTAX_NULL;  // invalidate the smival
  122.           return SNMP_CLASS_RESOURCE_UNAVAIL;
  123.         }
  124.       }
  125.     }
  126.     break;
  127.   case sNMP_SYNTAX_OID:
  128.     {
  129.       Oid oid;
  130.       tempvb.get_value(oid);
  131.       smival->value.oid.ptr = NULL;
  132.       smival->value.oid.len = oid.len();
  133.       if ( smival->value.oid.len > 0 )
  134.       {
  135.         smival->value.oid.ptr
  136.           = (SmiLPUINT32) new unsigned long [ smival->value.oid.len];
  137.         if ( smival->value.oid.ptr )
  138.         {
  139.           for (int i=0; i<(int)smival->value.oid.len ; i++)
  140.             smival->value.oid.ptr[i] = oid[i];
  141.         }
  142.         else
  143.         {
  144.           smival->syntax = sNMP_SYNTAX_NULL;  // invalidate the smival
  145.           return SNMP_CLASS_RESOURCE_UNAVAIL;
  146.         }
  147.       }
  148.     }
  149.     break;
  150.   default:
  151.     return SNMP_CLASS_INTERNAL_ERROR;
  152.   }
  153.   return SNMP_CLASS_SUCCESS;
  154. }
  155. // free a SMI value
  156. void freeSmivalDescriptor( SmiVALUE *smival )
  157. {
  158.   switch ( smival->syntax ) {
  159.   case sNMP_SYNTAX_OCTETS:
  160.   case sNMP_SYNTAX_OPAQUE:
  161.   case sNMP_SYNTAX_IPADDR:
  162.   case sNMP_SYNTAX_BITS:     // obsoleted in SNMPv2 Draft Std
  163.     delete [] smival->value.string.ptr;
  164.     break;
  165.   case sNMP_SYNTAX_OID:
  166.     delete [] smival->value.oid.ptr;
  167.     break;
  168.   }
  169.   smival->syntax = sNMP_SYNTAX_NULL;
  170. }
  171. #ifdef _SNMPv3
  172. int SnmpMessage::unloadv3( Pdu &pdu,                // Pdu returned
  173.                            snmp_version &version,   // version
  174.                            OctetStr &engine_id,     // optional v3
  175.                            OctetStr &security_name, // optional v3
  176.                            long int &security_model,
  177.                            UdpAddress &from_addr,
  178.    Snmp &snmp_session)
  179. {
  180.   OctetStr tmp;
  181.   return unload(pdu, tmp, version, &engine_id,
  182.                 &security_name, &security_model, &from_addr, &snmp_session);
  183. }
  184. #endif
  185. int SnmpMessage::load(const Pdu &cpdu,
  186.                       const OctetStr &community,
  187.                       const snmp_version version,
  188.                       const OctetStr* engine_id,
  189.                       const OctetStr* security_name,
  190.                       const int security_model)
  191. {
  192.   int status;
  193.   const Pdu *pdu = &cpdu;
  194.   Pdu temppdu;
  195.   // make sure pdu is valid
  196.   if ( !pdu->valid())
  197.     return SNMP_CLASS_INVALID_PDU;
  198.   // create a raw pdu
  199.   snmp_pdu *raw_pdu;
  200.   raw_pdu = snmp_pdu_create( (int) pdu->get_type());
  201.   Oid enterprise;
  202.   // load it up
  203.   raw_pdu->reqid = pdu->get_request_id();
  204. #ifdef _SNMPv3
  205.   raw_pdu->msgid = pdu->get_message_id();
  206. #endif
  207.   raw_pdu->errstat= (unsigned long) pdu->get_error_status();
  208.   raw_pdu->errindex= (unsigned long) pdu->get_error_index();
  209.   // if its a V1 trap then load up other values
  210.   // for v2, use normal pdu format
  211.   if (raw_pdu->command == sNMP_PDU_V1TRAP)
  212.   {
  213.     // DON'T forget about the v1 trap agent address (changed by Frank Fock)
  214.     GenAddress gen_addr;
  215.     IpAddress ip_addr;
  216.     int addr_set = FALSE;
  217.     if (pdu->get_v1_trap_address(gen_addr))
  218.     {
  219.       /* User did set the v1 trap address */
  220.       if ((gen_addr.get_type() != Address::type_ip) &&
  221.           (gen_addr.get_type() != Address::type_udp) )
  222.       {
  223. LOG_BEGIN(ERROR_LOG | 4);
  224. LOG("SNMPMessage: Bad v1 trap address type in pdu");
  225. LOG(gen_addr.get_type());
  226. LOG_END;
  227.         snmp_free_pdu( raw_pdu);
  228.         return SNMP_CLASS_INVALID_PDU;
  229.       }
  230.       ip_addr = gen_addr;
  231.       if (!ip_addr.valid())
  232.       {
  233. LOG_BEGIN(ERROR_LOG | 1);
  234. LOG("SNMPMessage: Copied v1 trap address not valid");
  235. LOG_END;
  236.         snmp_free_pdu( raw_pdu);
  237.         return SNMP_CLASS_RESOURCE_UNAVAIL;
  238.       }
  239.       addr_set = TRUE;
  240.     }
  241.     else
  242.     {
  243.       /* User did not set the v1 trap address */
  244.       char addrString[256];
  245.       if (gethostname(addrString, 255) == 0)
  246.       {
  247.           ip_addr = addrString;
  248.           addr_set = TRUE;
  249.       }
  250.     }
  251.     struct sockaddr_in agent_addr;  // agent address socket struct
  252.     // prepare the agent address
  253.     memset(&agent_addr, 0, sizeof(agent_addr));
  254.     agent_addr.sin_family = AF_INET;
  255.     if (addr_set)
  256.     {
  257.       agent_addr.sin_addr.s_addr
  258.         = inet_addr(((IpAddress &)ip_addr).IpAddress::get_printable());
  259.       LOG_BEGIN(INFO_LOG | 7);
  260.       LOG("SNMPMessage: Setting v1 trap address");
  261.       LOG(((IpAddress &)ip_addr).IpAddress::get_printable());
  262.       LOG_END;
  263.     }
  264.     raw_pdu->agent_addr = agent_addr;
  265.     //-----[ compute generic trap value ]-------------------------------
  266.     // determine the generic value
  267.     // 0 - cold start
  268.     // 1 - warm start
  269.     // 2 - link down
  270.     // 3 - link up
  271.     // 4 - authentication failure
  272.     // 5 - egpneighborloss
  273.     // 6 - enterprise specific
  274.     Oid trapid;
  275.     pdu->get_notify_id( trapid);
  276.     if ( !trapid.valid() || trapid.len() < 2 )
  277.       {
  278.         snmp_free_pdu( raw_pdu);
  279.         return SNMP_CLASS_INVALID_NOTIFYID;
  280.       }
  281.     raw_pdu->specific_type=0;
  282.     if ( trapid == coldStart)
  283.       raw_pdu->trap_type = 0;  // cold start
  284.     else if ( trapid == warmStart)
  285.       raw_pdu->trap_type = 1;  // warm start
  286.     else if( trapid == linkDown)
  287.       raw_pdu->trap_type = 2;  // link down
  288.     else if ( trapid == linkUp)
  289.       raw_pdu->trap_type = 3;  // link up
  290.     else if ( trapid == authenticationFailure )
  291.       raw_pdu->trap_type = 4;  // authentication failure
  292.     else if ( trapid == egpNeighborLoss)
  293.       raw_pdu->trap_type = 5;  // egp neighbor loss
  294.     else {
  295.       raw_pdu->trap_type = 6;     // enterprise specific
  296.       // last oid subid is the specific value
  297.       // if 2nd to last subid is "0", remove it
  298.       // enterprise is always the notify oid prefix
  299.       raw_pdu->specific_type = (int) trapid[(int) (trapid.len()-1)];
  300.       trapid.trim(1);
  301.       if ( trapid[(int)(trapid.len()-1)] == 0 )
  302.         trapid.trim(1);
  303.       enterprise = trapid;
  304.     }
  305.     if ( raw_pdu->trap_type !=6)
  306.       pdu->get_notify_enterprise( enterprise);
  307.     if ( enterprise.len() >0) {
  308.       // note!!
  309.       // these are hooks into an SNMP++ oid
  310.       // and therefor the raw_pdu enterprise
  311.       // should not free them. null them out!!
  312.       SmiLPOID rawOid;
  313.       rawOid = enterprise.oidval();
  314.       raw_pdu->enterprise = rawOid->ptr;
  315.       raw_pdu->enterprise_length = (int) rawOid->len;
  316.     }
  317.     // timestamp
  318.     TimeTicks timestamp;
  319.     pdu->get_notify_timestamp( timestamp);
  320.     raw_pdu->time = ( unsigned long) timestamp;
  321.   }
  322.   // if its a v2 trap then we need to make a few adjustments
  323.   // vb #1 is the timestamp
  324.   // vb #2 is the id, represented as an Oid
  325.   if (( raw_pdu->command == sNMP_PDU_TRAP) ||
  326.       ( raw_pdu->command == sNMP_PDU_INFORM))
  327.   {
  328.     Vb tempvb;
  329.     temppdu = *pdu;
  330.     temppdu.trim(temppdu.get_vb_count());
  331.     // vb #1 is the timestamp
  332.     TimeTicks timestamp;
  333.     tempvb.set_oid(SNMP_MSG_OID_SYSUPTIME);   // sysuptime
  334.     pdu->get_notify_timestamp( timestamp);
  335.     tempvb.set_value ( timestamp);
  336.     temppdu += tempvb;
  337.     // vb #2 is the id
  338.     Oid trapid;
  339.     tempvb.set_oid(SNMP_MSG_OID_TRAPID);
  340.     pdu->get_notify_id( trapid);
  341.     tempvb.set_value( trapid);
  342.     temppdu += tempvb;
  343.     // append the remaining vbs
  344.     for (int z=0; z<pdu->get_vb_count(); z++) {
  345.       pdu->get_vb( tempvb,z);
  346.       temppdu += tempvb;
  347.     }
  348.     pdu = &temppdu;          // reassign the pdu to the temp one
  349.   }
  350.   // load up the payload
  351.   // for all Vbs in list, add them to the pdu
  352.   int vb_count;
  353.   Vb tempvb;
  354.   Oid tempoid;
  355.   SmiLPOID smioid;
  356.   SmiVALUE smival;
  357.   vb_count = pdu->get_vb_count();
  358.   for (int z=0;z<vb_count;z++) {
  359.     pdu->get_vb( tempvb,z);
  360.     tempvb.get_oid( tempoid);
  361.     smioid = tempoid.oidval();
  362.     // clear the value portion, in case its
  363.     // not already been done so by the app writer
  364.     // only do it in the case its a get,next or bulk
  365.     if ((raw_pdu->command == sNMP_PDU_GET) ||
  366.         (raw_pdu->command == sNMP_PDU_GETNEXT) ||
  367.         (raw_pdu->command == sNMP_PDU_GETBULK))
  368.       tempvb.set_null();
  369.     status = convertVbToSmival( tempvb, &smival );
  370.     if ( status != SNMP_CLASS_SUCCESS) {
  371.       snmp_free_pdu( raw_pdu);
  372.       return status;
  373.     }
  374.     // add the vb to the raw pdu
  375.     snmp_add_var( raw_pdu, smioid->ptr, (int) smioid->len, &smival);
  376.     freeSmivalDescriptor( &smival);
  377.   }
  378.   // ASN1 encode the pdu
  379. #ifdef _SNMPv3
  380.   if (version == version3)
  381.   {
  382.     if ((!engine_id) || (!security_name))
  383.     {
  384.       LOG_BEGIN(ERROR_LOG | 4);
  385.       LOG("SNMPMessage: Need security name and engine id for v3 message");
  386.       LOG_END;
  387.       // prevention of SNMP++ Enterprise Oid death
  388.       if ( enterprise.len() >0) {
  389. raw_pdu->enterprise = 0;
  390. raw_pdu->enterprise_length=0;
  391.       }
  392.       snmp_free_pdu( raw_pdu);
  393.       return SNMP_CLASS_INVALID_TARGET;
  394.     }
  395.     status = v3MP::I->snmp_build(raw_pdu, databuff, (int *)&bufflen,
  396.  *engine_id, *security_name, security_model,
  397.  pdu->get_security_level(),
  398.  pdu->get_context_engine_id(),
  399.  pdu->get_context_name());
  400.     if (status == SNMPv3_MP_OK) {
  401.       if ((pdu->get_type() == sNMP_PDU_RESPONSE) &&
  402.           ((int)pdu->get_maxsize_scopedpdu() < pdu->get_asn1_length())) {
  403. LOG_BEGIN(ERROR_LOG | 1);
  404. LOG("SNMPMessage: *BUG*: Serialized response pdu is too big (len) (max)");
  405. LOG(pdu->get_asn1_length());
  406. LOG(pdu->get_maxsize_scopedpdu());
  407. LOG_END;
  408.         // prevention of SNMP++ Enterprise Oid death
  409.         if ( enterprise.len() >0) {
  410.           raw_pdu->enterprise = 0;
  411.           raw_pdu->enterprise_length=0;
  412.         }
  413.         snmp_free_pdu( raw_pdu);
  414.         return SNMP_ERROR_TOO_BIG;
  415.       }
  416.     }
  417.   }
  418.   else
  419. #endif
  420.     status = snmp_build( raw_pdu, databuff, (int *) &bufflen, version,
  421.                          community.data(), (int) community.len());
  422.   LOG_BEGIN(DEBUG_LOG | 4);
  423.   LOG("SNMPMessage: return value for build message");
  424.   LOG(status);
  425.   LOG_END;
  426.   if ((status != 0)
  427. #ifdef _SNMPv3
  428.       && ((version != version3) || (status != SNMPv3_MP_OK))
  429. #endif
  430.       ) {
  431.     valid_flag = false;
  432.     // prevention of SNMP++ Enterprise Oid death
  433.     if ( enterprise.len() >0) {
  434.       raw_pdu->enterprise = 0;
  435.       raw_pdu->enterprise_length=0;
  436.     }
  437.     snmp_free_pdu( raw_pdu);
  438. #ifdef _SNMPv3
  439.     if (version == version3)
  440.       return status;
  441.     else
  442. #endif
  443.       // NOTE: This is an assumption - in most cases during normal
  444.       // operation the reason is a tooBig - another could be a
  445.       // damaged variable binding.
  446.       return SNMP_ERROR_TOO_BIG;
  447.   }
  448.   valid_flag = true;
  449.   // prevention of SNMP++ Enterprise Oid death
  450.   if ( enterprise.len() >0) {
  451.     raw_pdu->enterprise = 0;
  452.     raw_pdu->enterprise_length=0;
  453.   }
  454.   snmp_free_pdu( raw_pdu);
  455.   return SNMP_CLASS_SUCCESS;
  456. }
  457. // load up a SnmpMessage
  458. int SnmpMessage::load( unsigned char *data,
  459.                        unsigned long len)
  460. {
  461.   bufflen = MAX_SNMP_PACKET;
  462.   valid_flag = false;
  463.   if (len <= MAX_SNMP_PACKET)
  464.   {
  465.     memcpy( (unsigned char *) databuff, (unsigned char *) data,
  466.             (unsigned int) len);
  467.     bufflen = len;
  468.     valid_flag = true;
  469.   }
  470.   else
  471.     return SNMP_ERROR_WRONG_LENGTH;
  472.   return SNMP_CLASS_SUCCESS;
  473. }
  474. // unload the data into SNMP++ objects
  475. int SnmpMessage::unload(Pdu &pdu,                 // Pdu object
  476. OctetStr &community,      // community object
  477. snmp_version &version,    // SNMP version #
  478.                         OctetStr *engine_id,      // optional v3
  479.                         OctetStr *security_name,  // optional v3
  480.                         long int *security_model,
  481.                         UdpAddress *from_addr,
  482.                         Snmp *snmp_session)
  483. {
  484.   pdu.clear();
  485.   if (!valid_flag)
  486.     return SNMP_CLASS_INVALID;
  487.   snmp_pdu *raw_pdu;
  488.   raw_pdu = snmp_pdu_create(0); // do a "snmp_free_pdu( raw_pdu)" before return
  489.   int status;
  490. #ifdef _SNMPv3
  491.   OctetStr context_engine_id;
  492.   OctetStr context_name;
  493.   long int security_level;
  494.   if ((security_model) && (security_name) && (engine_id) && (snmp_session)) {
  495.     status = v3MP::I->snmp_parse(snmp_session, raw_pdu,
  496.                          databuff, (int)bufflen, *engine_id,
  497.                          *security_name, context_engine_id, context_name,
  498.                          security_level, *security_model, version, *from_addr);
  499.     if (status != SNMPv3_MP_OK) {
  500.       pdu.set_request_id( raw_pdu->reqid);
  501.       pdu.set_type( raw_pdu->command);
  502.       snmp_free_pdu( raw_pdu);
  503.       return status;
  504.     }
  505.     pdu.set_context_engine_id(context_engine_id);
  506.     pdu.set_context_name(context_name);
  507.     pdu.set_security_level(security_level);
  508.     pdu.set_message_id(raw_pdu->msgid);
  509.     pdu.set_maxsize_scopedpdu(raw_pdu->maxsize_scopedpdu);
  510.   }
  511.   else {
  512. #endif
  513.     unsigned char community_name[MAX_LEN_COMMUNITY + 1];
  514.     int           community_len = MAX_LEN_COMMUNITY + 1;
  515.     status = snmp_parse(raw_pdu, databuff, (int) bufflen,
  516.                         community_name, community_len, version);
  517.     if (status != SNMP_CLASS_SUCCESS) {
  518.       snmp_free_pdu(raw_pdu);
  519.       return status;
  520.     }
  521.     community.set_data( community_name, community_len);
  522. #ifdef _SNMPv3
  523.   }
  524. #endif
  525.   // load up the SNMP++ variables
  526.   pdu.set_request_id(raw_pdu->reqid);
  527.   pdu.set_error_status((int) raw_pdu->errstat);
  528.   pdu.set_error_index((int) raw_pdu->errindex);
  529.   pdu.set_type( raw_pdu->command);
  530.   // deal with traps a little different
  531.   if ( raw_pdu->command == sNMP_PDU_V1TRAP) {
  532.     // timestamp
  533.     TimeTicks timestamp;
  534.     timestamp = raw_pdu->time;
  535.     pdu.set_notify_timestamp( timestamp);
  536.     // set the agent address
  537.     IpAddress agent_addr(inet_ntoa(raw_pdu->agent_addr.sin_addr));
  538.     if (agent_addr != "0.0.0.0")
  539.     {
  540.       pdu.set_v1_trap_address(agent_addr);
  541.       LOG_BEGIN(DEBUG_LOG | 4);
  542.       LOG("SNMPMessage: Trap address of received v1 trap");
  543.       LOG(agent_addr.get_printable());
  544.       LOG_END;
  545.     }
  546.     // set enterprise, notifyid
  547.     Oid enterprise;
  548.     if (raw_pdu->enterprise_length >0) {
  549.       for (int i=0; i< raw_pdu->enterprise_length; i++) {
  550.         enterprise += (int) (raw_pdu->enterprise[i]);
  551.       }
  552.       pdu.set_notify_enterprise(enterprise);
  553.     }
  554.     switch (raw_pdu->trap_type) {
  555.     case 0:
  556.       pdu.set_notify_id(coldStart);
  557.       break;
  558.     case 1:
  559.       pdu.set_notify_id(warmStart);
  560.       break;
  561.     case 2:
  562.       pdu.set_notify_id(linkDown);
  563.       break;
  564.     case 3:
  565.       pdu.set_notify_id(linkUp);
  566.       break;
  567.     case 4:
  568.       pdu.set_notify_id(authenticationFailure);
  569.       break;
  570.     case 5:
  571.       pdu.set_notify_id(egpNeighborLoss);
  572.       break;
  573.     case 6: { // enterprise specific
  574.       // base id + specific #
  575.       Oid eOid = enterprise;
  576.       eOid += 0ul;
  577.       eOid += raw_pdu->specific_type;
  578.       pdu.set_notify_id( eOid);
  579.       break;
  580.       }
  581.     default:
  582.       {
  583. LOG_BEGIN(WARNING_LOG | 3);
  584. LOG("SNMPMessage: Received trap with illegal trap type");
  585. LOG(raw_pdu->trap_type);
  586. LOG_END;
  587.       }
  588.     }
  589.   }
  590.   // vbs
  591.   Vb tempvb;
  592.   Oid tempoid;
  593.   struct   variable_list *vp;
  594.   int vb_nr = 1;
  595.   for(vp = raw_pdu->variables; vp; vp = vp->next_variable, vb_nr++) {
  596.     // extract the oid portion
  597.     tempoid.set_data( (unsigned long *)vp->name,
  598.                       ( unsigned int) vp->name_length);
  599.     tempvb.set_oid( tempoid);
  600.     // extract the value portion
  601.     switch(vp->type){
  602.       // octet string
  603.     case sNMP_SYNTAX_OCTETS:
  604.       {
  605. OctetStr octets( (unsigned char *) vp->val.string,
  606.  (unsigned long) vp->val_len);
  607. tempvb.set_value( octets);
  608.       }
  609.       break;
  610.     case sNMP_SYNTAX_OPAQUE:
  611.       {
  612. OpaqueStr octets( (unsigned char *) vp->val.string,
  613.           (unsigned long) vp->val_len);
  614. tempvb.set_value( octets);
  615.       }
  616.       break;
  617.       // object id
  618.     case sNMP_SYNTAX_OID:
  619.       {
  620. Oid oid( (unsigned long*) vp->val.objid,
  621.  (int) vp->val_len);
  622. tempvb.set_value( oid);
  623.         if ((vb_nr == 2) &&
  624.             ((raw_pdu->command == sNMP_PDU_TRAP) ||
  625.              (raw_pdu->command == sNMP_PDU_INFORM)) &&
  626.             (tempoid == SNMP_MSG_OID_TRAPID))
  627.         {
  628.           // set notify_id
  629.           pdu.set_notify_id(oid);
  630.   continue; // don't add vb to pdu
  631.         }
  632.       }
  633.       break;
  634.       // timeticks
  635.     case sNMP_SYNTAX_TIMETICKS:
  636.       {
  637. TimeTicks timeticks( (unsigned long) *(vp->val.integer));
  638. tempvb.set_value( timeticks);
  639.         if ((vb_nr == 1) &&
  640.             ((raw_pdu->command == sNMP_PDU_TRAP) ||
  641.              (raw_pdu->command == sNMP_PDU_INFORM)) &&
  642.             (tempoid == SNMP_MSG_OID_SYSUPTIME))
  643.         {
  644.           // set notify_timestamp
  645.           pdu.set_notify_timestamp( timeticks);
  646.   continue; // don't add vb to pdu
  647.         }
  648.       }
  649.       break;
  650.       // 32 bit counter
  651.     case sNMP_SYNTAX_CNTR32:
  652.       {
  653. Counter32 counter32( (unsigned long) *(vp->val.integer));
  654. tempvb.set_value( counter32);
  655.       }
  656.       break;
  657.       // 32 bit gauge
  658.     case sNMP_SYNTAX_GAUGE32:
  659.       {
  660. Gauge32 gauge32( (unsigned long) *(vp->val.integer));
  661. tempvb.set_value( gauge32);
  662.       }
  663.       break;
  664.       // ip address
  665.     case sNMP_SYNTAX_IPADDR:
  666.       {
  667. char buffer[42];
  668. if (vp->val_len == 16)
  669.   sprintf( buffer, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
  670.    "%02x%02x:%02x%02x:%02x%02x:%02x%02x",
  671.    vp->val.string[ 0], vp->val.string[ 1], vp->val.string[ 2],
  672.    vp->val.string[ 3], vp->val.string[ 4], vp->val.string[ 5],
  673.    vp->val.string[ 6], vp->val.string[ 7], vp->val.string[ 8],
  674.    vp->val.string[ 9], vp->val.string[10], vp->val.string[11],
  675.    vp->val.string[12], vp->val.string[13], vp->val.string[14],
  676.    vp->val.string[15]);
  677. else
  678.   sprintf( buffer,"%d.%d.%d.%d",
  679.    vp->val.string[0], vp->val.string[1],
  680.    vp->val.string[2], vp->val.string[3]);
  681. IpAddress ipaddress( buffer);
  682. tempvb.set_value( ipaddress);
  683.       }
  684.       break;
  685.       // 32 bit integer
  686.     case sNMP_SYNTAX_INT:
  687.       {
  688. SnmpInt32 int32( (long) *(vp->val.integer));
  689. tempvb.set_value( int32);
  690.       }
  691.       break;
  692.       // 32 bit unsigned integer
  693. /* Not distinguishable from Gauge32
  694.     case sNMP_SYNTAX_UINT32:
  695.       {
  696. SnmpUInt32 uint32( (unsigned long) *(vp->val.integer));
  697. tempvb.set_value( uint32);
  698.       }
  699.       break;
  700. */
  701.       // v2 counter 64's
  702.     case sNMP_SYNTAX_CNTR64:
  703.       { // Frank Fock (was empty before)
  704. Counter64 c64(((counter64*)vp->val.counter64)->high,
  705.       ((counter64*)vp->val.counter64)->low);
  706. tempvb.set_value( c64);
  707. break;
  708.       }
  709.     case sNMP_SYNTAX_NULL:
  710.     tempvb.set_null();
  711.     break;
  712.     // v2 vb exceptions
  713.     case sNMP_SYNTAX_NOSUCHOBJECT:
  714.     case sNMP_SYNTAX_NOSUCHINSTANCE:
  715.     case sNMP_SYNTAX_ENDOFMIBVIEW:
  716.       tempvb.set_exception_status(vp->type);
  717.       break;
  718.     default:
  719.       tempvb.set_null();
  720.     } // end switch
  721.     // append the vb to the pdu
  722.     pdu += tempvb;
  723.   }
  724.   snmp_free_pdu( raw_pdu);
  725.   return SNMP_CLASS_SUCCESS;
  726. }
  727. #ifdef SNMP_PP_NAMESPACE
  728. }; // end of namespace Snmp_pp
  729. #endif