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