www.pudn.com > snmp.rar > snmpget.c


#include 
#include 
#include 
#include 
#include 

#define DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#define SNMP_DEBUG(name) snmp_perror(name)

#define __MD5 (1)
#define __SHA (2)

#define __DES (1)
#define __AES (2)

struct snmp_sess_data{
  char *hostname;
  char *community;
  char *security_name;
  int snmp_version;
  int security_level;
  int auth_type;
  int priv_type;
  char *auth_key;
  char *priv_key;
};

int set_snmp_sess(struct snmp_session *session, struct snmp_sess_data *session_data, const char *name);
int set_snmp_pdu(struct snmp_pdu **pdu, u_char pdu_type, int init, const char *objname);
int send_snmp_pdu(struct snmp_session *session, struct snmp_pdu *pdu, struct snmp_pdu **response);
int handle_snmp_pdu(struct snmp_pdu *response);

int main()
{
  int status = 0;
  struct snmp_sess_data data;
  
  data.hostname = strdup("172.16.42.240");
  data.community = strdup("public");
  data.security_name = strdup("wanted");
  data.snmp_version = SNMP_VERSION_3;
  data.security_level = SNMP_SEC_LEVEL_AUTHPRIV;
  data.auth_type = __MD5;
  data.priv_type = __DES;
  data.auth_key = strdup("12345678");
  data.priv_key = strdup("23456789");
  
  struct snmp_session session;
  struct snmp_pdu *pdu;
  struct snmp_pdu *response;

  status = set_snmp_sess(&session, &data, "snmpv3");
  if(status != 0)
    {
      DEBUG("Prepare snmp session faild : %d\n", status);
      exit(-1);
    }
  
  status = set_snmp_pdu(&pdu, SNMP_MSG_GET, 1, "SNMPv2-MIB::sysLocation.0");
  if(status != 0)
    {
      DEBUG("Prepare snmp pdu faild : %d\n", status);
      exit(-1);
    }

  status = set_snmp_pdu(&pdu, SNMP_MSG_GET, 0, "SNMPv2-MIB::sysContact.0");
  if(status != 0)
    {
      DEBUG("Prepare snmp pdu faild :%d\n", status);
      exit(-1);
    }

  status = set_snmp_pdu(&pdu, SNMP_MSG_GET, 0, "SNMPv2-MIB::sysDescr.0");
  if(status != 0)
    {
      DEBUG("Prepare snmp pdu failed :%d\n", status);
      exit(-1);
    }

  status = send_snmp_pdu(&session, pdu, &response);
  if(status != 0)
    {
      DEBUG("Send snmp pdu failed :%d\n", status);
      exit(-1);
    }

  status = handle_snmp_pdu(response);
  if(status != 0)
    {
      DEBUG("Handld snmp pdu failed :%d\n", status);
      exit(-1);
    }

  return 0;
}

int set_snmp_sess(struct snmp_session *session, struct snmp_sess_data *session_data, const char *name)
{
  assert(session != NULL);
  assert(session_data != NULL);
  assert(name != NULL);
  
  int status = 0;

  /*initialize snmp libaray */
  init_snmp(name);
   
  /*initialize a session */
  snmp_sess_init(session);

  session->peername = session_data->hostname;
  session->version = session_data->snmp_version;
 
  if(session->version == SNMP_VERSION_1 || session->version == SNMP_VERSION_2c)
    {
      session->community = (u_char *) session_data->community;
      session->community_len = strlen(session_data->community);
    }
  else if(session->version == SNMP_VERSION_3)
    {

      if( session_data->security_level != SNMP_SEC_LEVEL_AUTHNOPRIV && 
	  session_data->security_level != SNMP_SEC_LEVEL_AUTHPRIV &&
	  session_data->security_level != SNMP_SEC_LEVEL_NOAUTH)
	{
	  DEBUG("SecurityLevel invalid :%d\n", session->securityLevel);
	  return -1;
	}
      
      /************** SNMPv3 settings *********************/
      session->securityName = session_data->security_name;
      session->securityNameLen = strlen(session->securityName);

      /* set the security level to authenticated and encrypted*/
      session->securityLevel = session_data->security_level;
      session->securityAuthKeyLen = USM_AUTH_KU_LEN;

      if( session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV ||
          session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV )
        {
          /* set authentication method */
          if( session_data->auth_type == __MD5 )
            {

              /* set the authentication method to MD5 */
              session->securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol,
								USM_AUTH_PROTO_MD5_LEN);
              session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
            }
          else if( session_data->auth_type == __SHA )
            {

              /* set authentication method to SHA*/
              session->securityAuthProto = snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
								USM_AUTH_PROTO_SHA_LEN);
              session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
            }
	  else
            {
              /* authentication method invalid */
              DEBUG("Invalid authentication method %d\n", session_data->auth_type);
              return -1;
	    }

	  if ( (status = generate_Ku(session->securityAuthProto,  session->securityAuthProtoLen,
				     (u_char *) session_data->auth_key, strlen(session_data->auth_key),
				     session->securityAuthKey,  &session->securityAuthKeyLen)) != SNMPERR_SUCCESS )

            {
	      DEBUG("Error generating a key (Ku) from the supplied authentication pass phrase %d\n", status);
              return -2;
            }

	}

      if( session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV )
        {
	  session->securityPrivKeyLen = USM_PRIV_KU_LEN;

          /* set encrypted method */
          if( session_data->priv_type == __DES )
            {

              /* set the encrypted method to DES */
              session->securityPrivProto =  snmp_duplicate_objid(usmDESPrivProtocol,
								 USM_PRIV_PROTO_DES_LEN);
              session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;

            }
          else if( session_data->priv_type == __AES )
            {

              /* set the encrypted method to AES */
              session->securityPrivProto =  snmp_duplicate_objid(usmAESPrivProtocol,
								 USM_PRIV_PROTO_AES_LEN);
              session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;

            }
          else
            {
              /* authentication method invalid */
              DEBUG("Invalid privacy method specified : %d \n", session_data->priv_type);
              return -1;
            }
	  
	  if ( (status = generate_Ku(session->securityAuthProto, session->securityAuthProtoLen,
				     (u_char *) session_data->priv_key , strlen(session_data->priv_key),
				     session->securityPrivKey, &session->securityPrivKeyLen)) != SNMPERR_SUCCESS )
            {
	      DEBUG("Error generating a key (Ku) from the supplied privacy pass phrase : %d", status);
              return  -2;
            }
	}
    }
  else
    {
      DEBUG("Invalid snmp version specified : %ld\n", session->version);
      return -1;
    }

  return 0;
}

int set_snmp_pdu(struct snmp_pdu **pdu, u_char pdu_type, int init, const char *objname)
{

  oid id_oid[MAX_OID_LEN];
  size_t id_len = MAX_OID_LEN;
  int status = 0;

  /*if init is true we create a new snmp_pdu*/
  if(init)
    {
      if( pdu_type != SNMP_MSG_GET &&
	  pdu_type != SNMP_MSG_GETNEXT &&
	  pdu_type != SNMP_MSG_RESPONSE &&
	  pdu_type != SNMP_MSG_SET &&
	  pdu_type != SNMP_MSG_TRAP &&
	  pdu_type != SNMP_MSG_GETBULK &&
	  pdu_type != SNMP_MSG_INFORM &&
	  pdu_type != SNMP_MSG_TRAP2 &&
	  pdu_type != SNMP_MSG_REPORT )
	{
	  DEBUG("PDU types not valid : %d\n", pdu_type);
	  return -1;
	}
      
	*pdu = snmp_pdu_create(pdu_type);
	if(*pdu == NULL)
	  {
	    SNMP_DEBUG("snmp_pdu_create");
	    return -1;
	  }
    }
  else
    {
      if(*pdu == NULL)
	{
	  SNMP_DEBUG("PDU should not be null");
	  return -1;
	}
    }

  status = read_objid(objname, id_oid, &id_len);
  if(status != 1)
    {
      SNMP_DEBUG("Failed on read_objid");
      return -1;
    }

  snmp_add_null_var(*pdu, id_oid, id_len);
  
  return 0;
}

int send_snmp_pdu(struct snmp_session *session, struct snmp_pdu *pdu, struct snmp_pdu **response)
{

  int status = 0;
  struct snmp_session  *sess_handle;

  sess_handle = snmp_open(session);
  if(sess_handle == NULL)
    {
      SNMP_DEBUG("Error openning snmp session");
      return -1;
    }

  status = snmp_synch_response(sess_handle, pdu, response);
  if(status != STAT_SUCCESS)
    {
      SNMP_DEBUG("snmp_synch_response");
      return -1;
    }

  snmp_close(sess_handle);
 
  return status;
}

int handle_snmp_pdu(struct snmp_pdu *response)
{
  assert(response != NULL);
  
  struct variable_list *vars;

  for(vars = response->variables; vars; vars =  vars->next_variable)
    {
      print_value(vars->name, vars->name_length, vars);
    }
  
  snmp_free_pdu(response);

  return 0;
}