/*
 * SNMP test program for CUPS.
 *
 * Copyright 2008-2014 by Apple Inc.
 *
 * These coded instructions, statements, and computer programs are the
 * property of Apple Inc. and are protected by Federal copyright
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 * which should have been included with this file.  If this file is
 * missing or damaged, see the license at "http://www.cups.org/".
 *
 * This file is subject to the Apple OS-Developed Software exception.
 */

/*
 * Include necessary headers...
 */

#include "cups-private.h"
#include "snmp-private.h"


/*
 * Local functions...
 */

static void	print_packet(cups_snmp_t *packet, void *data);
static int	show_oid(int fd, const char *community,
		         http_addr_t *addr, const char *s, int walk);
static void	usage(void) __attribute__((noreturn));


/*
 * 'main()' - Main entry.
 */

int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  int			fd = -1;	/* SNMP socket */
  http_addrlist_t	*host = NULL;	/* Address of host */
  int			walk = 0;	/* Walk OIDs? */
  char			*oid = NULL;	/* Last OID shown */
  const char		*community;	/* Community name */


  fputs("_cupsSNMPDefaultCommunity: ", stdout);

  if ((community = _cupsSNMPDefaultCommunity()) == NULL)
  {
    puts("FAIL (NULL community name)");
    return (1);
  }

  printf("PASS (%s)\n", community);

 /*
  * Query OIDs from the command-line...
  */

  for (i = 1; i < argc; i ++)
    if (!strcmp(argv[i], "-c"))
    {
      i ++;

      if (i >= argc)
        usage();
      else
        community = argv[i];
    }
    else if (!strcmp(argv[i], "-d"))
      _cupsSNMPSetDebug(10);
    else if (!strcmp(argv[i], "-w"))
      walk = 1;
    else if (!host)
    {
      if ((host = httpAddrGetList(argv[i], AF_UNSPEC, "161")) == NULL)
      {
	printf("testsnmp: Unable to find \"%s\"!\n", argv[1]);
	return (1);
      }

      if (fd < 0)
      {
	fputs("_cupsSNMPOpen: ", stdout);

	if ((fd = _cupsSNMPOpen(host->addr.addr.sa_family)) < 0)
	{
	  printf("FAIL (%s)\n", strerror(errno));
	  return (1);
	}

	puts("PASS");
      }
    }
    else if (!show_oid(fd, community, &(host->addr), argv[i], walk))
      return (1);
    else
      oid = argv[i];

  if (!host)
    usage();

  if (!oid)
  {
    if (!show_oid(fd, community,  &(host->addr),
                  walk ? ".1.3.6.1.2.1.43" :
		         ".1.3.6.1.2.1.43.10.2.1.4.1.1", walk))
      return (1);
  }

  return (0);
}


/*
 * 'print_packet()' - Print the contents of the response packet.
 */

static void
print_packet(cups_snmp_t *packet,	/* I - SNMP response packet */
             void        *data)		/* I - User data pointer (not used) */
{
  unsigned	i;			/* Looping var */
  char		temp[1024];		/* Temporary OID string */


  (void)data;

  printf("%s = ", _cupsSNMPOIDToString(packet->object_name, temp, sizeof(temp)));

  switch (packet->object_type)
  {
    case CUPS_ASN1_BOOLEAN :
	printf("BOOLEAN %s\n",
	       packet->object_value.boolean ? "TRUE" : "FALSE");
	break;

    case CUPS_ASN1_INTEGER :
	printf("INTEGER %d\n", packet->object_value.integer);
	break;

    case CUPS_ASN1_BIT_STRING :
	printf("BIT-STRING \"%s\"\n",
	       (char *)packet->object_value.string.bytes);
	break;

    case CUPS_ASN1_OCTET_STRING :
	printf("OCTET-STRING \"%s\"\n",
	       (char *)packet->object_value.string.bytes);
	break;

    case CUPS_ASN1_NULL_VALUE :
	puts("NULL-VALUE");
	break;

    case CUPS_ASN1_OID :
	printf("OID %s\n", _cupsSNMPOIDToString(packet->object_value.oid,
	                                        temp, sizeof(temp)));
	break;

    case CUPS_ASN1_HEX_STRING :
	fputs("Hex-STRING", stdout);
	for (i = 0; i < packet->object_value.string.num_bytes; i ++)
	  printf(" %02X", packet->object_value.string.bytes[i]);
	putchar('\n');
	break;

    case CUPS_ASN1_COUNTER :
	printf("Counter %d\n", packet->object_value.counter);
	break;

    case CUPS_ASN1_GAUGE :
	printf("Gauge %u\n", packet->object_value.gauge);
	break;

    case CUPS_ASN1_TIMETICKS :
	printf("Timeticks %u days, %u:%02u:%02u.%02u\n",
	       packet->object_value.timeticks / 8640000,
	       (packet->object_value.timeticks / 360000) % 24,
	       (packet->object_value.timeticks / 6000) % 60,
	       (packet->object_value.timeticks / 100) % 60,
	       packet->object_value.timeticks % 100);
	break;

    default :
	printf("Unknown-%X\n", packet->object_type);
	break;
  }
}


/*
 * 'show_oid()' - Show the specified OID.
 */

static int				/* O - 1 on success, 0 on error */
show_oid(int         fd,		/* I - SNMP socket */
         const char  *community,	/* I - Community name */
	 http_addr_t *addr,		/* I - Address to query */
         const char  *s,		/* I - OID to query */
	 int         walk)		/* I - Walk OIDs? */
{
  int		i;			/* Looping var */
  int		oid[CUPS_SNMP_MAX_OID];	/* OID */
  cups_snmp_t	packet;			/* SNMP packet */
  char		temp[1024];		/* Temporary OID string */


  if (!_cupsSNMPStringToOID(s, oid, sizeof(oid) / sizeof(oid[0])))
  {
    puts("testsnmp: Bad OID");
    return (0);
  }

  if (walk)
  {
    printf("_cupsSNMPWalk(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp)));

    if (_cupsSNMPWalk(fd, addr, CUPS_SNMP_VERSION_1, community, oid, 5.0,
                     print_packet, NULL) < 0)
    {
      printf("FAIL (%s)\n", strerror(errno));
      return (0);
    }
  }
  else
  {
    printf("_cupsSNMPWrite(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp)));

    if (!_cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, community,
		       CUPS_ASN1_GET_REQUEST, 1, oid))
    {
      printf("FAIL (%s)\n", strerror(errno));
      return (0);
    }

    puts("PASS");

    fputs("_cupsSNMPRead(5.0): ", stdout);

    if (!_cupsSNMPRead(fd, &packet, 5.0))
    {
      puts("FAIL (timeout)");
      return (0);
    }

    if (!_cupsSNMPIsOID(&packet, oid))
    {
      printf("FAIL (bad OID %d", packet.object_name[0]);
      for (i = 1; packet.object_name[i] >= 0; i ++)
	printf(".%d", packet.object_name[i]);
      puts(")");
      return (0);
    }

    if (packet.error)
    {
      printf("FAIL (%s)\n", packet.error);
      return (0);
    }

    puts("PASS");

    print_packet(&packet, NULL);
  }

  return (1);
}


/*
 * 'usage()' - Show program usage and exit.
 */

static void
usage(void)
{
  puts("Usage: testsnmp [options] host-or-ip [oid ...]");
  puts("");
  puts("Options:");
  puts("");
  puts("  -c community    Set community name");
  puts("  -d              Enable debugging");
  puts("  -w              Walk all OIDs under the specified one");

  exit (1);
}
