/*
** CBLM v3
** $Id: trap.c,v 1.2 2008/07/14 00:25:08 sella Exp $
** Copyright (c) 2005,2006 James M. Sella. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
*/

static const char rcsid[] = "$Id: trap.c,v 1.2 2008/07/14 00:25:08 sella Exp $";

#include "trap.h"

#include "prefs.h"

#include <snmptrap.h>

#include <string.h>
#include <stdlib.h>

#include <assert.h>
#include <errno.h>

/* Global Variables */
struct snmptrap_list_t *snmptrap_list = NULL;
struct snmptrap_list_t **sl_end = &snmptrap_list;

/* External Global Variables */
extern struct prefs_t prefs;
extern struct args_t args;
extern pid_t pid;
extern time_t startup_time;

int snmptrap_process_startup() {
	return snmptrap_pid(TRAP_PROCESS_STARTUP);
}

int snmptrap_process_shutdown() {
	return snmptrap_pid(TRAP_PROCESS_SHUTDOWN);
}

int snmptrap_process_restart() {
	return snmptrap_pid(TRAP_PROCESS_RESTART);
}

int snmptrap_database_down() {
	return snmptrap_database(TRAP_DATABASE_DOWN);
}

int snmptrap_database_up() {
	return snmptrap_database(TRAP_DATABASE_UP);
}

int snmptrap_database_reconfig() {
	return snmptrap_database(TRAP_DATABASE_RECONFIG);
}

int snmptrap_probe_threshold_alarm(int threshold_type, struct probe_t *probe, unsigned int current, unsigned int threshold) {
	return snmptrap_probe_threshold(TRAP_PROBE_THRESHOLD_ALARM, threshold_type, probe, current, threshold);
}

int snmptrap_probe_threshold_clear(int threshold_type, struct probe_t *probe, unsigned int current, unsigned int threshold) {
	return snmptrap_probe_threshold(TRAP_PROBE_THRESHOLD_CLEAR, threshold_type, probe, current, threshold);
}

int init_snmptrap_t(const char *trap_oid, snmptrap_t *trap) {
	int ret_val = 0;

	/* Zero trap struct */
	memset(trap, 0, sizeof(snmptrap_t));

	/* Setup trap structure */
	trap->sysUpTime = (time(NULL) - startup_time) * 100;
	strncpy(trap->sysObjectID, trap_oid, sizeof(trap->sysObjectID));
	trap->trap_type = 6; /* Only used for v1 */
	trap->specific_type = 0; /* Only used for v1 */
	trap->peer = prefs.peer;

	return ret_val;
}

int snmptrap_pid(const char *trap_oid) {
	int ret_val = 0;
	snmptrap_t trap;
	snmptrap_varbind_t *varbind = NULL;

	/* Any peers? */
	if (prefs.peer == NULL) {
		return 0;
	}

	/* Init trap struct */
	init_snmptrap_t(trap_oid, &trap);

	/* Setup varbind */
	trap.varbind = malloc(sizeof(snmptrap_varbind_t));

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_ID, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", pid);

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 'a';
	strncpy(varbind->var, OID_PROBE_ADDRESS, sizeof(varbind->var));
	inet_ntop(AF_INET, &args.source, varbind->val, sizeof(varbind->val));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_PROBE_NAME, sizeof(varbind->var));
	strncpy(varbind->val, args.name, sizeof(varbind->var));

	varbind->next = NULL;

	/* Send trap */
	ret_val = send_snmptrap(&trap);

	/* Free varbind memory */
   while (trap.varbind) {
      varbind = trap.varbind;
      trap.varbind = varbind->next;
      free(varbind);
   }

	return ret_val;
}

int snmptrap_database(const char* trap_oid) {
	int ret_val = 0;
	snmptrap_t trap;
	snmptrap_varbind_t *varbind = NULL;
	time_t cur = time(NULL);

	/* Any peers? */
	if (prefs.peer == NULL) {
		return 0;
	}

	/* Init trap struct */
	init_snmptrap_t(trap_oid, &trap);

	/* Setup varbind */
	trap.varbind = malloc(sizeof(snmptrap_varbind_t));

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_ID, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", pid);

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_DATABASE_HOST, sizeof(varbind->var));
	if (args.db_host) {
		strncpy(varbind->val, args.db_host, sizeof(varbind->var));
	} else {
		strncpy(varbind->val, "", sizeof(varbind->var));
	}

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 'u';
	strncpy(varbind->var, OID_DATABASE_PORT, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", args.db_port);

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_DATABASE_SOCKET, sizeof(varbind->var));
	if (args.db_sock) {
		strncpy(varbind->val, args.db_sock, sizeof(varbind->var));
	} else {
		strncpy(varbind->val, "", sizeof(varbind->var));
	}

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_DATABASE_NAME, sizeof(varbind->var));
	strncpy(varbind->val, args.db_name, sizeof(varbind->var));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_DATABASE_USER, sizeof(varbind->var));
	strncpy(varbind->val, args.db_user, sizeof(varbind->var));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 'a';
	strncpy(varbind->var, OID_PROBE_ADDRESS, sizeof(varbind->var));
	inet_ntop(AF_INET, &args.source, varbind->val, sizeof(varbind->val));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_PROBE_NAME, sizeof(varbind->var));
	strncpy(varbind->val, args.name, sizeof(varbind->var));

	varbind->next = NULL;

	/* Send trap */
	ret_val = send_snmptrap(&trap);

	/* Free varbind memory */
   while (trap.varbind) {
      varbind = trap.varbind;
      trap.varbind = varbind->next;
      free(varbind);
   }

	return ret_val;
}

int snmptrap_probe_threshold(const char* trap_oid, int threshold_type, struct probe_t *probe, unsigned int current, unsigned int threshold) {
	int ret_val = 0;
	snmptrap_t trap;
	snmptrap_varbind_t *varbind = NULL;
	time_t cur = time(NULL);

	/* Sanity check type */
	assert(threshold_type >= 0 && threshold_type <= THRESHOLD_TYPE_MAX);

	/* Any peers? */
	if (prefs.peer == NULL) {
		return 0;
	}

	/* Init trap struct */
	init_snmptrap_t(trap_oid, &trap);

	/* Setup varbind */
	trap.varbind = malloc(sizeof(snmptrap_varbind_t));

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_ID, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", pid);

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 'a';
	strncpy(varbind->var, OID_PROBE_ADDRESS, sizeof(varbind->var));
	inet_ntop(AF_INET, &args.source, varbind->val, sizeof(varbind->val));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_PROBE_NAME, sizeof(varbind->var));
	strncpy(varbind->val, args.name, sizeof(varbind->var));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 'a';
	strncpy(varbind->var, OID_PROBE_REMOTE_ADDRESS, sizeof(varbind->var));
	inet_ntop(AF_INET, &(probe->ip), varbind->val, sizeof(varbind->val));

	varbind->next = malloc(sizeof(snmptrap_varbind_t));
	varbind = varbind->next;
	varbind->type = 's';
	strncpy(varbind->var, OID_PROBE_REMOTE_NAME, sizeof(varbind->var));
	strncpy(varbind->val, probe->name, sizeof(varbind->var));

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_PROBE_THRESHOLD_TYPE, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", threshold_type);

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_PROBE_THRESHOLD_TRIGGER, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", threshold);

	varbind = trap.varbind;
	varbind->type = 'u';
	strncpy(varbind->var, OID_PROBE_THRESHOLD_CURRENT, sizeof(varbind->var));
	snprintf(varbind->val, sizeof(varbind->val), "%u", current);

	varbind->next = NULL;

	/* Send trap */
	ret_val = send_snmptrap(&trap);

	/* Free varbind memory */
   while (trap.varbind) {
      varbind = trap.varbind;
      trap.varbind = varbind->next;
      free(varbind);
   }

	return ret_val;
}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim: noet ts=3 sw=3
*/
