#ifndef CLICK_ADDRESSTRANSLATOR_HH
#define CLICK_ADDRESSTRANSLATOR_HH
#include <click/ip6address.hh>
#include <click/ipaddress.hh>
#include <click/vector.hh>
#include <click/element.hh>
#include <click/bighashmap.hh>
#include <click/ip6flowid.hh>
CLICK_DECLS
//#include <time.h>
/*
* =c
* AddressTranslator(number_of_static_Mapping,
* StaticPortMapping,
* StaticMapping1,...
* StaticMappingm,
* DynamicMapping,
* DynamicPortMapping,
* AddressAllocationDirection,
* Mapped_IP6Address Port_start Port_end)
*
*
* =s ip6
* translates IPv6/ICMPv6, TCP, and UDP packets' addresses and ports
*
* =d
* Translates IPv6/ICMPv6, TCP, and UDP packets by changing their source address,
* source port, destination address, and/or destination port.
*
* Has one or more inputs and one or more outputs. Input packets must have
* their IP6 header annotations set. Output packets are valid IP6 packets; for
* instance, translated packets have their checksums updated.
*
* AddressTranslator maintains a table of mappings for static address and port
* mapping and dynamic address mapping. It contains fields such
* as _iai, _ipi, _mai, _mpi, _ea, _ep, _t, _binding, _state, _static.
* For static mapping, the addresses (and ports) are mapped when the AddressTranslator
* is initiated. For dynamic mapping, mappings are created on the fly as new flows
* arrives from the direction that can be allocate new mapped address/port.
*
* For dynamic address and port configuration, the AddressTranslator maintains two tables
* _in_map and _out_map to map flow ID for outward packet and inward packet respectively.
*
* If the AddressTranslator is configured as static mapping or dynamic address mapping,
* when a packet arrives, the AddressTranslator will first check entries in the
* address-mapping * table, see if there exists an entry for the flow that the packet
* belongs to. If there's such an entry,then the packet's source address (and port)
* will be replaced with the mapped address (and port) of the entry for the outward packet
* and the packet's destination address (and port) will be replaced with the inner host's
* address (and port) for the inward packet.
*
* If there is no such an entry and it is configured for dynamic address mapping, then the
* translator will create a binding for the new mapping if the flow comes from the right direction (the direction that allocates a new mapping is allowed). Otherwise, the packet is discarded.
*
* If the AddressTranslator is configured for dynamic address and port mapping,the
* AddressTranslator will first check entries in the _in_map or _out_map table, depending on
* packet's direction. It checks if the table has an entry whose flowID is the same as the packet.
* If there is, use the mapped flowID of that entry for the packet. Otherwise, it will try to
* find an unsed port and create a mapped flowID for the flow and insert the entry, if the packet
* comes from the right direction.
*
* =a ProtocolTranslator64, ProtocolTranslator46 */
class AddressTranslator : public Element {
public:
class Mapping;
AddressTranslator();
~AddressTranslator();
const char *class_name() const { return "AddressTranslator"; }
const char *port_count() const { return "2/2"; }
const char *processing() const { return AGNOSTIC; }
int configure(Vector<String> &, ErrorHandler *);
void push(int port, Packet *p);
void add_map(IP6Address &mai, bool binding);
void add_map(IP6Address &iai, unsigned short ipi, IP6Address &mai, unsigned short mpi, IP6Address &ea, unsigned short ep, bool binding);
void handle_outward(Packet *p);
void handle_inward(Packet *p);
bool lookup(IP6Address &, unsigned short &, IP6Address &, unsigned short &, IP6Address &, unsigned short &, bool);
void cleanup(CleanupStage);
protected:
struct EntryMap {
IP6Address _iai;
unsigned short _ipi;
IP6Address _mai;
unsigned short _mpi;
IP6Address _ea;
unsigned short _ep;
//long unsigned int _t;
//time_t _t; //the last time that the packet passed the address translator
//later: the time when FIN received from both direction for TCP
//the time that the UDP packet has been sent for this session.
//unsigned char _state;
bool _binding;
bool _static;
};
Vector<EntryMap> _v;
int _number_of_smap; // number of static-mapping entry
bool _static_portmapping;
bool _dynamic_mapping;
bool _dynamic_portmapping;
bool _dynamic_mapping_allocation_direction;
//the index of the following bool array corresponds to the colums of
//_iai, _ipi, _mai, _mpi, _ea, _ep
bool _static_mapping[6];
//using new approach
typedef HashMap<IP6FlowID, Mapping *> Map6;
void clean_map(Map6 &, bool);
unsigned short find_mport( );
void mapping_freed(Mapping *, bool);
Map6 _in_map;
Map6 _out_map;
IP6Address _maddr;
unsigned short _mportl, _mporth;
Mapping *_rover;
Mapping *_rover2;
int _nmappings;
int _nmappings2;
};
class AddressTranslator::Mapping {
public:
Mapping();
void initialize(const IP6FlowID & new_flow) { _mapto = new_flow; }
const IP6FlowID &flow_id() const { return _mapto; }
unsigned short sport() const { return _mapto.sport(); }
unsigned short dport() const { return _mapto.dport(); }
//String s() const { return " "; }
Mapping * get_next() { return _next; }
Mapping * get_prev() { return _prev; }
void set_next(Mapping * next) { _next = next; }
void set_prev(Mapping * prev) { _prev = prev; }
Mapping *free_next() const { return _free_next; }
void set_free_next(Mapping *m) {_free_next = m;}
protected:
//long unsigned int _t;
IP6FlowID _mapto;
Mapping *_prev;
Mapping *_next;
Mapping *_free_next;
friend class AddressTranslator;
};
CLICK_ENDDECLS
#endif
syntax highlighted by Code2HTML, v. 0.9.1