asn1.cpp
来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 2,107 行 · 第 1/5 页
CPP
2,107 行
* 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 beginning of the next object. * * "string" is filled with the bit string. * * 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_parse_bitstring( unsigned char *data, int *datalength, unsigned char *type, unsigned char *string, int *strlength){ /* * bitstring ::= 0x03 asnlength unused {byte}* */ unsigned char *bufp = data; unsigned long asn_length; *type = *bufp++; if (*type != 0x03) { ASNERROR("Wrong Type. Not a bitstring"); return NULL; } bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL) return NULL; if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){ ASNERROR("overflow of message"); return NULL; } if ((int) asn_length > *strlength){ ASNERROR("I don't support such long bitstrings"); return NULL; } if (asn_length < 1){ ASNERROR("Invalid bitstring"); return NULL; } if (*bufp > 7){ ASNERROR("Invalid bitstring"); return NULL; } // fixed memcpy((char *)string,(char *)bufp, (int)asn_length); *strlength = (int)asn_length; *datalength -= (int)asn_length + SAFE_INT_CAST(bufp - data); return bufp + asn_length;}/* * asn_build_bitstring - Builds an ASN bit string object containing the * input string. * 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 beginning of the next 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_bitstring( unsigned char *data, int *datalength, unsigned char type, unsigned char *string, int strlength){ /* * ASN.1 bit string ::= 0x03 asnlength unused {byte}* */ if (strlength < 1 || *string > 7){ ASNERROR("Building invalid bitstring"); return NULL; } data = asn_build_header(data, datalength, type, strlength); if (data == NULL) return NULL; if (*datalength < strlength) return NULL; // fixed memcpy((char *)data,(char *)string, strlength); *datalength -= strlength; return data + strlength;}/* * asn_parse_unsigned_int64 - pulls a 64 bit unsigned long out of an ASN int * type. * 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_parse_unsigned_int64( unsigned char *data, int *datalength, unsigned char *type, struct counter64 *cp, int countersize){ /* * ASN.1 integer ::= 0x02 asnlength byte {byte}* */ unsigned char *bufp = data; unsigned long asn_length; unsigned long low = 0, high = 0; int intsize = 4; if (countersize != sizeof(struct counter64)){ ASNERROR("not right size"); return NULL; } *type = *bufp++; if ((*type != 0x02) && (*type != 0x46)) { ASNERROR("Wrong Type. Not an integer 64"); return NULL; } bufp = asn_parse_length(bufp, &asn_length); if (bufp == NULL){ ASNERROR("bad length"); return NULL; } if ((asn_length + (bufp - data)) > (unsigned long)(*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 + SAFE_INT_CAST(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 = 0xFFul << (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++; } else { /* * 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 = 0x1FFul << ((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;#ifdef _SNMPv3 pdu->msgid = 0;#endif pdu->errstat = 0; pdu->errindex = 0; pdu->enterprise = NULL; pdu->enterprise_length = 0; pdu->variables = NULL; return pdu;}// free content and clear pointersvoid clear_pdu(struct snmp_pdu *pdu, bool clear_all){ struct variable_list *vp, *ovp; vp = pdu->variables; while (vp) { if (vp->name) free((char *)vp->name); // free the oid part if (vp->val.string) free((char *)vp->val.string); // free deep data ovp = vp; vp = vp->next_variable; // go to the next one free((char *)ovp); // free up vb itself } pdu->variables = NULL; // if enterprise free it up if (pdu->enterprise) free((char *)pdu->enterprise); pdu->enterprise = NULL; if (!clear_all) return; pdu->command = 0; pdu->reqid = 0;#ifdef _SNMPv3 pdu->msgid = 0; pdu->maxsize_scopedpdu = 0;#endif pdu->errstat = 0; pdu->errindex = 0; pdu->enterprise_length = 0; pdu->trap_type = 0; pdu->specific_type = 0; pdu->time = 0;}// free a pduvoid snmp_free_pdu( struct snmp_pdu *pdu){ clear_pdu(pdu); // clear and free content free((char *)pdu); // free up pdu itself}// 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 vars = pdu->variables; while (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, const long int version, const unsigned char *community, const int community_len, const int messagelen){ // 5 is 3 octets for version and 2 for community header + len
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?