// $Id: DNS_Mgr.h,v 1.13 2003/08/31 00:38:11 vern Exp $
//
// Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef dnsmgr_h
#define dnsmgr_h

#include "util.h"
#include "BroList.h"
#include "Dict.h"
#include "EventHandler.h"

class ListVal;
class Val;
class Func;
class EventHandler;
class RecordType;

struct nb_dns_info;
struct nb_dns_result;

declare(PDict,ListVal);

class DNS_Mapping;
declare(PDict,DNS_Mapping);

enum DNS_MgrMode {
	DNS_PRIME,	// used to prime the cache
	DNS_FORCE,	// internal error if cache miss
	DNS_DEFAULT,	// lookup names as they're requested
	DNS_FAKE,	// don't look up names, just return dummy results
};

// Number of seconds we'll wait for a reply.
#define DNS_TIMEOUT 20

class DNS_Mgr {
public:
	DNS_Mgr(DNS_MgrMode mode);
	~DNS_Mgr();

	void Init();

	// Looks up the address or addresses of the given host, and returns
	// a ListVal of TYPE_ADDR.
	ListVal* LookupHost(const char* host);

	Val* LookupAddr(uint32 addr);

	void Verify();
	void Resolve();
	int Save();

protected:
	void Event(EventHandlerPtr e, DNS_Mapping* dm, ListVal* l1 = 0, ListVal* l2 = 0);
	void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm);

	Val* BuildMappingVal(DNS_Mapping* dm);

	void AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r);
	void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm);
	ListVal* AddrListDelta(ListVal* al1, ListVal* al2);
	void DumpAddrList(FILE* f, ListVal* al);

	void LoadCache(FILE* f);
	void Save(FILE* f, PDict(DNS_Mapping)& m);

	DNS_MgrMode mode;

	PDict(ListVal) services;

	PDict(DNS_Mapping) host_mappings;
	PDict(DNS_Mapping) addr_mappings;

	DNS_mgr_request_list requests;

	nb_dns_info* nb_dns;
	char* cache_name;

	int did_init;

	// DNS-related events.
	EventHandlerPtr dns_mapping_valid;
	EventHandlerPtr dns_mapping_unverified;
	EventHandlerPtr dns_mapping_new_name;
	EventHandlerPtr dns_mapping_lost_name;
	EventHandlerPtr dns_mapping_name_changed;
	EventHandlerPtr dns_mapping_altered;

	RecordType* dm_rec;

	int dns_fake_count;	// used to generate unique fake replies
};

extern DNS_Mgr* dns_mgr;

#endif
