summaryrefslogtreecommitdiff
path: root/backend/snmp.c
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-17 00:06:33 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-17 00:06:33 +0000
commit91c84a3551145559de2956179661e111e373db95 (patch)
treeea061b2b6ab3b9e4530347e35f5cde3511f8a305 /backend/snmp.c
parent080811b190031b9182e96dc76fc610fadfeaec21 (diff)
downloadcups-91c84a3551145559de2956179661e111e373db95.tar.gz
Import CUPS 1.4svn-r7226.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@582 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'backend/snmp.c')
-rw-r--r--backend/snmp.c1102
1 files changed, 25 insertions, 1077 deletions
diff --git a/backend/snmp.c b/backend/snmp.c
index 8969474ac..a001ff864 100644
--- a/backend/snmp.c
+++ b/backend/snmp.c
@@ -3,7 +3,7 @@
*
* SNMP discovery backend for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2006-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -21,38 +21,15 @@
* add_cache() - Add a cached device...
* add_device_uri() - Add a device URI to the cache.
* alarm_handler() - Handle alarm signals...
- * asn1_decode_snmp() - Decode a SNMP packet.
- * asn1_debug() - Decode an ASN1-encoded message.
- * asn1_encode_snmp() - Encode a SNMP packet.
- * asn1_get_integer() - Get an integer value.
- * asn1_get_length() - Get a value length.
- * asn1_get_oid() - Get an OID value.
- * asn1_get_packed() - Get a packed integer value.
- * asn1_get_string() - Get a string value.
- * asn1_get_type() - Get a value type.
- * asn1_set_integer() - Set an integer value.
- * asn1_set_length() - Set a value length.
- * asn1_set_oid() - Set an OID value.
- * asn1_set_packed() - Set a packed integer value.
- * asn1_size_integer() - Figure out the number of bytes needed for an
- * integer value.
- * asn1_size_length() - Figure out the number of bytes needed for a
- * length value.
- * asn1_size_oid() - Figure out the numebr of bytes needed for an
- * OID value.
- * asn1_size_packed() - Figure out the number of bytes needed for a
- * packed integer value.
* compare_cache() - Compare two cache entries.
* debug_printf() - Display some debugging information.
* fix_make_model() - Fix common problems in the make-and-model
* string.
* free_array() - Free an array of strings.
* free_cache() - Free the array of cached devices.
- * get_interface_addresses() - Get the broadcast address(es) associated
- * with an interface.
- * hex_debug() - Output hex debugging data...
+ * get_interface_addresses() - Get the broadcast address(es) associated with
+ * an interface.
* list_device() - List a device we found...
- * open_snmp_socket() - Open the SNMP broadcast socket.
* password_cb() - Handle authentication requests.
* probe_device() - Probe a device to discover whether it is a
* printer.
@@ -60,7 +37,6 @@
* read_snmp_response() - Read and parse a SNMP response...
* run_time() - Return the total running time...
* scan_devices() - Scan for devices using SNMP.
- * send_snmp_query() - Send an SNMP query packet.
* try_connect() - Try connecting on a port...
* update_cache() - Update a cached device...
*/
@@ -69,10 +45,11 @@
* Include necessary headers.
*/
-#include <cups/http-private.h>
#include "backend-private.h"
#include <cups/array.h>
#include <cups/file.h>
+#include <cups/snmp.h>
+#include <cups/http-private.h>
#include <regex.h>
@@ -133,28 +110,6 @@
*/
/*
- * Constants...
- */
-
-#define SNMP_PORT 161 /* SNMP well-known port */
-#define SNMP_MAX_OID 64 /* Maximum number of OID numbers */
-#define SNMP_MAX_PACKET 1472 /* Maximum size of SNMP packet */
-#define SNMP_MAX_STRING 512 /* Maximum size of string */
-#define SNMP_VERSION_1 0 /* SNMPv1 */
-
-#define ASN1_END_OF_CONTENTS 0x00 /* End-of-contents */
-#define ASN1_BOOLEAN 0x01 /* BOOLEAN */
-#define ASN1_INTEGER 0x02 /* INTEGER or ENUMERATION */
-#define ASN1_BIT_STRING 0x03 /* BIT STRING */
-#define ASN1_OCTET_STRING 0x04 /* OCTET STRING */
-#define ASN1_NULL_VALUE 0x05 /* NULL VALUE */
-#define ASN1_OID 0x06 /* OBJECT IDENTIFIER */
-#define ASN1_SEQUENCE 0x30 /* SEQUENCE */
-#define ASN1_GET_REQUEST 0xa0 /* Get-Request-PDU */
-#define ASN1_GET_RESPONSE 0xa2 /* Get-Response-PDU */
-
-
-/*
* Types...
*/
@@ -173,28 +128,6 @@ typedef struct snmp_cache_s /**** SNMP scan cache ****/
*make_and_model; /* device-make-and-model */
} snmp_cache_t;
-typedef struct snmp_packet_s /**** SNMP packet ****/
-{
- const char *error; /* Encode/decode error */
- int version; /* Version number */
- char community[SNMP_MAX_STRING];
- /* Community name */
- int request_type; /* Request type */
- int request_id; /* request-id value */
- int error_status; /* error-status value */
- int error_index; /* error-index value */
- int object_name[SNMP_MAX_OID];
- /* object-name value */
- int object_type; /* object-value type */
- union
- {
- int boolean; /* Boolean value */
- int integer; /* Integer value */
- int oid[SNMP_MAX_OID]; /* OID value */
- char string[SNMP_MAX_STRING];/* String value */
- } object_value; /* object-value value */
-} snmp_packet_t;
-
/*
* Private CUPS API to set the last error...
@@ -213,40 +146,6 @@ static void add_cache(http_addr_t *addr, const char *addrname,
const char *make_and_model);
static device_uri_t *add_device_uri(char *value);
static void alarm_handler(int sig);
-static int asn1_decode_snmp(unsigned char *buffer, size_t len,
- snmp_packet_t *packet);
-static void asn1_debug(unsigned char *buffer, size_t len,
- int indent);
-static int asn1_encode_snmp(unsigned char *buffer, size_t len,
- snmp_packet_t *packet);
-static int asn1_get_integer(unsigned char **buffer,
- unsigned char *bufend,
- int length);
-static int asn1_get_oid(unsigned char **buffer,
- unsigned char *bufend,
- int length, int *oid, int oidsize);
-static int asn1_get_packed(unsigned char **buffer,
- unsigned char *bufend);
-static char *asn1_get_string(unsigned char **buffer,
- unsigned char *bufend,
- int length, char *string,
- int strsize);
-static int asn1_get_length(unsigned char **buffer,
- unsigned char *bufend);
-static int asn1_get_type(unsigned char **buffer,
- unsigned char *bufend);
-static void asn1_set_integer(unsigned char **buffer,
- int integer);
-static void asn1_set_length(unsigned char **buffer,
- int length);
-static void asn1_set_oid(unsigned char **buffer,
- const int *oid);
-static void asn1_set_packed(unsigned char **buffer,
- int integer);
-static int asn1_size_integer(int integer);
-static int asn1_size_length(int length);
-static int asn1_size_oid(const int *oid);
-static int asn1_size_packed(int integer);
static int compare_cache(snmp_cache_t *a, snmp_cache_t *b);
static void debug_printf(const char *format, ...);
static void fix_make_model(char *make_model,
@@ -255,19 +154,13 @@ static void fix_make_model(char *make_model,
static void free_array(cups_array_t *a);
static void free_cache(void);
static http_addrlist_t *get_interface_addresses(const char *ifname);
-static void hex_debug(unsigned char *buffer, size_t len);
static void list_device(snmp_cache_t *cache);
-static int open_snmp_socket(void);
static const char *password_cb(const char *prompt);
static void probe_device(snmp_cache_t *device);
static void read_snmp_conf(const char *address);
static void read_snmp_response(int fd);
static double run_time(void);
static void scan_devices(int fd);
-static void send_snmp_query(int fd, http_addr_t *addr, int version,
- const char *community,
- const unsigned request_id,
- const int *oid);
static int try_connect(http_addr_t *addr, const char *addrname,
int port);
static void update_cache(snmp_cache_t *device, const char *uri,
@@ -282,11 +175,9 @@ static cups_array_t *Addresses = NULL;
static cups_array_t *Communities = NULL;
static cups_array_t *Devices = NULL;
static int DebugLevel = 0;
-static int DeviceDescOID[] = { 1, 3, 6, 1, 2, 1, 25, 3,
- 2, 1, 3, 1, 0 };
+static int DeviceDescOID[] = { CUPS_OID_hrDeviceDescr, 1, 0 };
static unsigned DeviceDescRequest;
-static int DeviceTypeOID[] = { 1, 3, 6, 1, 2, 1, 25, 3,
- 2, 1, 2, 1, 0 };
+static int DeviceTypeOID[] = { CUPS_OID_hrDeviceType, 1, 0 };
static unsigned DeviceTypeRequest;
static cups_array_t *DeviceURIs = NULL;
static int HostNameLookups = 0;
@@ -345,7 +236,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
* Open the SNMP socket...
*/
- if ((fd = open_snmp_socket()) < 0)
+ if ((fd = cupsSNMPOpen()) < 0)
return (1);
/*
@@ -354,6 +245,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
read_snmp_conf(argv[1]);
+ cupsSNMPSetDebug(DebugLevel);
+
Devices = cupsArrayNew((cups_array_func_t)compare_cache, NULL);
/*
@@ -366,7 +259,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
* Close, free, and return with no errors...
*/
- close(fd);
+ cupsSNMPClose(fd);
free_array(Addresses);
free_array(Communities);
@@ -548,798 +441,6 @@ alarm_handler(int sig) /* I - Signal number */
/*
- * 'asn1_decode_snmp()' - Decode a SNMP packet.
- */
-
-static int /* O - 0 on success, -1 on error */
-asn1_decode_snmp(unsigned char *buffer, /* I - Buffer */
- size_t len, /* I - Size of buffer */
- snmp_packet_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(snmp_packet_t));
-
- bufptr = buffer;
- bufend = buffer + len;
-
- if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
- packet->error = "Packet does not start with SEQUENCE";
- else if (asn1_get_length(&bufptr, bufend) == 0)
- packet->error = "SEQUENCE uses indefinite length";
- else if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
- packet->error = "No version number";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "Version uses indefinite length";
- else if ((packet->version = asn1_get_integer(&bufptr, bufend, length))
- != SNMP_VERSION_1)
- packet->error = "Bad SNMP version number";
- else if (asn1_get_type(&bufptr, bufend) != ASN1_OCTET_STRING)
- packet->error = "No community name";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "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))
- != ASN1_GET_RESPONSE)
- packet->error = "Packet does not contain a Get-Response-PDU";
- else if (asn1_get_length(&bufptr, bufend) == 0)
- packet->error = "Get-Response-PDU uses indefinite length";
- else if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
- packet->error = "No request-id";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "request-id uses indefinite length";
- else
- {
- packet->request_id = asn1_get_integer(&bufptr, bufend, length);
-
- if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
- packet->error = "No error-status";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "error-status uses indefinite length";
- else
- {
- packet->error_status = asn1_get_integer(&bufptr, bufend, length);
-
- if (asn1_get_type(&bufptr, bufend) != ASN1_INTEGER)
- packet->error = "No error-index";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "error-index uses indefinite length";
- else
- {
- packet->error_index = asn1_get_integer(&bufptr, bufend, length);
-
- if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
- packet->error = "No variable-bindings SEQUENCE";
- else if (asn1_get_length(&bufptr, bufend) == 0)
- packet->error = "variable-bindings uses indefinite length";
- else if (asn1_get_type(&bufptr, bufend) != ASN1_SEQUENCE)
- packet->error = "No VarBind SEQUENCE";
- else if (asn1_get_length(&bufptr, bufend) == 0)
- packet->error = "VarBind uses indefinite length";
- else if (asn1_get_type(&bufptr, bufend) != ASN1_OID)
- packet->error = "No name OID";
- else if ((length = asn1_get_length(&bufptr, bufend)) == 0)
- packet->error = "Name OID uses indefinite length";
- else
- {
- asn1_get_oid(&bufptr, bufend, length, packet->object_name,
- SNMP_MAX_OID);
-
- packet->object_type = asn1_get_type(&bufptr, bufend);
-
- if ((length = asn1_get_length(&bufptr, bufend)) == 0 &&
- packet->object_type != ASN1_NULL_VALUE &&
- packet->object_type != ASN1_OCTET_STRING)
- packet->error = "Value uses indefinite length";
- else
- {
- switch (packet->object_type)
- {
- case ASN1_BOOLEAN :
- packet->object_value.boolean =
- asn1_get_integer(&bufptr, bufend, length);
- break;
-
- case ASN1_INTEGER :
- packet->object_value.integer =
- asn1_get_integer(&bufptr, bufend, length);
- break;
-
- case ASN1_NULL_VALUE :
- break;
-
- case ASN1_OCTET_STRING :
- asn1_get_string(&bufptr, bufend, length,
- packet->object_value.string,
- SNMP_MAX_STRING);
- break;
-
- case ASN1_OID :
- asn1_get_oid(&bufptr, bufend, length,
- packet->object_value.oid, SNMP_MAX_OID);
- break;
-
- default :
- packet->error = "Unsupported value type";
- break;
- }
- }
- }
- }
- }
- }
- }
-
- return (packet->error ? -1 : 0);
-}
-
-
-/*
- * 'asn1_debug()' - Decode an ASN1-encoded message.
- */
-
-static void
-asn1_debug(unsigned char *buffer, /* I - Buffer */
- size_t len, /* I - Length of buffer */
- int indent) /* I - Indentation */
-{
- int i; /* Looping var */
- unsigned char *bufend; /* End of buffer */
- int integer; /* Number value */
- int oid[SNMP_MAX_OID]; /* OID value */
- char string[SNMP_MAX_STRING];/* String value */
- unsigned char value_type; /* Type of value */
- int value_length; /* Length of value */
-
-
- bufend = buffer + len;
-
- while (buffer < bufend)
- {
- /*
- * Get value type...
- */
-
- value_type = asn1_get_type(&buffer, bufend);
- value_length = asn1_get_length(&buffer, bufend);
-
- switch (value_type)
- {
- case ASN1_BOOLEAN :
- integer = asn1_get_integer(&buffer, bufend, value_length);
-
- fprintf(stderr, "DEBUG: %*sBOOLEAN %d bytes %d\n", indent, "",
- value_length, integer);
- break;
-
- case ASN1_INTEGER :
- integer = asn1_get_integer(&buffer, bufend, value_length);
-
- fprintf(stderr, "DEBUG: %*sINTEGER %d bytes %d\n", indent, "",
- value_length, integer);
- break;
-
- case ASN1_OCTET_STRING :
- fprintf(stderr, "DEBUG: %*sOCTET STRING %d bytes \"%s\"\n", indent, "",
- value_length, asn1_get_string(&buffer, bufend,
- value_length, string,
- sizeof(string)));
- break;
-
- case ASN1_NULL_VALUE :
- fprintf(stderr, "DEBUG: %*sNULL VALUE %d bytes\n", indent, "",
- value_length);
-
- buffer += value_length;
- break;
-
- case ASN1_OID :
- asn1_get_oid(&buffer, bufend, value_length, oid, SNMP_MAX_OID);
-
- fprintf(stderr, "DEBUG: %*sOID %d bytes ", indent, "",
- value_length);
- for (i = 0; oid[i]; i ++)
- fprintf(stderr, ".%d", oid[i]);
- putc('\n', stderr);
- break;
-
- case ASN1_SEQUENCE :
- fprintf(stderr, "DEBUG: %*sSEQUENCE %d bytes\n", indent, "",
- value_length);
- asn1_debug(buffer, value_length, indent + 4);
-
- buffer += value_length;
- break;
-
- case ASN1_GET_REQUEST :
- fprintf(stderr, "DEBUG: %*sGet-Request-PDU %d bytes\n", indent, "",
- value_length);
- asn1_debug(buffer, value_length, indent + 4);
-
- buffer += value_length;
- break;
-
- case ASN1_GET_RESPONSE :
- fprintf(stderr, "DEBUG: %*sGet-Response-PDU %d bytes\n", indent, "",
- value_length);
- asn1_debug(buffer, value_length, indent + 4);
-
- buffer += value_length;
- break;
-
- default :
- fprintf(stderr, "DEBUG: %*sUNKNOWN(%x) %d bytes\n", indent, "",
- value_type, value_length);
-
- buffer += value_length;
- break;
- }
- }
-}
-
-
-/*
- * 'asn1_encode_snmp()' - Encode a SNMP packet.
- */
-
-static int /* O - Length on success, -1 on error */
-asn1_encode_snmp(unsigned char *buffer, /* I - Buffer */
- size_t bufsize, /* I - Size of buffer */
- snmp_packet_t *packet) /* I - SNMP packet */
-{
- unsigned char *bufptr; /* Pointer into buffer */
- int total, /* Total length */
- msglen, /* Length of entire message */
- commlen, /* Length of community string */
- reqlen, /* Length of request */
- listlen, /* Length of variable list */
- varlen, /* Length of variable */
- namelen, /* Length of object name OID */
- valuelen; /* Length of object value */
-
-
- /*
- * Get the lengths of the community string, OID, and message...
- */
-
- namelen = asn1_size_oid(packet->object_name);
-
- switch (packet->object_type)
- {
- case ASN1_NULL_VALUE :
- valuelen = 0;
- break;
-
- case ASN1_BOOLEAN :
- valuelen = asn1_size_integer(packet->object_value.boolean);
- break;
-
- case ASN1_INTEGER :
- valuelen = asn1_size_integer(packet->object_value.integer);
- break;
-
- case ASN1_OCTET_STRING :
- valuelen = strlen(packet->object_value.string);
- break;
-
- case ASN1_OID :
- valuelen = asn1_size_oid(packet->object_value.oid);
- break;
-
- default :
- packet->error = "Unknown object type";
- return (-1);
- }
-
- varlen = 1 + asn1_size_length(namelen) + namelen +
- 1 + asn1_size_length(valuelen) + valuelen;
- listlen = 1 + asn1_size_length(varlen) + varlen;
- reqlen = 2 + asn1_size_integer(packet->request_id) +
- 2 + asn1_size_integer(packet->error_status) +
- 2 + asn1_size_integer(packet->error_index) +
- 1 + asn1_size_length(listlen) + listlen;
- commlen = strlen(packet->community);
- msglen = 2 + asn1_size_integer(packet->version) +
- 1 + asn1_size_length(commlen) + commlen +
- 1 + asn1_size_length(reqlen) + reqlen;
- total = 1 + asn1_size_length(msglen) + msglen;
-
- if (total > bufsize)
- {
- packet->error = "Message too large for buffer";
- return (-1);
- }
-
- /*
- * Then format the message...
- */
-
- bufptr = buffer;
-
- *bufptr++ = ASN1_SEQUENCE; /* SNMPv1 message header */
- asn1_set_length(&bufptr, msglen);
-
- asn1_set_integer(&bufptr, packet->version);
- /* version */
-
- *bufptr++ = ASN1_OCTET_STRING; /* community */
- asn1_set_length(&bufptr, commlen);
- memcpy(bufptr, packet->community, commlen);
- bufptr += commlen;
-
- *bufptr++ = packet->request_type; /* Get-Request-PDU */
- asn1_set_length(&bufptr, reqlen);
-
- asn1_set_integer(&bufptr, packet->request_id);
-
- asn1_set_integer(&bufptr, packet->error_status);
-
- asn1_set_integer(&bufptr, packet->error_index);
-
- *bufptr++ = ASN1_SEQUENCE; /* variable-bindings */
- asn1_set_length(&bufptr, listlen);
-
- *bufptr++ = ASN1_SEQUENCE; /* variable */
- asn1_set_length(&bufptr, varlen);
-
- asn1_set_oid(&bufptr, packet->object_name);
- /* ObjectName */
-
- switch (packet->object_type)
- {
- case ASN1_NULL_VALUE :
- *bufptr++ = ASN1_NULL_VALUE; /* ObjectValue */
- *bufptr++ = 0; /* Length */
- break;
-
- case ASN1_BOOLEAN :
- asn1_set_integer(&bufptr, packet->object_value.boolean);
- break;
-
- case ASN1_INTEGER :
- asn1_set_integer(&bufptr, packet->object_value.integer);
- break;
-
- case ASN1_OCTET_STRING :
- *bufptr++ = ASN1_OCTET_STRING;
- asn1_set_length(&bufptr, valuelen);
- memcpy(bufptr, packet->object_value.string, valuelen);
- bufptr += valuelen;
- break;
-
- case ASN1_OID :
- asn1_set_oid(&bufptr, packet->object_value.oid);
- break;
- }
-
- return (bufptr - buffer);
-}
-
-
-/*
- * 'asn1_get_integer()' - Get an integer value.
- */
-
-static int /* O - Integer value */
-asn1_get_integer(
- unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend, /* I - End of buffer */
- int length) /* I - Length of value */
-{
- int value; /* Integer value */
-
-
- for (value = 0;
- length > 0 && *buffer < bufend;
- length --, (*buffer) ++)
- value = (value << 8) | **buffer;
-
- return (value);
-}
-
-
-/*
- * 'asn1_get_length()' - Get a value length.
- */
-
-static int /* O - Length */
-asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend) /* I - End of buffer */
-{
- int length; /* Length */
-
-
- length = **buffer;
- (*buffer) ++;
-
- if (length & 128)
- length = asn1_get_integer(buffer, bufend, length & 127);
-
- return (length);
-}
-
-
-/*
- * 'asn1_get_oid()' - Get an OID value.
- */
-
-static int /* O - Last OID number */
-asn1_get_oid(
- unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend, /* I - End of buffer */
- int length, /* I - Length of value */
- int *oid, /* I - OID buffer */
- int oidsize) /* I - Size of OID buffer */
-{
- unsigned char *valend; /* End of value */
- int *oidend; /* End of OID buffer */
- int number; /* OID number */
-
-
- valend = *buffer + length;
- oidend = oid + oidsize - 1;
-
- if (valend > bufend)
- valend = bufend;
-
- number = asn1_get_packed(buffer, bufend);
-
- if (number < 80)
- {
- *oid++ = number / 40;
- number = number % 40;
- *oid++ = number;
- }
- else
- {
- *oid++ = 2;
- number -= 80;
- *oid++ = number;
- }
-
- while (*buffer < valend)
- {
- number = asn1_get_packed(buffer, bufend);
-
- if (oid < oidend)
- *oid++ = number;
- }
-
- *oid = 0;
-
- return (number);
-}
-
-
-/*
- * 'asn1_get_packed()' - Get a packed integer value.
- */
-
-static int /* O - Value */
-asn1_get_packed(
- unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend) /* I - End of buffer */
-{
- int value; /* Value */
-
-
- value = 0;
-
- while ((**buffer & 128) && *buffer < bufend)
- {
- value = (value << 7) | (**buffer & 127);
- (*buffer) ++;
- }
-
- if (*buffer < bufend)
- {
- value = (value << 7) | **buffer;
- (*buffer) ++;
- }
-
- return (value);
-}
-
-
-/*
- * 'asn1_get_string()' - Get a string value.
- */
-
-static char * /* O - String */
-asn1_get_string(
- unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend, /* I - End of buffer */
- int length, /* I - Value length */
- char *string, /* I - String buffer */
- int strsize) /* I - String buffer size */
-{
- if (length < 0)
- {
- /*
- * Disallow negative lengths!
- */
-
- fprintf(stderr, "ERROR: Bad ASN1 string length %d!\n", length);
- *string = '\0';
- }
- else if (length < strsize)
- {
- /*
- * String is smaller than the buffer...
- */
-
- if (length > 0)
- memcpy(string, *buffer, length);
-
- string[length] = '\0';
- }
- else
- {
- /*
- * String is larger than the buffer...
- */
-
- memcpy(string, buffer, strsize - 1);
- string[strsize - 1] = '\0';
- }
-
- if (length > 0)
- (*buffer) += length;
-
- return (string);
-}
-
-
-/*
- * 'asn1_get_type()' - Get a value type.
- */
-
-static int /* O - Type */
-asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */
- unsigned char *bufend) /* I - End of buffer */
-{
- int type; /* Type */
-
-
- type = **buffer;
- (*buffer) ++;
-
- if ((type & 31) == 31)
- type = asn1_get_packed(buffer, bufend);
-
- return (type);
-}
-
-
-/*
- * 'asn1_set_integer()' - Set an integer value.
- */
-
-static void
-asn1_set_integer(unsigned char **buffer,/* IO - Pointer in buffer */
- int integer) /* I - Integer value */
-{
- **buffer = ASN1_INTEGER;
- (*buffer) ++;
-
- if (integer > 0x7fffff || integer < -0x800000)
- {
- **buffer = 4;
- (*buffer) ++;
- **buffer = integer >> 24;
- (*buffer) ++;
- **buffer = integer >> 16;
- (*buffer) ++;
- **buffer = integer >> 8;
- (*buffer) ++;
- **buffer = integer;
- (*buffer) ++;
- }
- else if (integer > 0x7fff || integer < -0x8000)
- {
- **buffer = 3;
- (*buffer) ++;
- **buffer = integer >> 16;
- (*buffer) ++;
- **buffer = integer >> 8;
- (*buffer) ++;
- **buffer = integer;
- (*buffer) ++;
- }
- else if (integer > 0x7f || integer < -0x80)
- {
- **buffer = 2;
- (*buffer) ++;
- **buffer = integer >> 8;
- (*buffer) ++;
- **buffer = integer;
- (*buffer) ++;
- }
- else
- {
- **buffer = 1;
- (*buffer) ++;
- **buffer = integer;
- (*buffer) ++;
- }
-}
-
-
-/*
- * 'asn1_set_length()' - Set a value length.
- */
-
-static void
-asn1_set_length(unsigned char **buffer, /* IO - Pointer in buffer */
- int length) /* I - Length value */
-{
- if (length > 255)
- {
- **buffer = 0x82; /* 2-byte length */
- (*buffer) ++;
- **buffer = length >> 8;
- (*buffer) ++;
- **buffer = length;
- (*buffer) ++;
- }
- else if (length > 127)
- {
- **buffer = 0x81; /* 1-byte length */
- (*buffer) ++;
- **buffer = length;
- (*buffer) ++;
- }
- else
- {
- **buffer = length; /* Length */
- (*buffer) ++;
- }
-}
-
-
-/*
- * 'asn1_set_oid()' - Set an OID value.
- */
-
-static void
-asn1_set_oid(unsigned char **buffer, /* IO - Pointer in buffer */
- const int *oid) /* I - OID value */
-{
- **buffer = ASN1_OID;
- (*buffer) ++;
-
- asn1_set_length(buffer, asn1_size_oid(oid));
-
- asn1_set_packed(buffer, oid[0] * 40 + oid[1]);
-
- for (oid += 2; *oid; oid ++)
- asn1_set_packed(buffer, *oid);
-}
-
-
-/*
- * 'asn1_set_packed()' - Set a packed integer value.
- */
-
-static void
-asn1_set_packed(unsigned char **buffer, /* IO - Pointer in buffer */
- int integer) /* I - Integer value */
-{
- if (integer > 0xfffffff)
- {
- **buffer = (integer >> 28) & 0x7f;
- (*buffer) ++;
- }
-
- if (integer > 0x1fffff)
- {
- **buffer = (integer >> 21) & 0x7f;
- (*buffer) ++;
- }
-
- if (integer > 0x3fff)
- {
- **buffer = (integer >> 14) & 0x7f;
- (*buffer) ++;
- }
-
- if (integer > 0x7f)
- {
- **buffer = (integer >> 7) & 0x7f;
- (*buffer) ++;
- }
-
- **buffer = integer & 0x7f;
- (*buffer) ++;
-}
-
-/*
- * 'asn1_size_integer()' - Figure out the number of bytes needed for an
- * integer value.
- */
-
-static int /* O - Size in bytes */
-asn1_size_integer(int integer) /* I - Integer value */
-{
- if (integer > 0x7fffff || integer < -0x800000)
- return (4);
- else if (integer > 0x7fff || integer < -0x8000)
- return (3);
- else if (integer > 0x7f || integer < -0x80)
- return (2);
- else
- return (1);
-}
-
-
-/*
- * 'asn1_size_length()' - Figure out the number of bytes needed for a
- * length value.
- */
-
-static int /* O - Size in bytes */
-asn1_size_length(int length) /* I - Length value */
-{
- if (length > 0xff)
- return (3);
- else if (length > 0x7f)
- return (2);
- else
- return (1);
-}
-
-
-/*
- * 'asn1_size_oid()' - Figure out the numebr of bytes needed for an
- * OID value.
- */
-
-static int /* O - Size in bytes */
-asn1_size_oid(const int *oid) /* I - OID value */
-{
- int length; /* Length of value */
-
-
- for (length = asn1_size_packed(oid[0] * 40 + oid[1]), oid += 2; *oid; oid ++)
- length += asn1_size_packed(*oid);
-
- return (length);
-}
-
-
-/*
- * 'asn1_size_packed()' - Figure out the number of bytes needed for a
- * packed integer value.
- */
-
-static int /* O - Size in bytes */
-asn1_size_packed(int integer) /* I - Integer value */
-{
- if (integer > 0xfffffff)
- return (5);
- else if (integer > 0x1fffff)
- return (4);
- else if (integer > 0x3fff)
- return (3);
- else if (integer > 0x7f)
- return (2);
- else
- return (1);
-}
-
-
-/*
* 'compare_cache()' - Compare two cache entries.
*/
@@ -1549,35 +650,6 @@ get_interface_addresses(
/*
- * 'hex_debug()' - Output hex debugging data...
- */
-
-static void
-hex_debug(unsigned char *buffer, /* I - Buffer */
- size_t len) /* I - Number of bytes */
-{
- int col; /* Current column */
-
-
- fputs("DEBUG: Hex dump of packet:\n", stderr);
-
- for (col = 0; len > 0; col ++, buffer ++, len --)
- {
- if ((col & 15) == 0)
- fprintf(stderr, "DEBUG: %04X ", col);
-
- fprintf(stderr, " %02X", *buffer);
-
- if ((col & 15) == 15)
- putc('\n', stderr);
- }
-
- if (col & 15)
- putc('\n', stderr);
-}
-
-
-/*
* 'list_device()' - List a device we found...
*/
@@ -1594,49 +666,6 @@ list_device(snmp_cache_t *cache) /* I - Cached device */
/*
- * 'open_snmp_socket()' - Open the SNMP broadcast socket.
- */
-
-static int /* O - SNMP socket file descriptor */
-open_snmp_socket(void)
-{
- int fd; /* SNMP socket file descriptor */
- int val; /* Socket option value */
-
-
- /*
- * Create the SNMP socket...
- */
-
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- fprintf(stderr, "ERROR: Unable to create SNMP socket - %s\n",
- strerror(errno));
-
- return (-1);
- }
-
- /*
- * Set the "broadcast" flag...
- */
-
- val = 1;
-
- if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
- {
- fprintf(stderr, "ERROR: Unable to set broadcast mode - %s\n",
- strerror(errno));
-
- close(fd);
-
- return (-1);
- }
-
- return (fd);
-}
-
-
-/*
* 'password_cb()' - Handle authentication requests.
*
* All we do right now is return NULL, indicating that no authentication
@@ -1862,12 +891,8 @@ read_snmp_conf(const char *address) /* I - Single address to probe */
static void
read_snmp_response(int fd) /* I - SNMP socket file descriptor */
{
- unsigned char buffer[SNMP_MAX_PACKET];/* Data packet */
- int bytes; /* Number of bytes received */
- http_addr_t addr; /* Source address */
- socklen_t addrlen; /* Source address length */
char addrname[256]; /* Source address name */
- snmp_packet_t packet; /* Decoded packet */
+ cups_snmp_t packet; /* Decoded packet */
snmp_cache_t key, /* Search key */
*device; /* Matching device */
@@ -1876,10 +901,7 @@ read_snmp_response(int fd) /* I - SNMP socket file descriptor */
* Read the response data...
*/
- addrlen = sizeof(addr);
-
- if ((bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (void *)&addr,
- &addrlen)) < 0)
+ if (!cupsSNMPRead(fd, &packet, -1))
{
fprintf(stderr, "ERROR: Unable to read data from socket: %s\n",
strerror(errno));
@@ -1887,24 +909,20 @@ read_snmp_response(int fd) /* I - SNMP socket file descriptor */
}
if (HostNameLookups)
- httpAddrLookup(&addr, addrname, sizeof(addrname));
+ httpAddrLookup(&(packet.address), addrname, sizeof(addrname));
else
- httpAddrString(&addr, addrname, sizeof(addrname));
+ httpAddrString(&(packet.address), addrname, sizeof(addrname));
- debug_printf("DEBUG: %.3f Received %d bytes from %s...\n", run_time(),
- bytes, addrname);
+ debug_printf("DEBUG: %.3f Received data from %s...\n", run_time(), addrname);
/*
* Look for the response status code in the SNMP message header...
*/
- if (asn1_decode_snmp(buffer, bytes, &packet))
+ if (packet.error)
{
- fprintf(stderr, "ERROR: Bad SNMP packet from %s: %s\n",
- addrname, packet.error);
-
- asn1_debug(buffer, bytes, 0);
- hex_debug(buffer, bytes);
+ fprintf(stderr, "ERROR: Bad SNMP packet from %s: %s\n", addrname,
+ packet.error);
return;
}
@@ -1913,12 +931,6 @@ read_snmp_response(int fd) /* I - SNMP socket file descriptor */
debug_printf("DEBUG: request-id=%d\n", packet.request_id);
debug_printf("DEBUG: error-status=%d\n", packet.error_status);
- if (DebugLevel > 1)
- asn1_debug(buffer, bytes, 0);
-
- if (DebugLevel > 2)
- hex_debug(buffer, bytes);
-
if (packet.error_status)
return;
@@ -1950,13 +962,13 @@ read_snmp_response(int fd) /* I - SNMP socket file descriptor */
* Add the device and request the device description...
*/
- add_cache(&addr, addrname, NULL, NULL, NULL);
+ add_cache(&(packet.address), addrname, NULL, NULL, NULL);
- send_snmp_query(fd, &addr, SNMP_VERSION_1, packet.community,
- DeviceDescRequest, DeviceDescOID);
+ cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, packet.community,
+ CUPS_ASN1_GET_REQUEST, DeviceDescRequest, DeviceDescOID);
}
else if (packet.request_id == DeviceDescRequest &&
- packet.object_type == ASN1_OCTET_STRING)
+ packet.object_type == CUPS_ASN1_OCTET_STRING)
{
/*
* Update an existing cache entry...
@@ -2085,8 +1097,8 @@ scan_devices(int fd) /* I - SNMP socket */
community, address);
for (addr = addrs; addr; addr = addr->next)
- send_snmp_query(fd, &(addr->addr), SNMP_VERSION_1, community,
- DeviceTypeRequest, DeviceTypeOID);
+ cupsSNMPWrite(fd, &(addr->addr), CUPS_SNMP_VERSION_1, community,
+ CUPS_ASN1_GET_REQUEST, DeviceTypeRequest, DeviceTypeOID);
}
httpAddrFreeList(addrs);
@@ -2137,70 +1149,6 @@ scan_devices(int fd) /* I - SNMP socket */
/*
- * 'send_snmp_query()' - Send an SNMP query packet.
- */
-
-static void
-send_snmp_query(
- int fd, /* I - SNMP socket */
- http_addr_t *addr, /* I - Address to send to */
- int version, /* I - SNMP version */
- const char *community, /* I - Community name */
- const unsigned request_id, /* I - Request ID */
- const int *oid) /* I - OID */
-{
- int i; /* Looping var */
- snmp_packet_t packet; /* SNMP message packet */
- unsigned char buffer[SNMP_MAX_PACKET];/* SNMP message buffer */
- int bytes; /* Size of message */
- char addrname[32]; /* Address name */
-
-
- /*
- * Create the SNMP message...
- */
-
- memset(&packet, 0, sizeof(packet));
-
- packet.version = version;
- packet.request_type = ASN1_GET_REQUEST;
- packet.request_id = request_id;
- packet.object_type = ASN1_NULL_VALUE;
-
- strlcpy(packet.community, community, sizeof(packet.community));
-
- for (i = 0; oid[i]; i ++)
- packet.object_name[i] = oid[i];
-
- bytes = asn1_encode_snmp(buffer, sizeof(buffer), &packet);
-
- if (bytes < 0)
- {
- fprintf(stderr, "ERROR: Unable to send SNMP query: %s\n",
- packet.error);
- return;
- }
-
- /*
- * Send the message...
- */
-
- debug_printf("DEBUG: %.3f Sending %d bytes to %s...\n", run_time(),
- bytes, httpAddrString(addr, addrname, sizeof(addrname)));
- if (DebugLevel > 1)
- asn1_debug(buffer, bytes, 0);
- if (DebugLevel > 2)
- hex_debug(buffer, bytes);
-
- addr->ipv4.sin_port = htons(SNMP_PORT);
-
- if (sendto(fd, buffer, bytes, 0, (void *)addr, sizeof(addr->ipv4)) < bytes)
- fprintf(stderr, "ERROR: Unable to send %d bytes to %s: %s\n",
- bytes, addrname, strerror(errno));
-}
-
-
-/*
* 'try_connect()' - Try connecting on a port...
*/