1 /* 2 * SNMP test program for CUPS. 3 * 4 * Copyright 2008-2014 by Apple Inc. 5 * 6 * These coded instructions, statements, and computer programs are the 7 * property of Apple Inc. and are protected by Federal copyright 8 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 9 * which should have been included with this file. If this file is 10 * missing or damaged, see the license at "http://www.cups.org/". 11 * 12 * This file is subject to the Apple OS-Developed Software exception. 13 */ 14 15 /* 16 * Include necessary headers... 17 */ 18 19 #include "cups-private.h" 20 #include "snmp-private.h" 21 22 23 /* 24 * Local functions... 25 */ 26 27 static void print_packet(cups_snmp_t *packet, void *data); 28 static int show_oid(int fd, const char *community, 29 http_addr_t *addr, const char *s, int walk); 30 static void usage(void) __attribute__((noreturn)); 31 32 33 /* 34 * 'main()' - Main entry. 35 */ 36 37 int /* O - Exit status */ 38 main(int argc, /* I - Number of command-line args */ 39 char *argv[]) /* I - Command-line arguments */ 40 { 41 int i; /* Looping var */ 42 int fd = -1; /* SNMP socket */ 43 http_addrlist_t *host = NULL; /* Address of host */ 44 int walk = 0; /* Walk OIDs? */ 45 char *oid = NULL; /* Last OID shown */ 46 const char *community; /* Community name */ 47 48 49 fputs("_cupsSNMPDefaultCommunity: ", stdout); 50 51 if ((community = _cupsSNMPDefaultCommunity()) == NULL) 52 { 53 puts("FAIL (NULL community name)"); 54 return (1); 55 } 56 57 printf("PASS (%s)\n", community); 58 59 /* 60 * Query OIDs from the command-line... 61 */ 62 63 for (i = 1; i < argc; i ++) 64 if (!strcmp(argv[i], "-c")) 65 { 66 i ++; 67 68 if (i >= argc) 69 usage(); 70 else 71 community = argv[i]; 72 } 73 else if (!strcmp(argv[i], "-d")) 74 _cupsSNMPSetDebug(10); 75 else if (!strcmp(argv[i], "-w")) 76 walk = 1; 77 else if (!host) 78 { 79 if ((host = httpAddrGetList(argv[i], AF_UNSPEC, "161")) == NULL) 80 { 81 printf("testsnmp: Unable to find \"%s\"!\n", argv[1]); 82 return (1); 83 } 84 85 if (fd < 0) 86 { 87 fputs("_cupsSNMPOpen: ", stdout); 88 89 if ((fd = _cupsSNMPOpen(host->addr.addr.sa_family)) < 0) 90 { 91 printf("FAIL (%s)\n", strerror(errno)); 92 return (1); 93 } 94 95 puts("PASS"); 96 } 97 } 98 else if (!show_oid(fd, community, &(host->addr), argv[i], walk)) 99 return (1); 100 else 101 oid = argv[i]; 102 103 if (!host) 104 usage(); 105 106 if (!oid) 107 { 108 if (!show_oid(fd, community, &(host->addr), 109 walk ? ".1.3.6.1.2.1.43" : 110 ".1.3.6.1.2.1.43.10.2.1.4.1.1", walk)) 111 return (1); 112 } 113 114 return (0); 115 } 116 117 118 /* 119 * 'print_packet()' - Print the contents of the response packet. 120 */ 121 122 static void 123 print_packet(cups_snmp_t *packet, /* I - SNMP response packet */ 124 void *data) /* I - User data pointer (not used) */ 125 { 126 unsigned i; /* Looping var */ 127 char temp[1024]; /* Temporary OID string */ 128 129 130 (void)data; 131 132 printf("%s = ", _cupsSNMPOIDToString(packet->object_name, temp, sizeof(temp))); 133 134 switch (packet->object_type) 135 { 136 case CUPS_ASN1_BOOLEAN : 137 printf("BOOLEAN %s\n", 138 packet->object_value.boolean ? "TRUE" : "FALSE"); 139 break; 140 141 case CUPS_ASN1_INTEGER : 142 printf("INTEGER %d\n", packet->object_value.integer); 143 break; 144 145 case CUPS_ASN1_BIT_STRING : 146 printf("BIT-STRING \"%s\"\n", 147 (char *)packet->object_value.string.bytes); 148 break; 149 150 case CUPS_ASN1_OCTET_STRING : 151 printf("OCTET-STRING \"%s\"\n", 152 (char *)packet->object_value.string.bytes); 153 break; 154 155 case CUPS_ASN1_NULL_VALUE : 156 puts("NULL-VALUE"); 157 break; 158 159 case CUPS_ASN1_OID : 160 printf("OID %s\n", _cupsSNMPOIDToString(packet->object_value.oid, 161 temp, sizeof(temp))); 162 break; 163 164 case CUPS_ASN1_HEX_STRING : 165 fputs("Hex-STRING", stdout); 166 for (i = 0; i < packet->object_value.string.num_bytes; i ++) 167 printf(" %02X", packet->object_value.string.bytes[i]); 168 putchar('\n'); 169 break; 170 171 case CUPS_ASN1_COUNTER : 172 printf("Counter %d\n", packet->object_value.counter); 173 break; 174 175 case CUPS_ASN1_GAUGE : 176 printf("Gauge %u\n", packet->object_value.gauge); 177 break; 178 179 case CUPS_ASN1_TIMETICKS : 180 printf("Timeticks %u days, %u:%02u:%02u.%02u\n", 181 packet->object_value.timeticks / 8640000, 182 (packet->object_value.timeticks / 360000) % 24, 183 (packet->object_value.timeticks / 6000) % 60, 184 (packet->object_value.timeticks / 100) % 60, 185 packet->object_value.timeticks % 100); 186 break; 187 188 default : 189 printf("Unknown-%X\n", packet->object_type); 190 break; 191 } 192 } 193 194 195 /* 196 * 'show_oid()' - Show the specified OID. 197 */ 198 199 static int /* O - 1 on success, 0 on error */ 200 show_oid(int fd, /* I - SNMP socket */ 201 const char *community, /* I - Community name */ 202 http_addr_t *addr, /* I - Address to query */ 203 const char *s, /* I - OID to query */ 204 int walk) /* I - Walk OIDs? */ 205 { 206 int i; /* Looping var */ 207 int oid[CUPS_SNMP_MAX_OID]; /* OID */ 208 cups_snmp_t packet; /* SNMP packet */ 209 char temp[1024]; /* Temporary OID string */ 210 211 212 if (!_cupsSNMPStringToOID(s, oid, sizeof(oid) / sizeof(oid[0]))) 213 { 214 puts("testsnmp: Bad OID"); 215 return (0); 216 } 217 218 if (walk) 219 { 220 printf("_cupsSNMPWalk(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); 221 222 if (_cupsSNMPWalk(fd, addr, CUPS_SNMP_VERSION_1, community, oid, 5.0, 223 print_packet, NULL) < 0) 224 { 225 printf("FAIL (%s)\n", strerror(errno)); 226 return (0); 227 } 228 } 229 else 230 { 231 printf("_cupsSNMPWrite(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); 232 233 if (!_cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, community, 234 CUPS_ASN1_GET_REQUEST, 1, oid)) 235 { 236 printf("FAIL (%s)\n", strerror(errno)); 237 return (0); 238 } 239 240 puts("PASS"); 241 242 fputs("_cupsSNMPRead(5.0): ", stdout); 243 244 if (!_cupsSNMPRead(fd, &packet, 5.0)) 245 { 246 puts("FAIL (timeout)"); 247 return (0); 248 } 249 250 if (!_cupsSNMPIsOID(&packet, oid)) 251 { 252 printf("FAIL (bad OID %d", packet.object_name[0]); 253 for (i = 1; packet.object_name[i] >= 0; i ++) 254 printf(".%d", packet.object_name[i]); 255 puts(")"); 256 return (0); 257 } 258 259 if (packet.error) 260 { 261 printf("FAIL (%s)\n", packet.error); 262 return (0); 263 } 264 265 puts("PASS"); 266 267 print_packet(&packet, NULL); 268 } 269 270 return (1); 271 } 272 273 274 /* 275 * 'usage()' - Show program usage and exit. 276 */ 277 278 static void 279 usage(void) 280 { 281 puts("Usage: testsnmp [options] host-or-ip [oid ...]"); 282 puts(""); 283 puts("Options:"); 284 puts(""); 285 puts(" -c community Set community name"); 286 puts(" -d Enable debugging"); 287 puts(" -w Walk all OIDs under the specified one"); 288 289 exit (1); 290 } 291