Home | History | Annotate | Download | only in cups
      1 /*
      2  * SNMP test program for CUPS.
      3  *
      4  * Copyright 2008-2014 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) __attribute__((noreturn));
     31 
     32 
     33 /*
     34  * 'main()' - Main entry.
     35  */
     36 
     37 int					/* O - Exit status */
     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
    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 */
    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
    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