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