FreeBSD/contrib/bsnmp/lib/snmpagent.c
/*
 * Execute a GET operation. The tree is rooted at the global 'root'.
 * Build the response PDU on the fly. If the return code is SNMP_RET_ERR
 * the pdu error status and index will be set.
 */
Execute a GET operation. The tree is rooted at the global 'root'.
Build the response PDU on the fly. If the return code is SNMP_RET_ERR
the pdu error status and index will be set.
Execute a GET operation . The tree is rooted at the global ' root ' . Build the response PDU on the fly . If the return code is SNMP_RET_ERR the pdu error status and index will be set .
enum snmp_ret
snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b,
    struct snmp_pdu *resp, void *data)
{
	int ret;
	u_int i;
	struct snmp_node *tp;
	enum snmp_syntax except;
	struct context context;
	enum asn_err err;
	memset(&context, 0, sizeof(context));
	context.ctx.data = data;
	snmp_pdu_create_response(pdu, resp);
	if (snmp_pdu_encode_header(resp_b, resp) != SNMP_CODE_OK)
		return (SNMP_RET_IGN);
	for (i = 0; i < pdu->nbindings; i++) {
		resp->bindings[i].var = pdu->bindings[i].var;
		if ((tp = find_node(&pdu->bindings[i], &except)) == NULL) {
			if (pdu->version == SNMP_V1) {
				if (TR(GET))
					snmp_debug("get: nosuchname");
				pdu->error_status = SNMP_ERR_NOSUCHNAME;
				pdu->error_index = i + 1;
				snmp_pdu_free(resp);
				return (SNMP_RET_ERR);
			}
			if (TR(GET))
				snmp_debug("get: exception %u", except);
			resp->bindings[i].syntax = except;
		} else {
			resp->bindings[i].syntax = tp->syntax;
			ret = (*tp->op)(&context.ctx, &resp->bindings[i],
			    tp->oid.len, tp->index, SNMP_OP_GET);
			if (TR(GET))
				snmp_debug("get: action returns %d", ret);
			if (ret == SNMP_ERR_NOSUCHNAME) {
				if (pdu->version == SNMP_V1) {
					pdu->error_status = SNMP_ERR_NOSUCHNAME;
					pdu->error_index = i + 1;
					snmp_pdu_free(resp);
					return (SNMP_RET_ERR);
				}
				if (TR(GET))
					snmp_debug("get: exception noSuchInstance");
				resp->bindings[i].syntax = SNMP_SYNTAX_NOSUCHINSTANCE;
			} else if (ret != SNMP_ERR_NOERROR) {
				pdu->error_status = SNMP_ERR_GENERR;
				pdu->error_index = i + 1;
				snmp_pdu_free(resp);
				return (SNMP_RET_ERR);
			}
		}
		resp->nbindings++;
		err = snmp_binding_encode(resp_b, &resp->bindings[i]);
		if (err == ASN_ERR_EOBUF) {
			pdu->error_status = SNMP_ERR_TOOBIG;
			pdu->error_index = 0;
			snmp_pdu_free(resp);
			return (SNMP_RET_ERR);
		}
		if (err != ASN_ERR_OK) {
			if (TR(GET))
				snmp_debug("get: binding encoding: %u", err);
			pdu->error_status = SNMP_ERR_GENERR;
			pdu->error_index = i + 1;
			snmp_pdu_free(resp);
			return (SNMP_RET_ERR);
		}
	}
	if (snmp_fix_encoding(resp_b, resp) != SNMP_CODE_OK) {
		snmp_debug("get: failed to encode PDU");
		return (SNMP_RET_ERR);
	}
	return (SNMP_RET_OK);
}
enum snmp_ret snmp_get ( struct snmp_pdu * pdu , struct asn_buf * resp_b , struct snmp_pdu * resp , void * data ) { int ret ; u_int i ; struct snmp_node * tp ; enum snmp_syntax except ; struct context context ; enum asn_err err ; memset ( & context , 0 , sizeof ( context ) ) ; context . ctx . data = data ; snmp_pdu_create_response ( pdu , resp ) ; if ( snmp_pdu_encode_header ( resp_b , resp ) != SNMP_CODE_OK ) return ( SNMP_RET_IGN ) ; for ( i = 0 ; i < pdu -> nbindings ; i ++ ) { resp -> bindings [ i ] . var = pdu -> bindings [ i ] . var ; if ( ( tp = find_node ( & pdu -> bindings [ i ] , & except ) ) == NULL ) { if ( pdu -> version == SNMP_V1 ) { if ( TR ( GET ) ) snmp_debug ( " " ) ; pdu -> error_status = SNMP_ERR_NOSUCHNAME ; pdu -> error_index = i + 1 ; snmp_pdu_free ( resp ) ; return ( SNMP_RET_ERR ) ; } if ( TR ( GET ) ) snmp_debug ( " " , except ) ; resp -> bindings [ i ] . syntax = except ; } else { resp -> bindings [ i ] . syntax = tp -> syntax ; ret = ( * tp -> op ) ( & context . ctx , & resp -> bindings [ i ] , tp -> oid . len , tp -> index , SNMP_OP_GET ) ; if ( TR ( GET ) ) snmp_debug ( " " , ret ) ; if ( ret == SNMP_ERR_NOSUCHNAME ) { if ( pdu -> version == SNMP_V1 ) { pdu -> error_status = SNMP_ERR_NOSUCHNAME ; pdu -> error_index = i + 1 ; snmp_pdu_free ( resp ) ; return ( SNMP_RET_ERR ) ; } if ( TR ( GET ) ) snmp_debug ( " " ) ; resp -> bindings [ i ] . syntax = SNMP_SYNTAX_NOSUCHINSTANCE ; } else if ( ret != SNMP_ERR_NOERROR ) { pdu -> error_status = SNMP_ERR_GENERR ; pdu -> error_index = i + 1 ; snmp_pdu_free ( resp ) ; return ( SNMP_RET_ERR ) ; } } resp -> nbindings ++ ; err = snmp_binding_encode ( resp_b , & resp -> bindings [ i ] ) ; if ( err == ASN_ERR_EOBUF ) { pdu -> error_status = SNMP_ERR_TOOBIG ; pdu -> error_index = 0 ; snmp_pdu_free ( resp ) ; return ( SNMP_RET_ERR ) ; } if ( err != ASN_ERR_OK ) { if ( TR ( GET ) ) snmp_debug ( " " , err ) ; pdu -> error_status = SNMP_ERR_GENERR ; pdu -> error_index = i + 1 ; snmp_pdu_free ( resp ) ; return ( SNMP_RET_ERR ) ; } } if ( snmp_fix_encoding ( resp_b , resp ) != SNMP_CODE_OK ) { snmp_debug ( " " ) ; return ( SNMP_RET_ERR ) ; } return ( SNMP_RET_OK ) ; }
Execute a GET operation.
Execute a GET operation .
/* cannot even encode header - very bad */ /* call the action to fetch the value. */