int snmp_preview(u_char *data, unsigned length, struct SnmpObjects *vbinds) { int i = 0; /* number of varbinds parsed */ unsigned tmp; struct SnmpObject *obj; vbinds->num=0; /* number of varbinds present in vbinds */ while (length) { /* parse the name, value pair */ obj = &(vbinds->objs[i]); obj->namelen = MAX_NAME_LEN; data = snmp_parse_var_op(data, obj->name, &obj->namelen, &obj->valuetype, &obj->valuelen, &obj->value, &length); if (data == NULL) return -1; /* obj->value points to ASN encoded value * - skip past "type" and "len" fields, so that "value" * points to received value. */ tmp = data - obj->value; obj->value = asn_parse_header(obj->value, &tmp, &obj->valuetype); if (obj->value == NULL) return -1; i++; /* test which verifies that SET command contains valid VB ammount */ if((i >= SNMP_MAX_OIDS) && (length > 0)) return -1 ; } vbinds->num=i; /* number of varbinds present in vbinds */ return 0; }
char * smux_var (char *ptr, size_t len, oid objid[], size_t *objid_len, size_t *var_val_len, u_char *var_val_type, void **var_value) { u_char type; u_char val_type; size_t val_len; u_char *val; if (debug_smux) zlog_debug ("SMUX var parse: len %ld", len); /* Parse header. */ ptr = asn_parse_header (ptr, &len, &type); if (debug_smux) { zlog_debug ("SMUX var parse: type %d len %ld", type, len); zlog_debug ("SMUX var parse: type must be %d", (ASN_SEQUENCE | ASN_CONSTRUCTOR)); } /* Parse var option. */ *objid_len = MAX_OID_LEN; ptr = snmp_parse_var_op(ptr, objid, objid_len, &val_type, &val_len, &val, &len); if (var_val_len) *var_val_len = val_len; if (var_value) *var_value = (void*) val; if (var_val_type) *var_val_type = val_type; /* Requested object id length is objid_len. */ if (debug_smux) smux_oid_dump ("Request OID", objid, *objid_len); if (debug_smux) zlog_debug ("SMUX val_type: %d", val_type); /* Check request value type. */ if (debug_smux) switch (val_type) { case ASN_NULL: /* In case of SMUX_GET or SMUX_GET_NEXT val_type is set to ASN_NULL. */ zlog_debug ("ASN_NULL"); break; case ASN_INTEGER: zlog_debug ("ASN_INTEGER"); break; case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: case ASN_UINTEGER: zlog_debug ("ASN_COUNTER"); break; case ASN_COUNTER64: zlog_debug ("ASN_COUNTER64"); break; case ASN_IPADDRESS: zlog_debug ("ASN_IPADDRESS"); break; case ASN_OCTET_STR: zlog_debug ("ASN_OCTET_STR"); break; case ASN_OPAQUE: case ASN_NSAP: case ASN_OBJECT_ID: zlog_debug ("ASN_OPAQUE"); break; case SNMP_NOSUCHOBJECT: zlog_debug ("SNMP_NOSUCHOBJECT"); break; case SNMP_NOSUCHINSTANCE: zlog_debug ("SNMP_NOSUCHINSTANCE"); break; case SNMP_ENDOFMIBVIEW: zlog_debug ("SNMP_ENDOFMIBVIEW"); break; case ASN_BIT_STR: zlog_debug ("ASN_BIT_STR"); break; default: zlog_debug ("Unknown type"); break; } return ptr; }
int decode_vbind (unsigned char *data, unsigned int vb_len) { unsigned char *var_val; oid var_name[MAX_OID_LEN]; /* To test the objid */ size_t name_len = MAX_OID_LEN; /* To test the objid */ int badtype=0; size_t len; struct variable_list *vp; oid objid[MAX_OID_LEN]; char _docsis_snmp_label[50]; /* To hold the 'name' of the type, i.e. Integer etc */ char *enum_string = NULL; static char outbuf[16384]; struct tree *subtree; struct enum_list *enums; memset (outbuf, 0, 16384); vp = (struct variable_list *) malloc (sizeof (struct variable_list)); if (vp == NULL) { fprintf (stderr, "Out of memory\n"); return 0; } memset (vp, 0, sizeof (struct variable_list)); vp->next_variable = NULL; vp->val.string = NULL; vp->name_length = MAX_OID_LEN; vp->name = 0; data = snmp_parse_var_op (data, objid, &vp->name_length, &vp->type, &vp->val_len, &var_val, (size_t *) & vb_len); if (data == NULL) return -1; if (snmp_set_var_objid (vp, objid, vp->name_length)) return -1; len = PACKET_LENGTH; if (netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX); } /* Disable extended index format ... makes it harder to parse tokens in lex */ if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM); } /* Enable printing numeric enums */ if (netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); } /* Disable escape quotes in string index output */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_OID_OUTPUT_NUMERIC)) { netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); } snprint_objid (outbuf, 1023, vp->name, vp->name_length); if (!get_node (outbuf, var_name, &name_len)) { if (!read_objid (outbuf, var_name, &name_len)) { fprintf (stderr, "/* Hmm ... can't find oid %s at line %d ... perhaps the MIBs are not installed ? */\n", outbuf, line); /* temporarily set full output format */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_FULL); memset (outbuf, 0, 1024); snprint_objid (outbuf, 1023, vp->name, vp->name_length); /* Go back to suffix-mode for better readability */ netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); } } printf("%s", outbuf); /* save the subtree - we need it later to show enums */ subtree = get_tree (var_name, name_len, get_tree_head() ); /* This first switch is just for saving the type in the format we actually want to print. */ switch ((short) vp->type) { case ASN_INTEGER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Integer"); break; case ASN_COUNTER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Counter32"); break; case ASN_GAUGE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Gauge32"); break; case ASN_TIMETICKS: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "TimeTicks"); break; case ASN_UINTEGER: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Unsigned32"); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueCounter64"); break; case ASN_OPAQUE_U64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueU64"); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_COUNTER64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Counter64"); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_FLOAT: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueFloat"); break; case ASN_OPAQUE_DOUBLE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueDouble"); break; case ASN_OPAQUE_I64: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "OpaqueI64"); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_OCTET_STR: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "String"); break; case ASN_IPADDRESS: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "IPAddress"); break; case ASN_OPAQUE: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "Opaque"); break; case ASN_NSAP: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "NSAP"); break; case ASN_OBJECT_ID: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "ObjectID"); break; case ASN_BIT_STR: memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "BitString"); break; } switch ((short) vp->type) { case ASN_INTEGER: vp->val.integer = (long *) vp->buf; vp->val_len = sizeof (long); asn_parse_int (var_val, &len, &vp->type, (long *) vp->val.integer, sizeof (vp->val.integer)); break; case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: case ASN_UINTEGER: vp->val.integer = (long *) vp->buf; vp->val_len = sizeof (u_long); asn_parse_unsigned_int (var_val, &len, &vp->type, (u_long *) vp->val.integer, sizeof (vp->val.integer)); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: case ASN_OPAQUE_U64: #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_COUNTER64: vp->val.counter64 = (struct counter64 *) vp->buf; 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; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_FLOAT: vp->val.floatVal = (float *) vp->buf; vp->val_len = sizeof (float); asn_parse_float (var_val, &len, &vp->type, vp->val.floatVal, vp->val_len); break; case ASN_OPAQUE_DOUBLE: vp->val.doubleVal = (double *) vp->buf; vp->val_len = sizeof (double); asn_parse_double (var_val, &len, &vp->type, vp->val.doubleVal, vp->val_len); break; case ASN_OPAQUE_I64: vp->val.counter64 = (struct counter64 *) vp->buf; vp->val_len = sizeof (struct counter64); asn_parse_signed_int64 (var_val, &len, &vp->type, (struct counter64 *) vp->val.counter64, sizeof (*vp->val.counter64)); break; #endif /* OPAQUE_SPECIAL_TYPES */ case ASN_OCTET_STR: case ASN_IPADDRESS: case ASN_OPAQUE: case ASN_NSAP: if (vp->val_len < sizeof (vp->buf)) { vp->val.string = (u_char *) vp->buf; } else { vp->val.string = (u_char *) malloc ((unsigned) vp->val_len+1); memset(vp->val.string, 0, vp->val_len+1); } asn_parse_string (var_val, &len, &vp->type, vp->val.string, &vp->val_len); break; case ASN_OBJECT_ID: vp->val_len = MAX_OID_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); memmove (vp->val.objid, objid, vp->val_len); break; case SNMP_NOSUCHOBJECT: case SNMP_NOSUCHINSTANCE: case SNMP_ENDOFMIBVIEW: case ASN_NULL: break; case ASN_BIT_STR: vp->val.bitstring = (u_char *) malloc (vp->val_len); asn_parse_bitstring (var_val, &len, &vp->type, vp->val.bitstring, &vp->val_len); break; default: fprintf(stderr, "Error: bad type returned (%x)\n", vp->type); badtype = 1; break; } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID); } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS); } if (!netsnmp_ds_get_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); } if (!strcmp (_docsis_snmp_label, "String")) /* Strings need special treatment - see below */ { netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); netsnmp_ds_toggle_boolean (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); } switch ((short) vp->type) { case ASN_OCTET_STR: if (str_isprint((char *) vp->val.string, vp->val_len)) { snprintf(outbuf, vp->val_len+5, "\"%s\"", vp->val.string); } else { snprint_hexadecimal (outbuf, 16383, (char *) vp->val.string, vp->val_len); memset (_docsis_snmp_label, 0, 50); sprintf (_docsis_snmp_label, "HexString"); } break; case ASN_BIT_STR: snprint_hexadecimal (outbuf, 1023, (char *) vp->val.bitstring, vp->val_len); break; case ASN_OBJECT_ID: netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); snprint_value (outbuf, 1023, vp->name, vp->name_length, vp); netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_SUFFIX); break; default: snprint_value (outbuf, 1023, vp->name, vp->name_length, vp); } if ( subtree ) { enums = subtree->enums; for (; enums; enums = enums->next) { if (enums->value == *vp->val.integer) { enum_string = enums->label; break; } } } if (enum_string) printf(" %s %s; /* %s */", _docsis_snmp_label, outbuf, enum_string); else printf(" %s %s;", _docsis_snmp_label, outbuf); snmp_free_var (vp); return badtype; }
//* //* Parse_var_op_list goes through the list of variables and retrieves each one, //* placing it's value in the output packet. In the case of a set request, //* if action is RESERVE, the value is just checked for correct type and //* value, and resources may need to be reserved. If the action is COMMIT, //* the variable is set. If the action is FREE, an error was discovered //* somewhere in the previous RESERVE pass, so any reserved resources //* should be FREE'd. //* If any error occurs, an error code is returned. //* int parse_var_op_list( snmp_session *session, uint8 *data, //point to variable-binding of in-packet data int length, //in packet data length uint8 *out_data, //point to variable-binding of out-packet data int out_length, //out packet buffer length long *index, //error-index (output) int msgtype, //message type int action //??? ) { uint8 type; oid var_name[SNMP_MAX_NAME_LEN]; int var_name_len, var_val_len; uint8 var_val_type, *var_val, statType; uint8 *statP; int statLen; uint16 acl; int (*write_method)(); uint8 *headerP, *var_list_start; int dummyLen; #ifdef WEBADMIN int dummyLen1; // add -- By arius 5/17/2000 uint8 *newpacket_end; // add -- By arius 5/17/2000 #endif WEBADMIN int noSuchObject; int (*WriteMethod)(int,uint8 *,uint8,int,uint8 *,oid *,int); int err, exact; // if (msgtype== SET_REQ_MSG) rw = SNMP_WRITE; // else rw = SNMP_READ; if (msgtype == GETNEXT_REQ_MSG) exact = FALSE; else exact = TRUE; //Parse variable-binging header data = asn_parse_header(data, &length, &type); if (data == NULL){ ERROR("not enough space for varlist"); return PARSE_ERROR; } if (type != (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR)){ ERROR("wrong type"); return PARSE_ERROR; } headerP = out_data; //Set Resp variable-binging header out_data = asn_build_sequence(out_data, &out_length, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); if (out_data == NULL){ ERROR("not enough space in output packet"); return BUILD_ERROR; } var_list_start = out_data; *index = 1; while((int)length > 0){ // parse the name, value pair var_name_len = SNMP_MAX_NAME_LEN; data = snmp_parse_var_op(data, var_name, &var_name_len, &var_val_type, &var_val_len, &var_val, (int *)&length); if (data == NULL) return PARSE_ERROR; // now attempt to retrieve the variable on the local entity statP = getStatPtr(var_name, &var_name_len, &statType, &statLen, &acl, exact, &write_method, SNMP_VERSION_1, &noSuchObject, (msgtype==SET_REQ_MSG? (session->access & SNMP_ACCESS_WRITE): (session->access & SNMP_ACCESS_READ) ) ); if (/* session->version == SNMP_VERSION_1 &&*/ statP == NULL && (msgtype != SET_REQ_MSG || !write_method)) { //** XXX: happens when running // XXX: snmpwalk localhost public .1 // XXX: fix me some day. //** //** ERROR("warning: internal v1_error"); ** return SNMP_ERR_NOSUCHNAME; } // check if this variable is read-write (in the MIB sense). if( msgtype == SET_REQ_MSG && acl != RWRITE ) return SNMP_ERR_READONLY; // return session->version == SNMP_VERSION_1 ? SNMP_ERR_NOSUCHNAME : SNMP_ERR_NOTWRITABLE; //* Its bogus to check here on getnexts - the whole packet shouldn't // be dumped - this should should be the loop in getStatPtr // luckily no objects are set unreadable. This can still be // useful for sets to determine which are intrinsically writable if (msgtype== SET_REQ_MSG){ if (write_method == NULL){ if (statP != NULL){ // see if the type and value is consistent with this entity's variable if (!goodValue(var_val_type, var_val_len, statType,statLen)) { // if (session->version != SNMP_VERSION_1) // return SNMP_ERR_WRONGTYPE; // poor approximation // else { snmp_inbadvalues++; return SNMP_ERR_BADVALUE; } } // actually do the set if necessary if (action == COMMIT) setVariable(var_val, var_val_type, var_val_len,statP, statLen); } else { // if (session->version != SNMP_VERSION_1) // return SNMP_ERR_NOCREATION; // else return SNMP_ERR_NOSUCHNAME; } } else { WriteMethod = (int (*)(int,uint8 *,uint8,int,uint8 *,oid *,int)) write_method; err = (*WriteMethod)(action, var_val, var_val_type, var_val_len, statP, var_name, var_name_len); //* //* Map the SNMPv2 error codes to SNMPv1 error codes (RFC 2089). //* // if (session->version == SNMP_VERSION_1) { switch (err) { case SNMP_ERR_NOERROR: // keep the no-error error: break; case SNMP_ERR_WRONGVALUE: case SNMP_ERR_WRONGENCODING: case SNMP_ERR_WRONGTYPE: case SNMP_ERR_WRONGLENGTH: case SNMP_ERR_INCONSISTENTVALUE: err = SNMP_ERR_BADVALUE; break; case SNMP_ERR_NOACCESS: case SNMP_ERR_NOTWRITABLE: case SNMP_ERR_NOCREATION: case SNMP_ERR_INCONSISTENTNAME: case SNMP_ERR_AUTHORIZATIONERROR: err = SNMP_ERR_NOSUCHNAME; break; default: err = SNMP_ERR_GENERR; break; // } }//if(session->version == SNMP_VERSION_1) .... if (err != SNMP_ERR_NOERROR){ // if (session->version == SNMP_VERSION_1) { snmp_inbadvalues++; // } return err; } } } else { //* retrieve the value of the variable and place it into the //* outgoing packet if (statP == NULL){ statLen = 0; if (exact){ if (noSuchObject == TRUE){ statType = SNMP_NOSUCHOBJECT; } else { statType = SNMP_NOSUCHINSTANCE; } } else { statType = SNMP_ENDOFMIBVIEW; } } //if (statP == NULL) ... out_data = snmp_build_var_op(out_data, var_name, &var_name_len, statType, statLen, statP, &out_length); if (out_data == NULL){ return SNMP_ERR_TOOBIG; } } //if (msgtype== SET_REQ_MSG) ... (*index)++; } //while((int)length > 0) .... if(msgtype!= SET_REQ_MSG){ // save a pointer to the end of the packet packet_end = out_data; // Now rebuild header with the actual lengths dummyLen = packet_end - var_list_start; // modified by ---- Arius 5/17/2000 #ifdef WEBADMIN dummyLen1 = packet_end - headerP; newpacket_end = asn_build_sequence(headerP, &dummyLen1, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen); var_list_start -= (packet_end - newpacket_end); out_length += (packet_end - newpacket_end); // save new pointer to the end of the packet when the sapces will be adjust packet_end = newpacket_end; if (headerP == NULL) #else if (asn_build_sequence(headerP, &dummyLen, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen) == NULL) #endif WEBADMIN // end of here { return SNMP_ERR_TOOBIG; // bogus error ???? } } *index = 0; return SNMP_ERR_NOERROR; }
char * snmp_parse_trap(u_char * trapdata, /* IN - actual trap data from packet */ unsigned datalen, /* IN - length of trapdata */ struct trap_info * trapInfo) /* IN/OUT - struct to fill in */ { u_char * more; /* pointer to next unparsed PDU data */ u_char * nextVar; /* pointer to next unparsed TRAP variable */ unsigned left; /* length of more */ long version; /* SNMP version, always v1 */ u_char type; /* data types for checking */ u_char * varValPtr; int vars_in_struct; struct trapVar * vars; /* trap variables data structures */ u_long trapType; unsigned length; /* scratch for passing to asn1 */ /* do some basic setup of the passed data structures */ vars_in_struct = trapInfo->trapVars; trapInfo->trapVars = 0; /* bump later if vars are present */ left = datalen; more = snmp_auth_parse(trapdata, &left, (u_char*)trapInfo->community, (unsigned*)&trapInfo->commLen, &version); if (!more) return "community parse"; more = asn_parse_header(more, &left, &type); if (!more || type != TRP_REQ_MSG) return "trap pdu header"; more = asn_parse_objid(more, &left, &type, &trapInfo->objId[0], (unsigned*)&trapInfo->objLen); if (!more || type != ASN_OBJECT_ID) return "sys ObjId"; length = 4; /* number of bytes in IP address buffer */ more = asn_parse_string(more, &left, &type, (u_char*)(&trapInfo->agent_ip), &length); if (!more || type != IPADDRESS) return "agent's IP address"; more = asn_parse_int(more, &left, &type, (long*)&trapType, sizeof(long)); if (!more || type != ASN_INTEGER || trapType > 6) return "trap type"; trapInfo->trapType = trapType; more = asn_parse_int(more, &left, &type, (long*)&trapType, sizeof(long)); if (!more || type != ASN_INTEGER) return "specific type"; trapInfo->trapSpecific = trapType; more = asn_parse_int(more, &left, &type, (long*)&trapInfo->time, sizeof(long)); if (!more || type != TIMETICKS) return "timestamp"; if (!left) /* no variables in trap ? */ return NULL; /* rest of packet is a sequence of variables */ more = asn_parse_header(more, &left, &type); /* strip off leading SEQ */ if (!more || type != SEQUENCE) return "trap vars header"; vars = trapInfo->vars; /* set pointer array to receive variables data */ while (left) /* keep parsing & counting vars as long as there's data */ { /* extract variable info for this var */ length = left; /* number of valid bytes left in packet buffer */ varNameLen = MAX_OID_LEN ; /* define the max size of varName */ nextVar = snmp_parse_var_op(more, varName, &varNameLen, &varType, &varLen, &varValPtr, &left); if (!nextVar) /* quit if parse failed */ return ("var_op header"); /* extract the variable's value; pointed to by varValPtr: */ length -= more - nextVar; /* deduct size of header -> max. length of var */ switch (varType) { case ASN_INTEGER: case GAUGE: case COUNTER: case TIMETICKS: varLen = sizeof(long); /* size required by asn_parse_int() */ nextVar = asn_parse_int(varValPtr, &length, &varType, (long *)(&varVal[0]), varLen); break; case ASN_OCTET_STR: case IPADDRESS: case OPAQUE: varLen = MAX_TRAP_VAR; nextVar = asn_parse_string(varValPtr, &length, &varType, varVal, &varLen); break; case ASN_OBJECT_ID: varLen = MAX_TRAP_VAR; nextVar = asn_parse_objid(varValPtr, &length, &varType, (oid *)(&varVal[0]), &varLen); break; case ASN_NULL: nextVar = asn_parse_null(varValPtr, &length, &varType); break; default: SNMPERROR("wrong type"); return NULL; } if (!nextVar) return("variable"); /* if another trap variable info slot is available, fill it in */ if (trapInfo->trapVars <= vars_in_struct) { oidcpy(vars->varName, varName, varNameLen); if (vars->varBufLen <= varLen) /* need to truncate? */ vars->varValLen = vars->varBufLen-1; else /* we have room for the full variable data field */ vars->varValLen = varLen; MEMCPY(vars->varBuf, varVal, vars->varValLen); vars->varNameLen = varNameLen; vars->varType = varType; vars++; /* point to next variable info structure */ } trapInfo->trapVars++; /* another var */ more = nextVar; /* bump pointer to pdu */ } return NULL; }