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 + -
显示快捷键?