asn1.cpp

来自「HP公司的SNMP++的Win32版本源码」· C++ 代码 · 共 1,758 行 · 第 1/4 页

CPP
1,758
字号
    }
    totallength = cp - packet;

    length = SNMP_MSG_LENGTH;
	
	// encode the total len
    cp = asn_build_header( buf, 
		                   &length, 
						   (unsigned char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 
						   totallength);
    if (cp == NULL)
	  return -1;
	memcpy( (char *)cp, (char *)packet,totallength);
    totallength += cp - buf;

    length = *out_length;
    if (pdu->command != TRP_REQ_MSG) {

	   // request id 
	   cp = asn_build_int( packet, 
		                   &length,
	                       (unsigned char )(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
	                       (long *)&pdu->reqid, 
						   sizeof(pdu->reqid));
	   if (cp == NULL)
	      return -1;

	   // error status 
	   cp = asn_build_int(cp, 
		                  &length,
		                  (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		                  (long *)&pdu->errstat, sizeof(pdu->errstat));
	   if (cp == NULL)
	      return -1;

	   // error index 
	   cp = asn_build_int(cp, 
		                  &length,
		                  (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		                  (long *)&pdu->errindex, sizeof(pdu->errindex));
	   if (cp == NULL)
	     return -1;
    } 
	else {	// this is a trap message 

	   // enterprise 
	   cp = asn_build_objid( packet, 
		                     &length,
	                         (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID),
	                         (oid *)pdu->enterprise, 
							 pdu->enterprise_length);
	   if (cp == NULL)
	      return -1;

	   // agent-addr 
	   cp = asn_build_string(cp, 
		                     &length,
		                     (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | SMI_IPADDRESS),
		                     (unsigned char *)&pdu->agent_addr.sin_addr.s_addr, 
							 sizeof(pdu->agent_addr.sin_addr.s_addr));
	   if (cp == NULL)
	     return -1;

	  // generic trap 
	  cp = asn_build_int(cp, 
		                 &length,
		                 (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		                 (long *)&pdu->trap_type, 
						 sizeof(pdu->trap_type));
	  if (cp == NULL)
	     return -1;

	  // specific trap 
	  cp = asn_build_int( cp, 
		                  &length,
		                  (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		                  (long *)&pdu->specific_type, 
						  sizeof(pdu->specific_type));
	  if (cp == NULL)
	    return -1;

	  // timestamp  
	  cp = asn_build_int(cp, 
		                 &length,
		                 (unsigned char )(ASN_UNIVERSAL | ASN_PRIMITIVE | SMI_TIMETICKS),
		                 (long *)&pdu->time, 
						 sizeof(pdu->time));
	  if (cp == NULL)
	      return -1;
    }

    if (length < totallength)
	  return -1;
	// fixed
    memcpy((char *)cp, (char *)buf, totallength);
    totallength += cp - packet;

    length = SNMP_MSG_LENGTH;
    cp = asn_build_header(buf, 
		                  &length, 
						  (unsigned char)pdu->command, 
						  totallength);
    if (cp == NULL)
	  return -1;
    if (length < totallength)
	  return -1;
	// fixed
    memcpy((char *)cp, (char *)packet, totallength);
    totallength += cp - buf;

    length = *out_length;

    cp = snmp_auth_build( packet, 
		                  &length, 
						  version, 
						  community,
						  community_len,
						  totallength );
    if (cp == NULL)
	  return -1;
    if ((*out_length - (cp - packet)) < totallength)
	  return -1;
	// fixed
    memcpy((char *)cp, (char *)buf, totallength);
    totallength += cp - packet;
    *out_length = totallength;

    return 0;
};

// parse the authentication header
unsigned char *snmp_auth_parse(unsigned char *data,
                               int *length,
                               unsigned char *sid,
							   int *slen,
                               long	*version)
{
    unsigned char type;

	// get the type
    data = asn_parse_header( data, 
		                     length, 
							 &type);
    if (data == NULL){
	  ASNERROR("bad header");
	  return NULL;
    }

    if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)){
	   ASNERROR("wrong auth header type");
	   return NULL;
    }

	// get the version
    data = asn_parse_int(data, 
		                 length, 
						 &type, 
						 version, 
						 sizeof(*version));
    if (data == NULL){
	   ASNERROR("bad parse of version");
	   return NULL;
    }

	// get the community name
    data = asn_parse_string(data, 
		                    length, 
							&type, 
							sid, 
							slen);
    if (data == NULL){
	  ASNERROR("bad parse of community");
	  return NULL;
    }

    return (unsigned char *)data;
};

unsigned char *
snmp_parse_var_op( unsigned char *data,  // IN - pointer to the start of object 
    oid	    *var_name,	                 // OUT - object id of variable 
    int	    *var_name_len,               // IN/OUT - length of variable name 
    unsigned char  *var_val_type,        // OUT - type of variable (int or octet string) (one byte) 
    int	    *var_val_len,                // OUT - length of variable
    unsigned char  **var_val,	         // OUT - pointer to ASN1 encoded value of variable
    int	    *listlength)                 // IN/OUT - number of valid bytes left in var_op_list
{
    unsigned char var_op_type;
    int	var_op_len = *listlength;
    unsigned char *var_op_start = data;

    data = asn_parse_header(data, &var_op_len, &var_op_type);
    if (data == NULL){
	ASNERROR("");
	return NULL;
    }
    if (var_op_type != (unsigned  char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
	return NULL;
    data = asn_parse_objid(data, &var_op_len, &var_op_type, var_name, var_name_len);
    if (data == NULL){
	ASNERROR("");
	return NULL;
    }
    if (var_op_type != (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
	return NULL;
    *var_val = data;	/* save pointer to this object */
    /* find out what type of object this is */
    data = asn_parse_header(data, &var_op_len, var_val_type);
    if (data == NULL){
	ASNERROR("");
	return NULL;
    }
    *var_val_len = var_op_len;
    data += var_op_len;
    *listlength -= (int)(data - var_op_start);
    return data;
};



// build a pdu from a data and length
int snmp_parse( struct snmp_pdu *pdu,
                unsigned char  *data,
				unsigned char *community_name,
				unsigned long &community_len,
				snmp_version &spp_version,
                int length)
{
    unsigned char  msg_type;
    unsigned char  type;
    unsigned char  *var_val;
    long    version;
    int	    len, four;
    unsigned char community[256];
    int community_length = 256;
    struct variable_list *vp;
    oid	    objid[MAX_NAME_LEN], *op;
    unsigned char  *origdata = data;
    int      origlength = length;
    unsigned char  *save_data;

    // authenticates message and returns length if valid 
    data = snmp_auth_parse(data, 
		                   &length, 
						   community, 
						   &community_length, 
						   &version);
    if (data == NULL)
	return -1;

	// copy the returned community name
	memcpy( (unsigned char *) community_name, 
		    (unsigned char *) community, 
			community_length);
	community_len = (long int) community_length;

    if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C ) {
	    ASNERROR("Wrong version");
	    return -1;
    }

	spp_version = (snmp_version) version;

    save_data = data;

    data = asn_parse_header(data, 
		                    &length, 
							&msg_type);
    if (data == NULL)
	return -1;
    pdu->command = msg_type;

    if (pdu->command != TRP_REQ_MSG){
	   // get the rid
	   data = asn_parse_int(data, 
		                    &length, &type, 
							(long *)&pdu->reqid, 
							sizeof(pdu->reqid));
	   if (data == NULL)
	     return -1;
	   // get the error status
	   data = asn_parse_int(data, 
		                    &length, 
							&type, 
							(long *)&pdu->errstat, 
							sizeof(pdu->errstat));
	   if (data == NULL)
	     return -1;
	   // get the error index
	   data = asn_parse_int(data, 
		                    &length, 
							&type, 
							(long *)&pdu->errindex, 
							sizeof(pdu->errindex));
	   if (data == NULL)
	      return -1;
    } 
	else {  // is a trap

	   // get the enterprise
	   pdu->enterprise_length = MAX_NAME_LEN;
	   data = asn_parse_objid(data, 
		                      &length, 
							  &type, 
							  objid, 
							  &pdu->enterprise_length);
	   if (data == NULL)
	     return -1;

	   pdu->enterprise = (oid *)malloc(pdu->enterprise_length * sizeof(oid));
	   // fixed
	   memcpy((char *)pdu->enterprise,(char *)objid,  pdu->enterprise_length * sizeof(oid));

	   // get source address
	   four = 4;
	   data = asn_parse_string(data, 
		                       &length, 
							   &type, (unsigned char *)&pdu->agent_addr.sin_addr.s_addr, 
							   &four);
	   if (data == NULL)
	     return -1;

	   // get trap type
	   data = asn_parse_int(data, 
		                    &length, 
							&type, 
							(long *)&pdu->trap_type, 
							sizeof(pdu->trap_type));
	   if (data == NULL)
	     return -1;

	   // trap type
	   data = asn_parse_int(data, 
		                    &length, 
							&type, 
							(long *)&pdu->specific_type, 
							sizeof(pdu->specific_type));
	   if (data == NULL)
	     return -1;

	   // timestamp
	   data = asn_parse_int(data, &length, &type, (long *)&pdu->time, sizeof(pdu->time));
	   if (data == NULL)
	      return -1;
    }

	// get the vb list
    data = asn_parse_header(data, &length, &type);
    if (data == NULL)
	   return -1;
    if (type != (unsigned char)(ASN_SEQUENCE | ASN_CONSTRUCTOR))
	   return -1;
    while((int)length > 0){
	if (pdu->variables == NULL){
	    pdu->variables = vp = (struct variable_list *)malloc(sizeof(struct variable_list));
	} else {
	    vp->next_variable = (struct variable_list *)malloc(sizeof(struct variable_list));
	    vp = vp->next_variable;
	}
	vp->next_variable = NULL;
	vp->val.string = NULL;
	vp->name = NULL;
	vp->name_length = MAX_NAME_LEN;
	data = snmp_parse_var_op( data, 
		                      objid, 
							  &vp->name_length, 
							  &vp->type, 
							  &vp->val_len, 
							  &var_val, 
							  (int *)&length);
	if (data == NULL)
	    return -1;
	op = (oid *)malloc((unsigned)vp->name_length * sizeof(oid));
	// fixed
	memcpy((char *)op, (char *)objid, vp->name_length * sizeof(oid));
	vp->name = op;

	len = SNMP_MSG_LENGTH;
	switch((short)vp->type){
	    case ASN_INTEGER:
		   vp->val.integer = (long *)malloc(sizeof(long));
		   vp->val_len = sizeof(long);
		   asn_parse_int(var_val, &len, &vp->type, (long *)vp->val.integer, sizeof(vp->val.integer));
		break;

	    case SMI_COUNTER:
	    case SMI_GAUGE:
	    case SMI_TIMETICKS:
	    case SMI_UINTEGER:
		   vp->val.integer = (long *)malloc(sizeof(long));
		   vp->val_len = sizeof(long);
		   asn_parse_unsigned_int(var_val, &len, &vp->type, (unsigned long *)vp->val.integer, sizeof(vp->val.integer));
		break;

	    case SMI_COUNTER64:
		   vp->val.counter64 = (struct counter64 *)malloc( sizeof(struct counter64) );
		   vp->val_len = sizeof(struct counter64);
		   asn_parse_unsigned_int64(var_val, &len, &vp->type,
					    (struct counter64 *)vp->val.counter64,
					    sizeof(*vp->val.counter64));
		break;
	    
		case ASN_OCTET_STR:
	    case SMI_IPADDRESS:
	    case SMI_OPAQUE:
	    case SMI_NSAP:
		   vp->val.string = (unsigned char *)malloc((unsigned)vp->val_len);
		   asn_parse_string(var_val, &len, &vp->type, vp->val.string, &vp->val_len);
		break;

	    case ASN_OBJECT_ID:
		   vp->val_len = MAX_NAME_LEN;
		   asn_parse_objid(var_val, &len, &vp->type, objid, &vp->val_len);
		   //vp->val_len *= sizeof(oid);
		   vp->val.objid = (oid *)malloc((unsigned)vp->val_len * sizeof(oid));
		   // fixed
		   memcpy((char *)vp->val.objid,
			      (char *)objid,
			      vp->val_len * sizeof(oid));
		break;

        case SNMP_NOSUCHOBJECT:
        case SNMP_NOSUCHINSTANCE:
        case SNMP_ENDOFMIBVIEW:
	    case ASN_NULL:
		break;

	    default:
		   ASNERROR("bad type returned ");
		break;
	}
    }
    return 0;
};



⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?