User Manual, Developers Guide and API Documentation

Chain.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <IP/iptables/Chain.hpp>
00029 #include <IP/iptables/filters/FilterInterface.hpp>
00030 #include <IP/iptables/targets/TargetInterface.hpp>
00031 #include <IP/IPHeader.hpp>
00032 
00033 using namespace ip::iptables;
00034 
00035 Chain::Chain(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& _pyco) :
00036     wns::ldk::CommandTypeSpecifier<>(fun),
00037     wns::ldk::HasReceptor<>(),
00038     wns::ldk::HasConnector<>(),
00039     wns::ldk::HasDeliverer<>(),
00040     log(_pyco.get("logger")),
00041     ipHeaderReader(NULL)
00042 {
00043     int numRules = _pyco.len("rules");
00044     for (int i = 0;
00045          i < numRules;
00046          ++i)
00047     {
00048         wns::pyconfig::View rc = _pyco.get("rules", i);
00049 
00050         std::string filtername = rc.get<std::string>("filter.__plugin__");
00051         std::string targetname = rc.get<std::string>("target.__plugin__");
00052         ip::iptables::Rule::RuleTag ruleTag = rc.get<ip::iptables::Rule::RuleTag>("ruleTag");
00053         ip::iptables::Rule rule = Rule(
00054             filters::FilterInterfaceFactory::creator(filtername)->create(rc.get("filter")),
00055             targets::TargetInterfaceFactory::creator(targetname)->create(rc.get("target")),
00056             ruleTag);
00057 
00058         addRule(rule);
00059     }
00060 
00061 }
00062 
00063 Chain::~Chain()
00064 {
00065     while (!rules.empty())
00066     {
00067         Rule rule = *rules.begin();
00068         rules.pop_front();
00069     }
00070 }
00071 
00072 void
00073 Chain::onFUNCreated()
00074 {
00075     ipHeaderReader = getFUN()->getCommandReader("ip.ipHeader");
00076     assure(ipHeaderReader, "No reader for the IP Header available!");
00077 } // onFUNCreated
00078 
00079 bool
00080 Chain::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00081 {
00082     return getConnector()->hasAcceptor(compound);
00083 }
00084 
00085 void
00086 Chain::doSendData(const wns::ldk::CompoundPtr& compound)
00087 {
00088     //debugging stuff:
00089     showRules();
00090     //:debugging stuff
00091 
00092     assure(ipHeaderReader, "No reader for the IP Header available!");
00093     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00094     wns::service::tl::ITCPHeader* tcpHeader = NULL;
00095     wns::service::tl::IUDPHeader* udpHeader = NULL;
00096     wns::ldk::Compound* sdu = dynamic_cast<wns::ldk::Compound*>(compound->getUserData());
00097 
00098     if (sdu != NULL)
00099     {
00100         if (ipHeader->peer.protocol == wns::service::nl::TCP)
00101         {
00102             tcpHeader = getFUN()->getProxy()->
00103                 getCommand<wns::service::tl::ITCPHeader>(sdu->getCommandPool(), "tcp.tcpHeader");
00104         }
00105 
00106         if (ipHeader->peer.protocol == wns::service::nl::UDP)
00107         {
00108             udpHeader = getFUN()->getProxy()->
00109                 getCommand<wns::service::tl::IUDPHeader>(sdu->getCommandPool(), "tcp.tcpHeader");
00110         }
00111     }
00112 
00113     MESSAGE_SINGLE(VERBOSE, log, "Asking for outgoing activation");
00114 
00115     targets::TargetResult acceptPacket = targets::ACCEPT;
00116     if (activateOutgoing(*ipHeader))
00117     {
00118         acceptPacket = activateChain(ipHeader, tcpHeader, udpHeader);
00119     }
00120 
00121     if (acceptPacket == targets::ACCEPT || acceptPacket == targets::CONT)
00122     {
00123         // Forward to lower FU.
00124         getConnector()->getAcceptor(compound)->sendData(compound);
00125     }
00126 }
00127 
00128 void
00129 Chain::doWakeup()
00130 {
00131     getReceptor()->wakeup();
00132 }
00133 
00134 void
00135 Chain::doOnData(const wns::ldk::CompoundPtr& compound)
00136 {
00137     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00138     wns::service::tl::ITCPHeader* tcpHeader = NULL;
00139     wns::service::tl::IUDPHeader* udpHeader = NULL;
00140     wns::ldk::Compound* sdu = dynamic_cast<wns::ldk::Compound*>(compound->getUserData());
00141 
00142     if (sdu != NULL)
00143     {
00144         if (ipHeader->peer.protocol == wns::service::nl::TCP)
00145         {
00146             tcpHeader = getFUN()->getProxy()->
00147                 getCommand<wns::service::tl::ITCPHeader>(sdu->getCommandPool(), "tcp.tcpHeader");
00148         }
00149 
00150         if (ipHeader->peer.protocol == wns::service::nl::UDP)
00151         {
00152             udpHeader = getFUN()->getProxy()->
00153                 getCommand<wns::service::tl::IUDPHeader>(sdu->getCommandPool(), "tcp.tcpHeader");
00154         }
00155     }
00156 
00157     MESSAGE_SINGLE(VERBOSE, log, "Asking for incoming activation");
00158 
00159     targets::TargetResult acceptPacket = targets::ACCEPT;
00160     if (activateIncoming(*ipHeader))
00161     {
00162         acceptPacket = activateChain(ipHeader, tcpHeader, udpHeader);
00163     }
00164 
00165     if (acceptPacket == targets::ACCEPT || acceptPacket == targets::CONT)
00166     {
00167         // Hand compound to upper FU
00168         if(getDeliverer()->size())
00169             getDeliverer()->getAcceptor(compound)->onData(compound);
00170     }
00171 }
00172 
00173 targets::TargetResult
00174 Chain::activateChain(IPCommand* ipHeader, wns::service::tl::ITCPHeader* tcpHeader, wns::service::tl::IUDPHeader* udpHeader)
00175 {
00176     for(RuleContainer::iterator it = rules.begin();
00177         it != rules.end();
00178         ++it)
00179     {
00180             targets::TargetResult r;
00181             if (tcpHeader != NULL && it->getFilter()->fires(ipHeader, tcpHeader))
00182             {
00183                 r = it->getTarget()->mangle(ipHeader, tcpHeader);
00184             }
00185             else if (udpHeader != NULL && it->getFilter()->fires(ipHeader, udpHeader))
00186             {
00187                 r = it->getTarget()->mangle(ipHeader, udpHeader);
00188             }
00189             else
00190             {
00191                 r = it->getTarget()->mangle(ipHeader);
00192             }
00193 
00194             switch(r)
00195             {
00196             case targets::ACCEPT:
00197                 return targets::ACCEPT;
00198                 break;
00199 
00200             case targets::DROP:
00201                 return targets::DROP;
00202                 break;
00203 
00204             case targets::CONT:
00205                 continue;
00206                 break;
00207             default:
00208                 MESSAGE_SINGLE(NORMAL, log, "Unknown Thang!");
00209             };
00210     }
00211     return targets::ACCEPT;
00212 }
00213 
00214 void
00215 Chain::addRule(ip::iptables::Rule rule)
00216 {
00217     rules.insert(rules.end(), rule);
00218 
00219     MESSAGE_BEGIN(NORMAL, log, m, "");
00220     m << "New Rule added with RuleTag " << rule.getRuleTag();
00221     MESSAGE_END();
00222 }
00223 
00224 void
00225 Chain::removeRules(ip::iptables::Rule::RuleTag ruleTag)
00226 {
00227     int numberOfRules = 0;
00228     if(rules.empty())
00229     {
00230         std::cout<<"RuleContainer is empty! There are no Rules to remove with RuleTag "<<ruleTag<<std::endl;
00231     }
00232     else
00233     {
00234         for(RuleContainer::iterator it = rules.begin();
00235             it != rules.end();)
00236         {
00237             if((it->getRuleTag()) == ruleTag)
00238             {
00239                 numberOfRules++;
00240                 it = rules.erase(it);
00241                 it = rules.begin();
00242             }
00243             else
00244             {
00245                 ++it;
00246             }
00247         }
00248     MESSAGE_BEGIN(NORMAL, log, m, "");
00249     m <<"Erased "<< numberOfRules <<" Rules for RuleTag "<<ruleTag;
00250     MESSAGE_END();
00251     }
00252 }
00253 
00254 bool
00255 Chain::hasRules(ip::iptables::Rule::RuleTag ruleTag)
00256 {
00257     int numberOfRules = 0;
00258     if(rules.empty())
00259     {
00260         return false;
00261     }
00262 
00263     for(RuleContainer::iterator it = rules.begin();
00264         it != rules.end();
00265         ++it)
00266     {
00267         if((it->getRuleTag()) == ruleTag)
00268         {
00269             numberOfRules++;
00270         }
00271         else
00272         {
00273         }
00274     }
00275     if(numberOfRules>0)
00276         {
00277             return true;
00278         }
00279     else
00280         {
00281             return false;
00282         }
00283 }
00284 
00285 
00286 // use returnTarget with care!
00287 // just for RuleTags with just one rule!
00288 ip::iptables::Rule
00289 Chain::getRule(ip::iptables::Rule::RuleTag ruleTag)
00290 {
00291     for(RuleContainer::iterator it = rules.begin();
00292         it != rules.end();
00293         ++it)
00294     {
00295         if((it->getRuleTag()) == ruleTag)
00296         {
00297             return *it;
00298         }
00299     }
00300 }
00301 
00302 
00303 void
00304 Chain::showRules()
00305 {
00306     for(RuleContainer::iterator it = rules.begin();
00307         it != rules.end();
00308         ++it)
00309     {
00310     MESSAGE_BEGIN(NORMAL, log, m, "");
00311     m <<"Existing Rule for RuleTag: "<< it->getRuleTag();
00312     MESSAGE_END();
00313     }
00314 }

Generated on Tue May 22 03:32:13 2012 for openWNS by  doxygen 1.5.5