/* * SNMP test program for CUPS. * * Copyright 2008-2014 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright * law. Distribution and use rights are outlined in the file "LICENSE.txt" * which should have been included with this file. If this file is * missing or damaged, see the license at "http://www.cups.org/". * * This file is subject to the Apple OS-Developed Software exception. */ /* * Include necessary headers... */ #include "cups-private.h" #include "snmp-private.h" /* * Local functions... */ static void print_packet(cups_snmp_t *packet, void *data); static int show_oid(int fd, const char *community, http_addr_t *addr, const char *s, int walk); static void usage(void) __attribute__((noreturn)); /* * 'main()' - Main entry. */ int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ int fd = -1; /* SNMP socket */ http_addrlist_t *host = NULL; /* Address of host */ int walk = 0; /* Walk OIDs? */ char *oid = NULL; /* Last OID shown */ const char *community; /* Community name */ fputs("_cupsSNMPDefaultCommunity: ", stdout); if ((community = _cupsSNMPDefaultCommunity()) == NULL) { puts("FAIL (NULL community name)"); return (1); } printf("PASS (%s)\n", community); /* * Query OIDs from the command-line... */ for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "-c")) { i ++; if (i >= argc) usage(); else community = argv[i]; } else if (!strcmp(argv[i], "-d")) _cupsSNMPSetDebug(10); else if (!strcmp(argv[i], "-w")) walk = 1; else if (!host) { if ((host = httpAddrGetList(argv[i], AF_UNSPEC, "161")) == NULL) { printf("testsnmp: Unable to find \"%s\"!\n", argv[1]); return (1); } if (fd < 0) { fputs("_cupsSNMPOpen: ", stdout); if ((fd = _cupsSNMPOpen(host->addr.addr.sa_family)) < 0) { printf("FAIL (%s)\n", strerror(errno)); return (1); } puts("PASS"); } } else if (!show_oid(fd, community, &(host->addr), argv[i], walk)) return (1); else oid = argv[i]; if (!host) usage(); if (!oid) { if (!show_oid(fd, community, &(host->addr), walk ? ".1.3.6.1.2.1.43" : ".1.3.6.1.2.1.43.10.2.1.4.1.1", walk)) return (1); } return (0); } /* * 'print_packet()' - Print the contents of the response packet. */ static void print_packet(cups_snmp_t *packet, /* I - SNMP response packet */ void *data) /* I - User data pointer (not used) */ { unsigned i; /* Looping var */ char temp[1024]; /* Temporary OID string */ (void)data; printf("%s = ", _cupsSNMPOIDToString(packet->object_name, temp, sizeof(temp))); switch (packet->object_type) { case CUPS_ASN1_BOOLEAN : printf("BOOLEAN %s\n", packet->object_value.boolean ? "TRUE" : "FALSE"); break; case CUPS_ASN1_INTEGER : printf("INTEGER %d\n", packet->object_value.integer); break; case CUPS_ASN1_BIT_STRING : printf("BIT-STRING \"%s\"\n", (char *)packet->object_value.string.bytes); break; case CUPS_ASN1_OCTET_STRING : printf("OCTET-STRING \"%s\"\n", (char *)packet->object_value.string.bytes); break; case CUPS_ASN1_NULL_VALUE : puts("NULL-VALUE"); break; case CUPS_ASN1_OID : printf("OID %s\n", _cupsSNMPOIDToString(packet->object_value.oid, temp, sizeof(temp))); break; case CUPS_ASN1_HEX_STRING : fputs("Hex-STRING", stdout); for (i = 0; i < packet->object_value.string.num_bytes; i ++) printf(" %02X", packet->object_value.string.bytes[i]); putchar('\n'); break; case CUPS_ASN1_COUNTER : printf("Counter %d\n", packet->object_value.counter); break; case CUPS_ASN1_GAUGE : printf("Gauge %u\n", packet->object_value.gauge); break; case CUPS_ASN1_TIMETICKS : printf("Timeticks %u days, %u:%02u:%02u.%02u\n", packet->object_value.timeticks / 8640000, (packet->object_value.timeticks / 360000) % 24, (packet->object_value.timeticks / 6000) % 60, (packet->object_value.timeticks / 100) % 60, packet->object_value.timeticks % 100); break; default : printf("Unknown-%X\n", packet->object_type); break; } } /* * 'show_oid()' - Show the specified OID. */ static int /* O - 1 on success, 0 on error */ show_oid(int fd, /* I - SNMP socket */ const char *community, /* I - Community name */ http_addr_t *addr, /* I - Address to query */ const char *s, /* I - OID to query */ int walk) /* I - Walk OIDs? */ { int i; /* Looping var */ int oid[CUPS_SNMP_MAX_OID]; /* OID */ cups_snmp_t packet; /* SNMP packet */ char temp[1024]; /* Temporary OID string */ if (!_cupsSNMPStringToOID(s, oid, sizeof(oid) / sizeof(oid[0]))) { puts("testsnmp: Bad OID"); return (0); } if (walk) { printf("_cupsSNMPWalk(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); if (_cupsSNMPWalk(fd, addr, CUPS_SNMP_VERSION_1, community, oid, 5.0, print_packet, NULL) < 0) { printf("FAIL (%s)\n", strerror(errno)); return (0); } } else { printf("_cupsSNMPWrite(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); if (!_cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, community, CUPS_ASN1_GET_REQUEST, 1, oid)) { printf("FAIL (%s)\n", strerror(errno)); return (0); } puts("PASS"); fputs("_cupsSNMPRead(5.0): ", stdout); if (!_cupsSNMPRead(fd, &packet, 5.0)) { puts("FAIL (timeout)"); return (0); } if (!_cupsSNMPIsOID(&packet, oid)) { printf("FAIL (bad OID %d", packet.object_name[0]); for (i = 1; packet.object_name[i] >= 0; i ++) printf(".%d", packet.object_name[i]); puts(")"); return (0); } if (packet.error) { printf("FAIL (%s)\n", packet.error); return (0); } puts("PASS"); print_packet(&packet, NULL); } return (1); } /* * 'usage()' - Show program usage and exit. */ static void usage(void) { puts("Usage: testsnmp [options] host-or-ip [oid ...]"); puts(""); puts("Options:"); puts(""); puts(" -c community Set community name"); puts(" -d Enable debugging"); puts(" -w Walk all OIDs under the specified one"); exit (1); }