📄 asn1.cpp
字号:
if ((int)(asn_length + (bufp - data)) > *datalength){ ASNERROR("overflow of message"); return NULL; } if (((int)asn_length > (intsize * 2 + 1)) || (((int)asn_length == (intsize * 2) + 1) && *bufp != 0x00)){ ASNERROR("I don't support such large integers"); return NULL; } *datalength -= (int)asn_length + (bufp - data); if (*bufp & 0x80){ low = (unsigned long) -1; // integer is negative high = (unsigned long) -1; } while(asn_length--){ high = (high << 8) | ((low & 0xFF000000) >> 24); low = (low << 8) | *bufp++; } cp->low = low; cp->high = high; return bufp;};/* * asn_build_unsigned_int64 - builds an ASN object containing a 64 bit integer. * On entry, datalength is input as the number of valid bytes following * "data". On exit, it is returned as the number of valid bytes * following the end of this object. * * Returns a pointer to the first byte past the end * of this object (i.e. the start of the next object). * Returns NULL on any error. */unsigned char * asn_build_unsigned_int64( unsigned char *data, int *datalength, unsigned char type, struct counter64 *cp, int countersize){/* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */ unsigned long low, high; unsigned long mask, mask2; int add_null_byte = 0; int intsize; if (countersize != sizeof (struct counter64)) return NULL; intsize = 8; low = cp->low; high = cp->high; mask = 0xFF << (8 * (sizeof(long) - 1)); /* mask is 0xFF000000 on a big-endian machine */ if ((unsigned char)((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80){ /* if MSB is set */ add_null_byte = 1; intsize++; } /* * Truncate "unnecessary" bytes off of the most significant end of this 2's * complement integer. * There should be no sequence of 9 consecutive 1's or 0's at the most * significant end of the integer. */ mask2 = 0x1FF << ((8 * (sizeof(long) - 1)) - 1); /* mask2 is 0xFF800000 on a big-endian machine */ while((((high & mask2) == 0) || ((high & mask2) == mask2)) && intsize > 1){ intsize--; high = (high << 8) | ((low & mask) >> (8 * (sizeof(long) - 1))); low <<= 8; } data = asn_build_header(data, datalength, type, intsize); if (data == NULL) return NULL; if (*datalength < intsize) return NULL; *datalength -= intsize; if (add_null_byte == 1){ *data++ = '\0'; intsize--; } while(intsize--){ *data++ = (unsigned char)((high & mask) >> (8 * (sizeof(long) - 1))); high = (high << 8) | ((low & mask) >> (8 * (sizeof(long) - 1))); low <<= 8; } return data;};// create a pdustruct snmp_pdu * snmp_pdu_create( int command){ struct snmp_pdu *pdu; pdu = (struct snmp_pdu *)malloc(sizeof(struct snmp_pdu)); memset((char *)pdu, 0,sizeof(struct snmp_pdu)); pdu->command = command; pdu->errstat = 0; pdu->errindex = 0; pdu->enterprise = NULL; pdu->enterprise_length = 0; pdu->variables = NULL; return pdu;};// free a pduvoid snmp_free_pdu( struct snmp_pdu *pdu){ struct variable_list *vp, *ovp; vp = pdu->variables; while(vp){ // free the oid part if (vp->name) free((char *)vp->name); // if deep data, then free as well if (vp->val.string) free((char *)vp->val.string); ovp = vp; // go to the next one vp = vp->next_variable; // free up vb itself free((char *)ovp); } // if enterprise free it up if (pdu->enterprise) free((char *)pdu->enterprise); // free up pdu itself free((char *)pdu);};// add a null var to a pduvoid snmp_add_var(struct snmp_pdu *pdu, oid *name, int name_length, SmiVALUE *smival){ struct variable_list *vars; // if we don't have a vb list ,create one if (pdu->variables == NULL) pdu->variables = vars = (struct variable_list *)malloc(sizeof(struct variable_list)); else { // we have one, find the end for(vars = pdu->variables; vars->next_variable; vars = vars->next_variable); // create a new one vars->next_variable = (struct variable_list *)malloc(sizeof(struct variable_list)); // bump ptr vars = vars->next_variable; } // add the oid with no data vars->next_variable = NULL; // hook in the Oid portion vars->name = (oid *)malloc(name_length * sizeof(oid)); // fixed memcpy((char *)vars->name,(char *)name, name_length * sizeof(oid)); vars->name_length = name_length; // hook in the SMI value switch( smival->syntax) { // null , do nothing case sNMP_SYNTAX_NULL: case sNMP_SYNTAX_NOSUCHOBJECT: case sNMP_SYNTAX_NOSUCHINSTANCE: case sNMP_SYNTAX_ENDOFMIBVIEW: { vars->type = (unsigned char) smival->syntax; vars->val.string = NULL; vars->val_len = 0; } break; // octects case sNMP_SYNTAX_OCTETS: case sNMP_SYNTAX_OPAQUE: case sNMP_SYNTAX_IPADDR: { vars->type = (unsigned char) smival->syntax; vars->val.string = (unsigned char *)malloc((unsigned)smival->value.string.len); vars->val_len = (int) smival->value.string.len; memcpy( (unsigned char *) vars->val.string, (unsigned char *) smival->value.string.ptr, (unsigned) smival->value.string.len); } break; // oid case sNMP_SYNTAX_OID: { vars->type = (unsigned char) smival->syntax; vars->val_len = (int) smival->value.oid.len * sizeof(oid); vars->val.objid = (oid *)malloc((unsigned)vars->val_len); memcpy((unsigned long *)vars->val.objid, (unsigned long *)smival->value.oid.ptr, (unsigned) vars->val_len); } break; case sNMP_SYNTAX_TIMETICKS: case sNMP_SYNTAX_CNTR32: case sNMP_SYNTAX_GAUGE32: case sNMP_SYNTAX_UINT32: { long templong; vars->type = (unsigned char) smival->syntax; vars->val.integer = (long *)malloc(sizeof(long)); vars->val_len = sizeof(long); templong = (long) smival->value.uNumber; memcpy( (long*) vars->val.integer, (long*) &templong, sizeof(long)); } break; case sNMP_SYNTAX_INT32: { long templong; vars->type = (unsigned char) smival->syntax; vars->val.integer = (long *)malloc(sizeof(long)); vars->val_len = sizeof(long); templong = (long) smival->value.sNumber; memcpy( (long*) vars->val.integer, (long*) &templong, sizeof(long)); } break; // 64 bit counter case sNMP_SYNTAX_CNTR64: { vars->type = ( unsigned char) smival->syntax; vars->val.counter64 = (struct counter64 *)malloc( sizeof(struct counter64) ); vars->val_len = sizeof(struct counter64); memcpy( (struct counter64*) vars->val.counter64, (SmiLPCNTR64) &(smival->value.hNumber), sizeof( SmiCNTR64)); } break; } // end switch};// build the authentication// works for v1 or v2cunsigned char *snmp_auth_build( unsigned char *data, int *length, long int version, unsigned char *community, int community_len, int messagelen){ unsigned char *params; int plen; params = community; plen = community_len; data = asn_build_sequence(data, length, (unsigned char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), messagelen + plen + 5); if (data == NULL){ ASNERROR("buildheader"); return NULL; } data = asn_build_int(data, length, (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), (long *)&version, sizeof(version)); if (data == NULL){ ASNERROR("buildint"); return NULL; } data = asn_build_string(data, length, (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), params, plen ); if (data == NULL){ ASNERROR("buildstring"); return NULL; } return (unsigned char *)data;};// build a variable bindingunsigned char * snmp_build_var_op(unsigned char *data, oid * var_name, int *var_name_len, unsigned char var_val_type, int var_val_len, unsigned char *var_val, int *listlength){ int dummyLen, headerLen; unsigned char *dataPtr; dummyLen = *listlength; dataPtr = data; data += 4; dummyLen -=4; if (dummyLen < 0) return NULL; headerLen = data - dataPtr; *listlength -= headerLen; data = asn_build_objid( data, listlength, (unsigned char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), var_name, *var_name_len); if (data == NULL){ ASNERROR(""); return NULL; } // based on the type... switch(var_val_type){ case ASN_INTEGER: data = asn_build_int( data, listlength, var_val_type, (long *)var_val, var_val_len); break; case SMI_GAUGE: case SMI_COUNTER: case SMI_TIMETICKS: case SMI_UINTEGER: data = asn_build_unsigned_int( data, listlength, var_val_type, (unsigned long *)var_val, var_val_len); break; case SMI_COUNTER64: data = asn_build_unsigned_int64(data, listlength, var_val_type, (struct counter64 *)var_val, var_val_len); break; case ASN_OCTET_STR: case SMI_IPADDRESS: case SMI_OPAQUE: case SMI_NSAP: data = asn_build_string(data, listlength, var_val_type, var_val, var_val_len); break; case ASN_OBJECT_ID: data = asn_build_objid(data, listlength, var_val_type, (oid *)var_val, var_val_len / sizeof(oid)); break; case ASN_NULL: data = asn_build_null(data, listlength, var_val_type); break; case ASN_BIT_STR: data = asn_build_bitstring(data, listlength, var_val_type, var_val, var_val_len); break; case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: data = asn_build_null(data, listlength, var_val_type); break; default: ASNERROR("wrong type"); return NULL; } if (data == NULL){ ASNERROR(""); return NULL; } dummyLen = (data - dataPtr) - headerLen; asn_build_sequence(dataPtr, &dummyLen, (unsigned char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen); return data;};// serialize the pduint snmp_build( struct snmp_pdu *pdu, unsigned char *packet, int *out_length, long version, unsigned char* community, int community_len){ unsigned char buf[SNMP_MSG_LENGTH]; unsigned char *cp; struct variable_list *vp; int length; long int zero = 0; int totallength; length = *out_length; cp = packet; for(vp = pdu->variables; vp; vp = vp->next_variable){ cp = snmp_build_var_op( cp, vp->name, &vp->name_length, vp->type, vp->val_len, (unsigned char *)vp->val.string, &length); if (cp == NULL) return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -