/*
** SellaNMS
** $Id: bgp.cxx,v 1.8 2006/01/24 07:08:10 sella Exp $
** Copyright (c) 2001-2005 Digital Genesis Software, LLC. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
*/

static const char rcsid[] = "$Id: bgp.cxx,v 1.8 2006/01/24 07:08:10 sella Exp $";

#include "bgp.h"
#include "common/util.h"
#include "common/netblock.h"
#include "storage/storagedata.h"
#include "policy_framework/policy_framework.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stl/list>
#include <stl/queue>
#include <stl/list>
#include <stl/string>

extern ConfigNode* config;

extern bool interrupt;

BGP::BGP():timestamp(0) {
}

BGP::~BGP() {
}

RESULT BGP::execute() {
	Neighbor *t_neighbor = NULL;

	pthread_t thread_id;
	pthread_t listen_id;

	/* Create the TCP listener thread */
	if (result == SUCCESS) {
		if ((err = pthread_create(&listen_id, NULL, (void* (*)(void*))BGP::listen, this)) == 0) {
			TRACE(TRACE_THREAD, "bgp listen thread created.");
		}
	}
	for (Vector<string>::iterator nit = neighborVector.begin(); nit != neighborVector.end(); ++nit) {
		t_neighbor = new Neighbor();

		t_neighbor.setBGP(this);
		t_neighbor.setPeer(*nit);
		t_neighbor.setConfigured(true);

		if ((err = pthread_create(&thread_id, NULL, (void* (*)(void*))BGP::neighbor, t_neighbor)) == 0) {
			TRACE(TRACE_THREAD, "bgp listen thread created.");
			neighborhood[thread_id] = t_neighbor;
		} else {
			delete t_neighbor;
			interrupt = true;
		}
	}
	while (!interrupt) {
		//monitor threads and stuff.
	}

	return SUCCESS;
}

RESULT BGP::readConfig() {
	RESULT result = SUCCESS;
	string str;
	vector<string> v;
	vector<string>::iterator v_it;
	ConfigNode node;
	struct in_addr ip;
	unsigned long tmp = 0;

	if (!config->assignNode(getConfigPath(), node)) {
		LMSG("No '%s' section found within the config file.", getConfigPath());

		return FAILURE;
	}

	node.assignValues("allow", allowVector);
	node.assignValues("neighbor", neighborVector);

#if 0
	/* How often to start a polling inteval. */
	node.assignValue("interval", interval, 30, 1);

	/* Clear any existing policies. */
	inputPolicy.clear();
	outputPolicy.clear();

	/* Add and compile output policy. */
	if (node.assignValues("policy output", v)) {
		if (outputPolicy.addPolicies(config, v) == FAILURE) {
			LMSG("NOTICE: Failed to add/compile output policies.");

			return FAILURE;
		}
	}

	/* Verify we have required policies. */
	if (outputPolicy.empty()) {
		LMSG("NOTICE: An output policy is required for this module.");

		return FAILURE;
	}
#endif

	/* Configure Storage */
	if (storage.setConfig(*config) != SUCCESS) {
		result = FAILURE;
	}

	printConfig();

	return result;
}

void BGP::printConfig() {
	string str;
	vector<string> v;
	vector<string>::iterator v_it;

	if (!TRACE_ISSET(TRACE_CONFIG)) {
		return;
	}

#if 0
	TRACE(TRACE_CONFIG, "interval: %lu (sec)", this->interval);

	if (config->assignValues("monitor bgp policy input", v)) {
		str.erase();
		for (v_it = v.begin(); v_it != v.end(); ++v_it) {
			str.append(*v_it + " ");
		}
		TRACE(TRACE_CONFIG, "policy input: %s", str.c_str());
	} else {
		TRACE(TRACE_CONFIG, "policy input: none");
	}

	if (config->assignValues("monitor bgp policy output", v)) {
		str.erase();
		for (v_it = v.begin(); v_it != v.end(); ++v_it) {
			str.append(*v_it + " ");
		}
		TRACE(TRACE_CONFIG, "policy output: %s", str.c_str());
	} else {
		TRACE(TRACE_CONFIG, "policy output: none");
	}
#endif

	return;
}

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