• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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