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