// $Id: PktSrc.h,v 1.7 2003/09/04 06:04:46 vern Exp $
//
// Copyright (c) 1999, 2000, 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 pktsrc_h
#define pktsrc_h

#include "Dict.h"

extern "C" {
#include <pcap.h>
}

declare(PDict,bpf_program);

class PktSrc {
public:
	~PktSrc();

	int NotOpen() const		{ return pd == 0; }
	const char* ErrorMsg() const	{ return errbuf; }
	void ClearErrorMsg()		{ *errbuf ='\0'; }

	pcap_dumper_t* OpenDumper(const char* writefile);

	// Returns nil if there are no more packets.  Will continue to
	// return the same packet until ConsumePacket() is called; this
	// allows for "peeking" at the next packet but deferring processing
	// until later if needed.
	const u_char* NextPacket(struct pcap_pkthdr*& hdr);

	// Same, but just for the timestamp of the next packet.
	// Returns < 0 if no more packets.
	double NextTimestamp();

	int HdrSize() const		{ return hdr_size; }

	void ConsumePacket()	{ data = 0; }

	int IsLive() const		{ return interface != 0; }

	pcap_t* PcapHandle() const	{ return pd; }

	const char* ReadFile() const	{ return readfile; }
	const char* Interface() const	{ return interface; }

	// Precompiles a filter and associates the given index with it.
	// Returns true on success, 0 if a problem occurred.
	int PrecompileFilter(int index, const char* filter);

	// Activates the filter with the given index.
	// Returns true on success, 0 if a problem occurred.
	int SetFilter(int index);

protected:
	PktSrc();

	void SetHdrSize();

	void Close();

	struct pcap_pkthdr hdr;
	const u_char* data;	// contents of current packet
	int hdr_size;

	char* interface;	// nil if not reading from an interface
	char* readfile;		// nil if not reading from a file

	pcap_t* pd;
	uint32 netmask;
	char errbuf[PCAP_ERRBUF_SIZE + 256];

	PDict(bpf_program) filters; // precompiled filters
};

class PktInterfaceSrc : public PktSrc {
public:
	PktInterfaceSrc(const char* interface, const char* filter);
};

class PktFileSrc : public PktSrc {
public:
	PktFileSrc(const char* readfile, const char* filter);
};

#endif
