1 /*
2 * SNMP test program for CUPS.
3 *
4 * Copyright 2008-2018 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) _CUPS_NORETURN;
31
32
33 /*
34 * 'main()' - Main entry.
35 */
36
37 int /* O - Exit status */
main(int argc,char * argv[])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
print_packet(cups_snmp_t * packet,void * data)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 */
show_oid(int fd,const char * community,http_addr_t * addr,const char * s,int walk)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
usage(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