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