/*
**  GXSNMP -- An snmp management application
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
**  snmp_setup -- This subroutine creates and fills in a host_snmp
**                block for a host based on the contents of the 
**		  configuration file.
*/

/*REMOVE IF DEFINED AF_INET6 ELSEWHERE */

#define AF_INET6 0

#include <glib.h>
#include <g_snmp.h>

#include "main.h"
#include "config_file.h"

#define DEFAULT_READ_COMMUNITY  "public"
#define DEFAULT_WRITE_COMMUNITY "public"
#define DEFAULT_TIMEOUT         60
#define DEFAULT_RETRIES         3
#define DEFAULT_DOMAIN          "AF_INET"
#define DEFAULT_VERSION         "SNMP_V1"
#define DEFAULT_PORT            161


host_snmp *
snmp_setup (gchar * hostid)
{

  CONFIG_NODE * snmp;		/* The default SNMP settings */
  CONFIG_NODE * host_table;	/* The host table in the config file */
  CONFIG_NODE * host;		/* The desired host in the host table */
  CONFIG_NODE * hostsnmp;	/* The SNMP table in the desired host entry */
  CONFIG_NODE * cn;             /* Used to grab individual settings */
  host_snmp   * hs;		/* The block we are constructing */
  gchar       * string;


/*
**  First, look in the top level of the configuration file for nodes
**  named 'snmp' and 'host'
*/

  snmp       = config_node_lookup (config, "snmp");
  host_table = config_node_lookup (config, "host");

  if (!host_table)
    {
      g_print ("The configuration file contains no host table\n");
      return NULL;
    }

/*
**  Now look inside the host table for the specific host we are interested in
*/

  host = config_node_lookup (host_table, hostid);
  if (!host)
    {
      g_print ("Host %s was not found in the host table\n", hostid);
      return NULL;
    }

/*
**  Next see if that specific host has a snmp group in it
*/
 
  hostsnmp = config_node_lookup (host, "snmp");

/*
**  Now allocate a host_snmp block and fill it in.  Start with the name
**  of the host, as pulled from the 'name' element of the host entry.
*/

  cn = config_node_lookup (host, "name");
  if (!cn)
    {
      g_print ("Host %s has no 'name' field\n", hostid);
      return NULL;
    }
  if (!config_node_is_string (cn))
    {
      g_print ("Error:  Name field for host %s is not a string\n", hostid);
      return NULL;
    }

  hs = g_malloc0 (sizeof (host_snmp));  /* Allocate the result block */

  hs->name = g_strdup (config_node_get_string (cn));	/* Fill in the name */

/*
**  Now, for each element of the SNMP settings information, look first in the
**  hostsnmp branch for a local override, then look in the snmp branch for
**  the user-specified default value.  If neither are present, plug in a
**  reasonable default value from the top of this file.
*/

/********************* read community **********************/

  if ((cn = config_node_lookup (hostsnmp, "read_community")) != NULL)
    if (!config_node_is_string (cn))
      {
	g_print ("Error: SNMP read_community setting for host %s is not "
		 "a string.\n", hostid);
        cn = NULL;	/* Can't use it */
      }
  if (!cn)	/* Host-specific read_community string not usable */
    if ((cn = config_node_lookup (snmp, "read_community")) != NULL)
      if (!config_node_is_string (cn))
        {
          g_print ("Error: Default SNMP read_community setting is not "
		   "a string\n");
          cn = NULL;      /* Can't use it */
	}
  if (cn)	/* Found a valid read_community string */
    hs->rcomm = g_strdup (config_node_get_string (cn));
  else
    hs->rcomm = g_strdup (DEFAULT_READ_COMMUNITY);

/********************* write community **********************/

  if ((cn = config_node_lookup (hostsnmp, "write_community")) != NULL)
    if (!config_node_is_string (cn))
      {
        g_print ("Error: SNMP write_community setting for host %s is not "
                 "a string.\n", hostid);
        cn = NULL;
      }
  if (!cn)      
    if ((cn = config_node_lookup (snmp, "write_community")) != NULL)
      if (!config_node_is_string (cn))
        {
          g_print ("Error: Default SNMP write_community setting is not "
                   "a string.\n");
          cn = NULL;
        }
  if (cn)
    hs->wcomm = g_strdup (config_node_get_string (cn));
  else
    hs->wcomm = g_strdup (DEFAULT_WRITE_COMMUNITY);

/************************* timeout **************************/

  if ((cn = config_node_lookup (hostsnmp, "timeout")) != NULL)
    if (!config_node_is_number (cn))
      {
        g_print ("Error: SNMP timeout setting for host %s is "
                 "not a number.\n", hostid);
        cn = NULL;      
      }
  if (!cn)      
    if ((cn = config_node_lookup (snmp, "timeout")) != NULL)
      if (!config_node_is_number (cn))
        {
          g_print ("Error: Default SNMP timeout setting is not a number.\n");
          cn = NULL;      
        }
  if (cn)
    hs->timeout = config_node_get_number (cn);
  else
    hs->timeout = DEFAULT_TIMEOUT;

  
/************************* retries **************************/

  if ((cn = config_node_lookup (hostsnmp, "retries")) != NULL)
    if (!config_node_is_number (cn))
      {
        g_print ("Error: SNMP retries setting for host %s is "
                 "not a number.\n", hostid);
        cn = NULL;
      }
  if (!cn)
    if ((cn = config_node_lookup (snmp, "retries")) != NULL)
      if (!config_node_is_number (cn))
        {
          g_print ("Error: Default SNMP retries setting is not a number.\n");
          cn = NULL;
        }
  if (cn)
    hs->retries = config_node_get_number (cn);
  else
    hs->retries = DEFAULT_RETRIES;

/************************* domain **************************/

  string = NULL;
  if ((cn = config_node_lookup (hostsnmp, "domain")) != NULL)
    {
      if (config_node_is_string (cn))		/* If it's a string */
        {
          string = config_node_get_string (cn);
          if (strcmp (string, "AF_INET") &&     /* Make sure it's one */ 
              strcmp (string, "AF_IPX") &&  	/* of these strings */
              strcmp (string, "AF_INET6")) 
            cn = NULL;				/* Otherwise it's invalid */
        }
      else cn = NULL;		/* It's invalid if it isn't a string */
      if (!cn) 	
        {
          g_print ("Error: SNMP domain setting for host %s is invalid. "
                   "Valid settings are \"AF_INET\", \"AF_IPX\", and "
	  	   "\"AF_INET6\"\n", hostid);
          cn = NULL;
        }
    }
  if (!cn)
    if ((cn = config_node_lookup (snmp, "domain")) != NULL)
      {
        if (config_node_is_string (cn))		/* If it's a string */
        {                                       
          string = config_node_get_string (cn);
          if (strcmp (string, "AF_INET") &&     /* Make sure it's one */  
              strcmp (string, "AF_IPX") &&      /* of these strings */
              strcmp (string, "AF_INET6"))
            cn = NULL;				/* Otherwise it's invalid */
        }
      else cn = NULL;            /* It's invalid if it isn't a string */
      if (!cn)  
        {
          g_print ("Error: Default SNMP domain setting is invalid. "
                   "Valid settings are \"AF_INET\", \"AF_IPX\", and "
                   "\"AF_INET6\"\n");
          cn = NULL;
        }
    }
  if (!cn)			/* Fall back to the default value */
    string = DEFAULT_DOMAIN;	/* If we found nothing valid */

  if      (!strcmp (string, "AF_INET"))  hs->domain = AF_INET;
  else if (!strcmp (string, "AF_IPX"))   hs->domain = AF_IPX;
  else if (!strcmp (string, "AF_INET6")) hs->domain = AF_INET6;
  else g_print ("This should never happen!\n");

/************************* version **************************/

  if ((cn = config_node_lookup (hostsnmp, "version")) != NULL)
    {
      if (config_node_is_string (cn))		/* If it's a string */
        {
          string = config_node_get_string (cn);
          if (strcmp (string, "SNMP_V1") &&     /* Make sure it's one */
              strcmp (string, "SNMP_V2C") &&    /* of these strings */
	      strcmp (string, "SNMP_V2") &&
              strcmp (string, "SNMP_V3"))
            cn = NULL;				/* Otherwise it's invalid */
        }
      else cn = NULL;        	     /* It's invalid if it isn't a string */
      if (!cn)
        {
          g_print ("Error: SNMP version setting for host %s is invalid. "
                   "Valid settings are \"SNMP_V1\", \"SNMP_V2C\", "
                   "\"SNMP_V2\", and \"SNMP_V3\"\n", hostid);
          cn = NULL;
        }
    }
  if (!cn)
    if ((cn = config_node_lookup (snmp, "version")) != NULL)
      {
        if (config_node_is_string (cn))		/* If it's a string */
        {
          string = config_node_get_string (cn);
          if (strcmp (string, "SNMP_V1") &&     /* Make sure it's one */
              strcmp (string, "SNMP_V2C") &&    /* of these strings */
              strcmp (string, "SNMP_V2") &&
              strcmp (string, "SNMP_V3"))
            cn = NULL;				/* Otherwise it's invalid */
        }
      else cn = NULL;             /* It's invalid if it isn't a string */
      if (!cn)
        {
          g_print ("Error: Default SNMP version setting is invalid. "
                   "Valid settings are \"SNMP_V1\", \"SNMP_V2C\", "
                   "\"SNMP_V2\", and \"SNMP_V3\"\n");
          cn = NULL;
        }
    }
  if (cn)       /* means that 'string' has been validated */
    {
      if      (!strcmp (string, "SNMP_V1"))  hs->version = PMODEL_SNMPV1;
      else if (!strcmp (string, "SNMP_V2C")) hs->version = PMODEL_SNMPV2C;
      else if (!strcmp (string, "SNMP_V2"))  hs->version = PMODEL_SNMPV2;
      else if (!strcmp (string, "SNMP_V3"))  hs->version = PMODEL_SNMPV3;
      else g_print ("This should never happen!\n");
    }

/************************* port **************************/

  if ((cn = config_node_lookup (hostsnmp, "port")) != NULL)
    if (!config_node_is_number (cn))
      {
        g_print ("Error: SNMP port setting for host %s is "
                 "not a number.\n", hostid);
        cn = NULL;
      }
  if (!cn)
    if ((cn = config_node_lookup (snmp, "timeout")) != NULL)
      if (!config_node_is_number (cn))
        {
          g_print ("Error: Default SNMP port setting is not a number.\n");
          cn = NULL;
        }
  if (cn)
    hs->port = config_node_get_number (cn);
  else
    hs->port = DEFAULT_PORT;

/************ All finished.  Return the completed host_snmp block *******/

  return hs;
}

/* EOF */
