📄 addresstranslator.cc
字号:
/* * addresstranslator{cc,hh} -- element that translates an IPv6 packet by * replacing with the src/dst IPv6 address and/or port by mapped IPv6address * and port. * * Peilei Fan * * Copyright (c) 1999-2001 Massachusetts Institute of Technology. * * This software is being provided by the copyright holders under the GNU * General Public License, either version 2 or, at your discretion, any later * version. For more information, see the `COPYRIGHT' file in the source * distribution. */#include <click/config.h>#include "addresstranslator.hh"#include <click/confparse.hh>#include <click/error.hh>#include <clicknet/ip.h>#include <clicknet/ip6.h>#include <clicknet/icmp.h>#include <clicknet/icmp6.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>CLICK_DECLSAddressTranslator::AddressTranslator() : _dynamic_mapping_allocation_direction(0), _in_map(0), _out_map(0), _rover(0), _rover2(0), _nmappings(0){ // input 0: IPv6 arriving outward packets // input 1: IPv6 arriving inward packets // output 0: IPv6 outgoing outward packets with mapped addresses and port // output 1: IPv6 outgoing inward packets with mapped address and port}AddressTranslator::~AddressTranslator(){}AddressTranslator::Mapping::Mapping() : _prev(0), _next(0), _free_next(0){}voidAddressTranslator::cleanup(CleanupStage){ if (_dynamic_mapping_allocation_direction==0) { clean_map(_in_map, 1); clean_map(_out_map, 0); } else { clean_map(_in_map, 0); clean_map(_out_map, 1); }}voidAddressTranslator::mapping_freed(Mapping *m, bool major_map){ if (major_map) { if (_rover == m) { _rover = m->get_next(); if (_rover == m) _rover = 0; } _nmappings--; if (_nmappings) { Mapping * m_prev = m->free_next(); m_prev->set_next(m->get_next()); } } else { if(_rover2 == m) { _rover2 = m->get_next(); if (_rover2 == m) _rover2 = 0; } _nmappings2--; if (_nmappings2) { Mapping * m_prev = m->free_next(); m_prev->set_next(m->get_next()); } }}voidAddressTranslator::clean_map(Map6 &table, bool major_map){ Mapping *to_free=0; for (Map6::iterator iter = table.begin(); iter.live(); iter++) { Mapping *m = iter.value(); m->set_free_next(to_free); to_free = m; } while (to_free) { Mapping *next = to_free->free_next(); mapping_freed(to_free, major_map); delete to_free; to_free = next; } table.clear();}unsigned shortAddressTranslator::find_mport( ){ if (_mportl == _mporth || !_rover) return _mportl; Mapping * r = _rover; Mapping * r2 = _rover2; unsigned short this_mport = r->sport(); //click_chatter("in find_mport(), this_mport is %x", this_mport); do { Mapping *next = r->get_next(); Mapping *next2 = r2->get_next(); unsigned short next_mport = next->sport(); if (next_mport > this_mport +1) { goto found; } else if (next_mport <= this_mport) { if (this_mport < _mporth) { goto found; } else if (next_mport > _mportl) { this_mport = _mportl -1; goto found; } } r = next; r2=next2; this_mport = next_mport; } while (r!=_rover); return 0; found: _rover = r; _rover2 = r2; return this_mport+1;}//add an entry to the mapping table for dynamic mappingvoidAddressTranslator::add_map(IP6Address &mai, bool binding){ struct EntryMap e; if (_dynamic_mapping_allocation_direction ==0) //outward address allocation { e._mai = mai; } else //inward address allocation { e._iai = mai; } e._binding = binding; e._static = false; _v.push_back(e);}//add an entry to the mapping table for static address (and port) mappingvoidAddressTranslator::add_map(IP6Address &iai, unsigned short ipi, IP6Address &mai, unsigned short mpi, IP6Address &ea, unsigned short ep, bool binding){ struct EntryMap e; if (_static_mapping[0]) e._iai = iai; if (_static_mapping[1]) e._ipi = ipi; if (_static_mapping[2]) e._mai = mai; if (_static_mapping[3]) e._mpi = mpi; if (_static_mapping[4]) e._ea = ea; if (_static_mapping[5]) e._ep = ep; e._binding = binding; e._static = true; _v.push_back(e);}intAddressTranslator::configure(Vector<String> &conf, ErrorHandler *errh){ _v.clear(); int before = errh->nerrors(); int s = 0; IP6Address ia, ma, ea; int ip, mp, ep; //get the static mapping entries for the mapping table if (!cp_integer(conf[0], &_number_of_smap)) { errh->error("argument %d should be : integer", 0); return (before ==errh->nerrors() ? 0: -1); } if (_number_of_smap==0) s = 1; else { s = _number_of_smap+2; if (!cp_bool(conf[1], &_static_portmapping)) errh->error("argument %d should be : bool", 2); _static_mapping[0] = 1; _static_mapping[1] = 0; _static_mapping[2] = 1; _static_mapping[3] = 0; _static_mapping[4] = 0; _static_mapping[5] = 0; if (_static_portmapping) { _static_mapping[1] = 1; _static_mapping[3] = 1; } for (int i = 0; i<_number_of_smap; i++) { Vector<String> words0; cp_spacevec(conf[2+i], words0); int j = 0; if (_static_mapping[0] ==1) cp_ip6_address(words0[j],(unsigned char *)&ia); if (_static_mapping[1] ==1) cp_integer(words0[++j], &ip); if (_static_mapping[2] ==1) cp_ip6_address(words0[++j],(unsigned char *)&ma); if (_static_mapping[3] ==1) cp_integer(words0[++j], &mp); add_map(ia, ip, ma, mp, ea, ep, 1); } } //get the dynamic mapping entries for the mapping table if (!cp_bool(conf[s], &_dynamic_mapping)) errh->error("argument %d should be : bool", s); if (!_dynamic_mapping) return (before ==errh->nerrors() ? 0: -1); if (!cp_bool(conf[s+1], &_dynamic_portmapping)) errh->error("argument %d should be : bool", s+1); if (!cp_bool(conf[s+2], &_dynamic_mapping_allocation_direction)) errh->error("argument %d should be : bool", s+2); //get the rest of the arguments for dynamic mapping // get the argument for dynamic address mapping: // Mapped_Ip6Address1, Mapped_IP6Address2... if (!_dynamic_portmapping) { IP6Address ipa6; for (int i =3; i<(conf.size()-s); i++) { if (cp_ip6_address(conf[s+i], (unsigned char *)&ipa6)) add_map(ipa6, 0); else errh->error("argument %d should be : <IP6Address>", i); } return (before ==errh->nerrors() ? 0: -1); } // get the argument for dynamic add & port mapping: // Mapped_IP6Address port_start# port_end# int i = 3; Vector<String> words1; IP6Address ipa6; int port_start, port_end; cp_spacevec(conf[s+i], words1); if (cp_ip6_address(words1[0], (unsigned char *)&ipa6) && cp_integer(words1[1], &port_start) && cp_integer(words1[2], &port_end)) { _maddr = ipa6; _mportl = port_start; _mporth = port_end; } else errh->error("argument %d should be : <IP6Address> <unsigned char> <unsigned char>", i); //click_chatter("configuration for AT is successful"); return (before ==errh->nerrors() ? 0: -1);}boolAddressTranslator::lookup(IP6Address &iai, unsigned short &ipi, IP6Address &mai, unsigned short &mpi, IP6Address &ea, unsigned short &ep, bool lookup_direction){ if (( _number_of_smap >0 ) || (!_dynamic_portmapping)) { //find the mapped entry in the table for (int i=0; i<_v.size(); i++) { bool match = true; if (_v[i]._static) //this is a static mapping entry { if (_static_mapping[0] && (lookup_direction ==_dynamic_mapping_allocation_direction)) match = match && (_v[i]._iai == iai); if (_static_mapping[1] && (lookup_direction ==_dynamic_mapping_allocation_direction)) match = match && (_v[i]._ipi == ipi); if (_static_mapping[0] && (lookup_direction != _dynamic_mapping_allocation_direction)) match = match && (_v[i]._mai == mai); if (_static_mapping[1] && (lookup_direction != _dynamic_mapping_allocation_direction)) match = match && (_v[i]._mpi == mpi); if (match) { if (_static_mapping[2] && (lookup_direction == _dynamic_mapping_allocation_direction)) mai = _v[i]._mai; else if (_static_mapping[2] && (lookup_direction != _dynamic_mapping_allocation_direction)) iai = _v[i]._iai; else if (lookup_direction == _dynamic_mapping_allocation_direction) mai = iai; else if (lookup_direction != _dynamic_mapping_allocation_direction) iai = _v[i]._iai; if (_static_mapping[3]) mpi = _v[i]._mpi; else if (lookup_direction == _dynamic_mapping_allocation_direction) mpi = ipi; else if (lookup_direction !=_dynamic_mapping_allocation_direction) ipi = mpi; return (true); } } else if (_v[i]._binding) //this is a dynamic bindign entry { if (lookup_direction ==0) match = (_v[i]._iai == iai); //outward, check if the inner address matches else match = (_v[i]._mai == mai); //inward, check if the map address matches if (match) { if (lookup_direction==0) //outward packet { mai = _v[i]._mai; mpi = ipi; } else //inward packet { iai = _v[i]._iai; ipi = mpi; } return (true); } } } //no match found if (!_dynamic_mapping) return false; if (_dynamic_mapping_allocation_direction != lookup_direction) return false; if (!_dynamic_portmapping) // dynamic address mapping only, try to allocate an address { for (int i=0; i<_v.size(); i++) { if ((_v[i]._binding == false ) && ((!_v[i]._static))) { if (lookup_direction == 0) //outward packet { _v[i]._iai = iai; mai = _v[i]._mai;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -