// $Id: Frag.h,v 1.7 2002/10/11 02:20:15 leres Exp $
//
// Copyright (c) 1998, 1999, 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 frag_h
#define frag_h

#include "util.h"
#include "IP.h"
#include "Net.h"
#include "Reassem.h"
#include "Timer.h"

class HashKey;
class NetSessions;

class FragReassembler;
class FragTimer;

typedef void (FragReassembler::*frag_timer_func)(double t);

class FragReassembler : public Reassembler {
public:
	FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt,
			uint32 frag_field, HashKey* k, double t);
	~FragReassembler();

	void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt,
				uint32 frag_field);

	void Expire(double t);
	void DeleteTimer();

	const IP_Hdr* ReassembledPkt()	{ return reassembled_pkt; }
	HashKey* Key() const	{ return key; }

protected:
	void BlockInserted(double t, DataBlock* start_block);
	void Overlap(const u_char* b1, const u_char* b2, int n);

	struct ip* proto_hdr;
	IP_Hdr* reassembled_pkt;
	int proto_hdr_len;
	NetSessions* s;
	int frag_size;	// size of fully reassembled fragment
	HashKey* key;

	Timer* expire_timer;
};

class FragTimer : public Timer {
public:
	FragTimer(FragReassembler* arg_f, double arg_t)
		: Timer(arg_t)
			{ f = arg_f; }

	void Dispatch(double t, int is_expire);

protected:
	FragReassembler* f;
};

#endif
