/*******************************************************************-o-****** * snmp_comstr_build * * Parameters: * *data * *length * *psid * *slen * *version * messagelen * * Returns: * Pointer into 'data' after built section. * * * Build the header of a community string-based message such as that found * in SNMPv1 and SNMPv2c. * * NOTE: The length of the message will have to be inserted later, * if not known. * * NOTE: Version is an 'int'. (CMU had it as a long, but was passing * in a *int. Grrr.) Assign version to verfix and pass in * that to asn_build_int instead which expects a long. -- WH */ u_char * snmp_comstr_build(u_char * data, size_t * length, u_char * psid, size_t * slen, long *version, size_t messagelen) { long verfix = *version; u_char *h1 = data; u_char *h1e; size_t hlength = *length; /* * Build the the message wrapper (note length will be inserted later). */ data = asn_build_sequence(data, length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); if (data == NULL) { return NULL; } h1e = data; /* * Store the version field. */ data = asn_build_int(data, length, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &verfix, sizeof(verfix)); if (data == NULL) { return NULL; } /* * Store the community string. */ data = asn_build_string(data, length, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR), psid, *(u_char *) slen); if (data == NULL) { return NULL; } /* * Insert length. */ asn_build_sequence(h1, &hlength, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), data - h1e + messagelen); return data; } /* end snmp_comstr_build() */
int smux_trap (oid *name, size_t namelen, oid *iname, size_t inamelen, struct trap_object *trapobj, size_t trapobjlen, unsigned int tick, u_char sptrap) { unsigned int i; u_char buf[BUFSIZ]; u_char *ptr; size_t len, length; struct in_addr addr; unsigned long val; u_char *h1, *h1e; ptr = buf; len = BUFSIZ; length = len; /* When SMUX connection is not established. */ if (smux_sock < 0) return 0; /* SMUX header. */ ptr = asn_build_header (ptr, &len, (u_char) SMUX_TRAP, 0); /* Sub agent enterprise oid. */ ptr = asn_build_objid (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), smux_oid, smux_oid_len); /* IP address. */ addr.s_addr = 0; ptr = asn_build_string (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_IPADDRESS), (u_char *)&addr, sizeof (addr)); /* Generic trap integer. */ val = SNMP_TRAP_ENTERPRISESPECIFIC; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &val, sizeof (val)); /* Specific trap integer. */ val = sptrap; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &val, sizeof (val)); /* Timeticks timestamp. */ val = 0; ptr = asn_build_unsigned_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_TIMETICKS), &val, sizeof (val)); /* Variables. */ h1 = ptr; ptr = asn_build_sequence (ptr, &len, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); /* Iteration for each objects. */ h1e = ptr; for (i = 0; i < trapobjlen; i++) { int ret; oid oid[MAX_OID_LEN]; size_t oid_len; void *val; size_t val_len; u_char val_type; /* Make OID. */ if (trapobj[i].namelen > 0) { oid_copy (oid, name, namelen); oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen); oid_copy (oid + namelen + trapobj[i].namelen, iname, inamelen); oid_len = namelen + trapobj[i].namelen + inamelen; } else { oid_copy (oid, name, namelen); oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen * (-1)); oid_len = namelen + trapobj[i].namelen * (-1) ; } if (debug_smux) { smux_oid_dump ("Trap", name, namelen); if (trapobj[i].namelen < 0) smux_oid_dump ("Trap", trapobj[i].name, (- 1) * (trapobj[i].namelen)); else { smux_oid_dump ("Trap", trapobj[i].name, (trapobj[i].namelen)); smux_oid_dump ("Trap", iname, inamelen); } smux_oid_dump ("Trap", oid, oid_len); zlog_info ("BUFSIZ: %d // oid_len: %d", BUFSIZ, oid_len); } ret = smux_get (oid, &oid_len, 1, &val_type, &val, &val_len); if (debug_smux) zlog_debug ("smux_get result %d", ret); if (ret == 0) ptr = snmp_build_var_op (ptr, oid, &oid_len, val_type, val_len, val, &len); } /* Now variable size is known, fill in size */ asn_build_sequence(h1, &length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), ptr - h1e); /* Fill in size of whole sequence */ len = BUFSIZ; asn_build_header (buf, &len, (u_char) SMUX_TRAP, (ptr - buf) - 2); return send (smux_sock, buf, (ptr - buf), 0); }
void smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat, long errindex, u_char val_type, void *arg, size_t arg_len) { int ret; u_char buf[BUFSIZ]; u_char *ptr, *h1, *h1e, *h2, *h2e; size_t len, length; ptr = buf; len = BUFSIZ; length = len; if (debug_smux) { zlog_debug ("SMUX GETRSP send"); zlog_debug ("SMUX GETRSP reqid: %ld", reqid); } h1 = ptr; /* Place holder h1 for complete sequence */ ptr = asn_build_sequence (ptr, &len, (u_char) SMUX_GETRSP, 0); h1e = ptr; ptr = asn_build_int (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &reqid, sizeof (reqid)); if (debug_smux) zlog_debug ("SMUX GETRSP errstat: %ld", errstat); ptr = asn_build_int (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &errstat, sizeof (errstat)); if (debug_smux) zlog_debug ("SMUX GETRSP errindex: %ld", errindex); ptr = asn_build_int (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &errindex, sizeof (errindex)); h2 = ptr; /* Place holder h2 for one variable */ ptr = asn_build_sequence (ptr, &len, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); h2e = ptr; ptr = snmp_build_var_op (ptr, objid, &objid_len, val_type, arg_len, arg, &len); /* Now variable size is known, fill in size */ asn_build_sequence(h2,&length,(u_char)(ASN_SEQUENCE|ASN_CONSTRUCTOR),ptr-h2e); /* Fill in size of whole sequence */ asn_build_sequence(h1,&length,(u_char)SMUX_GETRSP,ptr-h1e); if (debug_smux) zlog_debug ("SMUX getresp send: %ld", (ptr - buf)); ret = send (smux_sock, buf, (ptr - buf), 0); }
u_char * _docsis_snmp_build_var_op(u_char * data, oid * var_name, size_t * var_name_len, u_char var_val_type, size_t var_val_len, u_char * var_val, size_t * listlength) { size_t dummyLen, headerLen; u_char *dataPtr; dummyLen = *listlength; dataPtr = data; #if 0 data = asn_build_sequence(data, &dummyLen, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); if (data == NULL) { return NULL; } #endif if (dummyLen < 2) return NULL; data += 2; dummyLen -= 2; headerLen = data - dataPtr; *listlength -= headerLen; DEBUGDUMPHEADER("send", "Name"); data = asn_build_objid(data, listlength, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), var_name, *var_name_len); DEBUGINDENTLESS(); if (data == NULL) { ERROR_MSG("Can't build OID for variable"); return NULL; } DEBUGDUMPHEADER("send", "Value"); switch (var_val_type) { case ASN_INTEGER: data = asn_build_int(data, listlength, var_val_type, (long *) var_val, var_val_len); break; case ASN_GAUGE: case ASN_COUNTER: case ASN_TIMETICKS: case ASN_UINTEGER: data = asn_build_unsigned_int(data, listlength, var_val_type, (u_long *) var_val, var_val_len); break; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: case ASN_OPAQUE_U64: #endif case ASN_COUNTER64: data = asn_build_unsigned_int64(data, listlength, var_val_type, (struct counter64 *) var_val, var_val_len); break; case ASN_OCTET_STR: case ASN_IPADDRESS: case ASN_OPAQUE: case ASN_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; #ifdef OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_FLOAT: data = asn_build_float(data, listlength, var_val_type, (float *) var_val, var_val_len); break; case ASN_OPAQUE_DOUBLE: data = asn_build_double(data, listlength, var_val_type, (double *) var_val, var_val_len); break; case ASN_OPAQUE_I64: data = asn_build_signed_int64(data, listlength, var_val_type, (struct counter64 *) var_val, var_val_len); break; #endif /* OPAQUE_SPECIAL_TYPES */ default: ERROR_MSG("wrong type"); return NULL; } DEBUGINDENTLESS(); if (data == NULL) { ERROR_MSG("Can't build value"); return NULL; } dummyLen = (data - dataPtr) - headerLen; _docsis_asn_build_sequence(dataPtr, &dummyLen, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), dummyLen); return data; }
//* //* 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; }
int snmp_agent_parse( snmp_session *session, uint8 *indata, int inlength, uint8 *outdata, int *outlength ) { uint8 msgtype, type; long zero = 0; long reqid, errstat, errindex, dummyindex; uint8 *out_auth, *out_header, *out_reqid; uint8 *startData = indata; int startLength = inlength; long version; uint8 *origdata = indata; int origlen = inlength; // usecEntry *ue; int packet_len, ret = 0; #ifdef WEBADMIN int newoutdata; // add -- by arius 5/17/2000 int len; // add -- by arius 5/17/2000 #endif WEBADMIN session->community_len = COMMUNITY_MAX_LEN; //get community name indata = snmp_parse_auth(indata, &inlength, community, &session->community_len, &version); if (indata == NULL){ // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("bad auth encoding"); return 0; } #if 1 //ONLY SUPPORT VERSION 1 if(version != SNMP_VERSION_1) { ERROR("wrong version"); snmp_inbadversions++; return 0; } #else //////////////////////////////////////////// if( version != SNMP_VERSION_1 && version != SNMP_VERSION_2C && version != SNMP_VERSION_2 ) { // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("wrong version"); snmp_inbadversions++; return 0; } if( version == SNMP_VERSION_2C || version == SNMP_VERSION_2 ) { if( version == SNMP_VERSION_2 ) { ret = check_auth( session, origdata, origlen, indata - session->community_len, session->community_len, &ue ); *outlength = (SNMP_MAX_LEN < session->MMS) ? SNMP_MAX_LEN : session->MMS; session->MMS = SNMP_MAX_LEN; } else if( version == SNMP_VERSION_2C ) { ret = community_auth( session ); session->version = SNMP_VERSION_2C; } if( ret < 0 ) { // increment_stat( -ret ); if( (indata=asn_parse_header(indata, &inlength, &msgtype)) && asn_parse_int(indata, &inlength, &type, &reqid, sizeof(reqid)) ) { if( msgtype == REPORT_MSG ) return 0; if( !(session->qoS & USEC_QOS_GENREPORT) ) return 0; session->agentBoots = _agentBoots; session->agentClock = _agentStartTime; memcpy( session->agentID, _agentID, 12 ); session->MMS = SNMP_MAX_LEN; create_report( session, outdata, outlength, -ret, reqid ); return 1; } else { return 0; } } else if( ret > 0 ) { // increment_stat( ret ); return 0; } } else { #endif ///////////////////////////////////////////////////// //VERSION 1 if(community_auth( session )==0) return 0; // session->version = SNMP_VERSION_1; #if 0 //////// } #endif /////// indata = asn_parse_header(indata, &inlength, &msgtype); if (indata == NULL){ // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("bad header"); return 0; } // XXX: increment by total number of vars at correct place: snmp_intotalreqvars++; if(msgtype == GET_REQ_MSG) snmp_ingetrequests++; else if (msgtype == GETNEXT_REQ_MSG) snmp_ingetnexts++; else if (msgtype == SET_REQ_MSG) snmp_insetrequests++; else return 0; // if (msgtype == GETBULK_REQ_MSG: //version 2 // Request ID indata = asn_parse_int(indata, &inlength, &type, &reqid, sizeof(reqid)); if (indata == NULL){ // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("bad parse of reqid"); return 0; } //Error Status indata = asn_parse_int(indata, &inlength, &type, &errstat, sizeof(errstat)); if (indata == NULL){ // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("bad parse of errstat"); snmp_inasnparseerrors++; return 0; } //Error Index indata = asn_parse_int(indata, &inlength, &type, &errindex, sizeof(errindex)); if (indata == NULL){ // increment_stat( SNMP_STAT_ENCODING_ERRORS ); ERROR("bad parse of errindex"); return 0; } // // Now start cobbling together what is known about the output packet. // The final lengths are not known now, so they will have to be recomputed // later. // // setup for response //Simon time( (time_t *) &session->agentTime ); //Simon session->agentClock = _agentStartTime; //Simon session->agentBoots = _agentBoots; //Simon memcpy( session->agentID, _agentID, 12 ); out_auth = outdata; //Set Resp Community out_header = snmp_build_auth(out_auth, outlength, community,session->community_len, (long)SNMP_VERSION_1,0); if (out_header == NULL){ ERROR("snmp_build_auth failed"); snmp_inasnparseerrors++; return 0; } out_reqid = asn_build_sequence(out_header, outlength, (uint8)GET_RSP_MSG, 0); if (out_reqid == NULL){ ERROR("out_reqid == NULL"); return 0; } //Set Resp ID type = (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER); // return identical request id outdata = asn_build_int(out_reqid, outlength, type, &reqid, sizeof(reqid)); if (outdata == NULL){ ERROR("build reqid failed"); return 0; } // assume that error status will be zero outdata = asn_build_int(outdata, outlength, type, &zero, sizeof(zero)); if (outdata == NULL){ ERROR("build errstat failed"); return 0; } // assume that error index will be zero outdata = asn_build_int(outdata, outlength, type, &zero, sizeof(zero)); if (outdata == NULL){ ERROR("build errindex failed"); return 0; } #if 0 /////////////////////////////////////////// if (msgtype == GETBULK_REQ_MSG) errstat = bulk_var_op_list(indata, inlength, outdata, *outlength, errstat, errindex, &errindex ); else #endif 0 //////////////////////////////////////// errstat = parse_var_op_list(session, indata, inlength, outdata, *outlength, &errindex, msgtype, RESERVE1); if (msgtype== SET_REQ_MSG){ if (errstat == SNMP_ERR_NOERROR) errstat = parse_var_op_list(session, indata, inlength, outdata, *outlength, &errindex, msgtype, RESERVE2); if (errstat == SNMP_ERR_NOERROR){ // //* SETS require 3-4 passes through the var_op_list. The first two //* passes verify that all types, lengths, and values are valid //* and may reserve resources and the third does the set and a //* fourth executes any actions. Then the identical GET RESPONSE //* packet is returned. //* If either of the first two passes returns an error, another //* pass is made so that any reserved resources can be freed. //* parse_var_op_list(session, indata, inlength, outdata, *outlength, &dummyindex, msgtype, COMMIT); parse_var_op_list(session, indata, inlength, outdata, *outlength, &dummyindex, msgtype, ACTION); if (create_identical(session, startData, out_auth, startLength, 0L, 0L )){ *outlength = packet_end - out_auth; return 1; } return 0; } else { parse_var_op_list(session, indata, inlength, outdata, *outlength, &dummyindex, msgtype, COMM_FREE); } } switch((short)errstat){ case SNMP_ERR_NOERROR: // re-encode the headers with the real lengths *outlength = packet_end - out_header; packet_len = *outlength; outdata = asn_build_sequence(out_header, outlength, GET_RSP_MSG, packet_end - out_reqid); // add --- By arius 5/17/2000 #ifdef WEBADMIN newoutdata = packet_end - outdata; // how many shifts len = packet_end - out_reqid; packet_end = outdata; // save new pointer end of packet outdata -= len; out_reqid = out_reqid - newoutdata; #endif WEBADMIN // end of here if (outdata != out_reqid){ ERROR("internal error: header"); return 0; } *outlength = packet_end - out_auth; outdata = snmp_build_auth(out_auth, outlength, community, session->community_len, (long)SNMP_VERSION_1, packet_end - out_header ); // add --- By arius 5/17/2000 #ifdef WEBADMIN out_header -= (packet_end - outdata); packet_end = outdata; // save new pointer end of packet #endif WEBADMIN // end of here *outlength = packet_end - out_auth; #if 0 // packet_end is correct for old SNMP. This dichotomy needs to be fixed. if (session->version == SNMP_VERSION_2) packet_end = out_auth + packet_len; #endif break; case SNMP_ERR_TOOBIG: snmp_intoobigs++; #if notdone if (session->version == SNMP_VERSION_2){ create_toobig(out_auth, *outlength, reqid, pi); break; } // else FALLTHRU #endif case SNMP_ERR_NOACCESS: case SNMP_ERR_WRONGTYPE: case SNMP_ERR_WRONGLENGTH: case SNMP_ERR_WRONGENCODING: case SNMP_ERR_WRONGVALUE: case SNMP_ERR_NOCREATION: case SNMP_ERR_INCONSISTENTVALUE: case SNMP_ERR_RESOURCEUNAVAILABLE: case SNMP_ERR_COMMITFAILED: case SNMP_ERR_UNDOFAILED: case SNMP_ERR_AUTHORIZATIONERROR: case SNMP_ERR_NOTWRITABLE: case SNMP_ERR_INCONSISTENTNAME: case SNMP_ERR_NOSUCHNAME: case SNMP_ERR_BADVALUE: case SNMP_ERR_READONLY: case SNMP_ERR_GENERR: if (create_identical(session, startData, out_auth, startLength, errstat, errindex)){ *outlength = packet_end - out_auth; return 1; } return 0; default: return 0; } #if 0 if( session->qoS & USEC_QOS_AUTH ) { md5Digest( out_auth, *outlength, outdata - (session->contextLen + 16), outdata - (session->contextLen + 16) ); } #endif return 1; }
//* //*--------------------------------------------------------------------------------- //* Function Name: snmp_build_auth //* Description : Encodes the community name and version number in BER encoding //* rules. //* Return Value : pointer of message with community name and version number encoded //* in it. //*--------------------------------------------------------------------------------- //* uint8 *snmp_build_auth( uint8 *outdata, int *outlength, uint8 *community, int community_len, long version, int messagelen ) { // build the the message wrapper (30 82 Length) // 5 bytes = version header + version value + community header // add -- By arius 5/17/2000 #ifdef WEBADMIN uint8 *oldoutdata; int newoutlength; oldoutdata = outdata; outdata = asn_build_sequence(outdata, outlength, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); #else outdata = asn_build_sequence(outdata, outlength, (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), messagelen + community_len + 5); #endif WEBADMIN // end of here if (outdata == NULL){ ERROR("buildheader"); return NULL; } // store the version field (02 length version) outdata = asn_build_int(outdata, outlength, (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &version, sizeof(version)); if(outdata == NULL){ ERROR("buildint"); return NULL; } outdata = asn_build_string(outdata, outlength, (uint8)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STRING), community, community_len); if(outdata == NULL){ ERROR("buildstring"); return NULL; } // add -- By arius 5/17/2000 #ifdef WEBADMIN if (messagelen) { newoutlength = *outlength + (community_len + 5 + 4); // (default 4) include 30 82 Length outdata = asn_build_sequence(oldoutdata, &newoutlength , (uint8)(ASN_SEQUENCE | ASN_CONSTRUCTOR), messagelen + community_len + 5); } #endif WEBADMIN // end of here return outdata; }