Beispiel #1
0
int
mps_getreq(struct snmp_message *msg, struct ber_element *root,
    struct ber_oid *o, u_int sm_version)
{
	struct ber_element	*elm = root;
	struct oid		 key, *value;
	unsigned long		 error_type = 0;	/* noSuchObject */

	if (o->bo_n > BER_MAX_OID_LEN)
		return (-1);
	bzero(&key, sizeof(key));
	bcopy(o, &key.o_id, sizeof(struct ber_oid));
	smi_oidlen(&key.o_id);	/* Strip off any trailing .0. */
	value = smi_find(&key);
	if (value == NULL)
		goto fail;

	if (OID_NOTSET(value))
		return (-1);

	if (value->o_flags & OID_REGISTERED) {
		struct agentx_pdu	*pdu;

		if ((pdu = snmp_agentx_get_pdu((struct snmp_oid *)o, 1)) == NULL)
			return (-1);
		pdu->cookie = msg;
		if (snmp_agentx_send(value->o_session->handle, pdu) == -1)
			return (-1);

		control_event_add(value->o_session,
		    value->o_session->handle->fd, EV_WRITE, NULL);
		return (1);
	}

	if (value->o_get == NULL)
		goto fail;

	if (value->o_oidlen == o->bo_n) {
		/* No instance identifier specified. */
		error_type = 1;	/* noSuchInstance */
		goto fail;
	}

	if ((value->o_flags & OID_TABLE) == 0)
		elm = ber_add_oid(elm, o);
	if (value->o_get(value, o, &elm) != 0)
		return (-1);

	return (0);

fail:
	if (sm_version == 0)
		return (-1);

	/* Set SNMPv2 extended error response. */
	elm = ber_add_oid(elm, o);
	elm = ber_add_null(elm);
	ber_set_header(elm, BER_CLASS_CONTEXT, error_type);
	return (0);
}
Beispiel #2
0
/*
 * Convert variable bindings from AgentX to SNMP dialect.
 */
int
varbind_convert(struct agentx_pdu *pdu, struct agentx_varbind_hdr *vbhdr,
    struct ber_element **varbind, struct ber_element **iter)
{
	struct ber_oid			 oid;
	u_int32_t			 d;
	u_int64_t			 l;
	int				 slen;
	char				*str;
	struct ber_element		*a;
	int				 ret = AGENTX_ERR_NONE;

	if (snmp_agentx_read_oid(pdu, (struct snmp_oid *)&oid) == -1) {
		ret = AGENTX_ERR_PARSE_ERROR;
		goto done;
	}

	*iter = ber_add_sequence(*iter);
	if (*varbind == NULL)
		*varbind = *iter;

	a = ber_add_oid(*iter, &oid);

	switch (vbhdr->type) {
	case AGENTX_NO_SUCH_OBJECT:
	case AGENTX_NO_SUCH_INSTANCE:
	case AGENTX_END_OF_MIB_VIEW:
	case AGENTX_NULL:
		a = ber_add_null(a);
		break;

	case AGENTX_IP_ADDRESS:
	case AGENTX_OPAQUE:
	case AGENTX_OCTET_STRING:
		str = snmp_agentx_read_octetstr(pdu, &slen);
		if (str == NULL) {
			ret = AGENTX_ERR_PARSE_ERROR;
			goto done;
		}
		a = ber_add_nstring(a, str, slen);
		break;

	case AGENTX_OBJECT_IDENTIFIER:
		if (snmp_agentx_read_oid(pdu,
		    (struct snmp_oid *)&oid) == -1) {
			ret = AGENTX_ERR_PARSE_ERROR;
			goto done;
		}
		a = ber_add_oid(a, &oid);
		break;

	case AGENTX_INTEGER:
	case AGENTX_COUNTER32:
	case AGENTX_GAUGE32:
	case AGENTX_TIME_TICKS:
		if (snmp_agentx_read_int(pdu, &d) == -1) {
			ret = AGENTX_ERR_PARSE_ERROR;
			goto done;
		}
		a = ber_add_integer(a, d);
		break;

	case AGENTX_COUNTER64:
		if (snmp_agentx_read_int64(pdu, &l) == -1) {
			ret = AGENTX_ERR_PARSE_ERROR;
			goto done;
		}
		a = ber_add_integer(a, l);
		break;

	default:
		log_debug("unknown data type '%i'", vbhdr->type);
		ret = AGENTX_ERR_PARSE_ERROR;
		goto done;
	}

	/* AgentX types correspond to BER types */
	switch (vbhdr->type) {
	case BER_TYPE_INTEGER:
	case BER_TYPE_BITSTRING:
	case BER_TYPE_OCTETSTRING:
	case BER_TYPE_NULL:
	case BER_TYPE_OBJECT:
		/* universal types */
		break;

	/* Convert AgentX error types to SNMP error types */
	case AGENTX_NO_SUCH_OBJECT:
		ber_set_header(a, BER_CLASS_CONTEXT, 0);
		break;
	case AGENTX_NO_SUCH_INSTANCE:
		ber_set_header(a, BER_CLASS_CONTEXT, 1);
		break;

	case AGENTX_COUNTER32:
		ber_set_header(a, BER_CLASS_APPLICATION, SNMP_COUNTER32);
		break;

	case AGENTX_GAUGE32:
		ber_set_header(a, BER_CLASS_APPLICATION, SNMP_GAUGE32);
		break;

	case AGENTX_COUNTER64:
		ber_set_header(a, BER_CLASS_APPLICATION, SNMP_COUNTER64);
		break;

	case AGENTX_IP_ADDRESS:
		/* application 0 implicit 4-byte octet string per SNMPv2-SMI */
		break;

	default:
		/* application-specific types */
		ber_set_header(a, BER_CLASS_APPLICATION, vbhdr->type);
		break;
	}
 done:
	return (ret);
}