unsigned int send_request(Options *options, int socket, char *agent_host, int agent_port, char *oid) { SNMPMessage *message; int len; unsigned char *buf; unsigned long int request_id = next_request_id++; message = snmp_create_message(); snmp_set_version(message, 0); snmp_set_community(message, "public"); snmp_set_pdu_type(message, SNMP_GET_REQUEST_TYPE); snmp_set_request_id(message, request_id); snmp_set_error(message, 0); snmp_set_error_index(message, 0); snmp_add_varbind_null(message, oid); len = snmp_message_length(message); buf = malloc(len); snmp_render_message(message, buf); if (options->verbose) snmp_print_message(message, stderr); snmp_destroy_message(message); if (options->verbose) fprintf(stderr, "Sending datagram to %s:%d\n", agent_host, agent_port); send_udp_datagram(buf, len, socket, agent_host, agent_port); free(buf); return request_id; }
static int /* O - 0 on success, -1 on error */ asn1_decode_snmp(unsigned char *buffer, /* I - Buffer */ size_t len, /* I - Size of buffer */ cups_snmp_t *packet) /* I - SNMP packet */ { unsigned char *bufptr, /* Pointer into the data */ *bufend; /* End of data */ int length; /* Length of value */ /* * Initialize the decoding... */ memset(packet, 0, sizeof(cups_snmp_t)); packet->object_name[0] = -1; bufptr = buffer; bufend = buffer + len; if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) snmp_set_error(packet, _("Packet does not start with SEQUENCE")); else if (asn1_get_length(&bufptr, bufend) == 0) snmp_set_error(packet, _("SEQUENCE uses indefinite length")); else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) snmp_set_error(packet, _("No version number")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("Version uses indefinite length")); else if ((packet->version = asn1_get_integer(&bufptr, bufend, length)) != CUPS_SNMP_VERSION_1) snmp_set_error(packet, _("Bad SNMP version number")); else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_OCTET_STRING) snmp_set_error(packet, _("No community name")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("Community name uses indefinite length")); else { asn1_get_string(&bufptr, bufend, length, packet->community, sizeof(packet->community)); if ((packet->request_type = asn1_get_type(&bufptr, bufend)) != CUPS_ASN1_GET_RESPONSE) snmp_set_error(packet, _("Packet does not contain a Get-Response-PDU")); else if (asn1_get_length(&bufptr, bufend) == 0) snmp_set_error(packet, _("Get-Response-PDU uses indefinite length")); else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) snmp_set_error(packet, _("No request-id")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("request-id uses indefinite length")); else { packet->request_id = asn1_get_integer(&bufptr, bufend, length); if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) snmp_set_error(packet, _("No error-status")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("error-status uses indefinite length")); else { packet->error_status = asn1_get_integer(&bufptr, bufend, length); if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) snmp_set_error(packet, _("No error-index")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("error-index uses indefinite length")); else { packet->error_index = asn1_get_integer(&bufptr, bufend, length); if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) snmp_set_error(packet, _("No variable-bindings SEQUENCE")); else if (asn1_get_length(&bufptr, bufend) == 0) snmp_set_error(packet, _("variable-bindings uses indefinite length")); else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) snmp_set_error(packet, _("No VarBind SEQUENCE")); else if (asn1_get_length(&bufptr, bufend) == 0) snmp_set_error(packet, _("VarBind uses indefinite length")); else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_OID) snmp_set_error(packet, _("No name OID")); else if ((length = asn1_get_length(&bufptr, bufend)) == 0) snmp_set_error(packet, _("Name OID uses indefinite length")); else { asn1_get_oid(&bufptr, bufend, length, packet->object_name, CUPS_SNMP_MAX_OID); packet->object_type = asn1_get_type(&bufptr, bufend); if ((length = asn1_get_length(&bufptr, bufend)) == 0 && packet->object_type != CUPS_ASN1_NULL_VALUE && packet->object_type != CUPS_ASN1_OCTET_STRING) snmp_set_error(packet, _("Value uses indefinite length")); else { switch (packet->object_type) { case CUPS_ASN1_BOOLEAN : packet->object_value.boolean = asn1_get_integer(&bufptr, bufend, length); break; case CUPS_ASN1_INTEGER : packet->object_value.integer = asn1_get_integer(&bufptr, bufend, length); break; case CUPS_ASN1_NULL_VALUE : break; case CUPS_ASN1_OCTET_STRING : case CUPS_ASN1_BIT_STRING : case CUPS_ASN1_HEX_STRING : packet->object_value.string.num_bytes = length; asn1_get_string(&bufptr, bufend, length, (char *)packet->object_value.string.bytes, sizeof(packet->object_value.string.bytes)); break; case CUPS_ASN1_OID : asn1_get_oid(&bufptr, bufend, length, packet->object_value.oid, CUPS_SNMP_MAX_OID); break; case CUPS_ASN1_COUNTER : packet->object_value.counter = asn1_get_integer(&bufptr, bufend, length); break; case CUPS_ASN1_GAUGE : packet->object_value.gauge = asn1_get_integer(&bufptr, bufend, length); break; case CUPS_ASN1_TIMETICKS : packet->object_value.timeticks = asn1_get_integer(&bufptr, bufend, length); break; default : snmp_set_error(packet, _("Unsupported value type")); break; } } } } } } } return (packet->error ? -1 : 0); }