support for tos matching for PF

This commit is contained in:
Vadim Kurland
2008-07-06 02:02:26 +00:00
parent 7304483a30
commit ce2508e93a
5 changed files with 1271 additions and 868 deletions
+3
View File
@@ -1,5 +1,8 @@
2008-07-05 Vadim Kurland <vadim@vk.crocodile.org> 2008-07-05 Vadim Kurland <vadim@vk.crocodile.org>
* PolicyCompiler_pf_writers.cpp (PrintRule::_printDstService):
Support for tos matching in compiler for pf.
* PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): Support for * PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): Support for
TOS and DSCP matching in compiler for iptables. TOS and DSCP matching in compiler for iptables.
+81 -47
View File
@@ -34,6 +34,7 @@
#include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMPService.h"
#include "fwbuilder/TCPService.h" #include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h" #include "fwbuilder/UDPService.h"
#include "fwbuilder/TagService.h"
#include "fwbuilder/Policy.h" #include "fwbuilder/Policy.h"
#include "fwbuilder/Interface.h" #include "fwbuilder/Interface.h"
#include "fwbuilder/Firewall.h" #include "fwbuilder/Firewall.h"
@@ -875,53 +876,6 @@ bool PolicyCompiler_pf::splitIfInterfaceInRE::processNext()
return true; return true;
} }
bool PolicyCompiler_pf::separateSrcPort::processNext()
{
PolicyRule *rule=getNext(); if (rule==NULL) return false;
RuleElementSrv *rel= rule->getSrv();
if (rel->size()==1) {
tmp_queue.push_back(rule);
return true;
}
list<Service*> services;
for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) {
FWObject *o= *i;
if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
Service *s=Service::cast(o);
assert(s!=NULL);
if ( TCPService::isA(s) || UDPService::isA(s) ) {
int srs=TCPUDPService::cast(s)->getSrcRangeStart();
int sre=TCPUDPService::cast(s)->getSrcRangeEnd();
compiler->normalizePortRange(srs,sre);
if (srs!=0 || sre!=0) {
PolicyRule *r= PolicyRule::cast(
compiler->dbcopy->create(PolicyRule::TYPENAME) );
compiler->temp_ruleset->add(r);
r->duplicate(rule);
RuleElementSrv *nsrv=r->getSrv();
nsrv->clearChildren();
nsrv->addRef( s );
tmp_queue.push_back(r);
services.push_back(s);
}
}
}
for (list<Service*>::iterator i=services.begin(); i!=services.end(); i++)
rel->removeRef( (*i) );
if (!rel->isAny())
tmp_queue.push_back(rule);
return true;
}
bool PolicyCompiler_pf::createTables::processNext() bool PolicyCompiler_pf::createTables::processNext()
{ {
PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler); PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler);
@@ -958,6 +912,83 @@ bool PolicyCompiler_pf::printScrubRule::processNext()
return true; return true;
} }
PolicyCompiler_pf::separateServiceObject::separateServiceObject(
const string &name) : PolicyRuleProcessor(name)
{
}
bool PolicyCompiler_pf::separateServiceObject::processNext()
{
PolicyRule *rule=getNext(); if (rule==NULL) return false;
RuleElementSrv *rel= rule->getSrv();
if (rel->size()==1) {
tmp_queue.push_back(rule);
return true;
}
list<Service*> services;
for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++)
{
FWObject *o= *i;
if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
Service *s=Service::cast(o);
assert(s!=NULL);
if (condition(s))
{
PolicyRule *r= PolicyRule::cast(
compiler->dbcopy->create(PolicyRule::TYPENAME) );
compiler->temp_ruleset->add(r);
r->duplicate(rule);
RuleElementSrv *nsrv=r->getSrv();
nsrv->clearChildren();
nsrv->addRef( s );
tmp_queue.push_back(r);
services.push_back(s);
}
}
for (list<Service*>::iterator i=services.begin(); i!=services.end(); i++)
rel->removeRef( (*i) );
if (!rel->isAny())
tmp_queue.push_back(rule);
return true;
}
bool PolicyCompiler_pf::separateSrcPort::condition(const Service *srv)
{
if ( TCPService::isA(srv) || UDPService::isA(srv) )
{
int srs = TCPUDPService::constcast(srv)->getSrcRangeStart();
int sre = TCPUDPService::constcast(srv)->getSrcRangeEnd();
compiler->normalizePortRange(srs,sre);
return (srs!=0 || sre!=0);
}
return false;
}
bool PolicyCompiler_pf::separateTagged::condition(const Service *srv)
{
return ( TagService::isA(srv));
}
bool PolicyCompiler_pf::separateTOS::condition(const Service *srv)
{
const IPService *ip = IPService::constcast(srv);
return (ip && !ip->getTOSCode().empty());
}
void PolicyCompiler_pf::compile() void PolicyCompiler_pf::compile()
{ {
cout << " Compiling " << fw->getName(); cout << " Compiling " << fw->getName();
@@ -1083,6 +1114,9 @@ void PolicyCompiler_pf::compile()
add( new splitServices("split rules with different protocols")); add( new splitServices("split rules with different protocols"));
add( new separateTCPWithFlags("separate TCP services with flags" )); add( new separateTCPWithFlags("separate TCP services with flags" ));
add( new separateSrcPort("split on TCP and UDP with source ports")); add( new separateSrcPort("split on TCP and UDP with source ports"));
add( new separateTagged("split on TagService"));
add( new separateTOS("split on IPService with TOS"));
add( new verifyCustomServices( add( new verifyCustomServices(
"verify custom services for this platform")); "verify custom services for this platform"));
// add( new ProcessScrubOption( "process 'scrub' option" )); // add( new ProcessScrubOption( "process 'scrub' option" ));
+44 -1
View File
@@ -354,12 +354,55 @@ namespace fwcompiler {
eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {}
}; };
/**
* separate service object that satisfies condition
* implemented in the virtual method "condition" so we have
* exactly one such object per rule.
*/
class separateServiceObject : public PolicyRuleProcessor
{
protected:
virtual bool condition(const libfwbuilder::Service *srv) =0;
public:
separateServiceObject(const std::string &name);
virtual bool processNext();
};
/** /**
* separate TCP/UDP services that specify source port (can * separate TCP/UDP services that specify source port (can
* not be used in combination with destination port with * not be used in combination with destination port with
* multiport) * multiport)
*/ */
DECLARE_POLICY_RULE_PROCESSOR(separateSrcPort); class separateSrcPort : public separateServiceObject
{
protected:
virtual bool condition(const libfwbuilder::Service *srv);
public:
separateSrcPort(const std::string &name) : separateServiceObject(name) {}
};
/**
* separate Tag services so we have exactly one per rule.
*/
class separateTagged : public separateServiceObject
{
protected:
virtual bool condition(const libfwbuilder::Service *srv);
public:
separateTagged(const std::string &name) : separateServiceObject(name) {}
};
/**
* separate IPService objects with tos attrubute so we have
* exactly one per rule.
*/
class separateTOS : public separateServiceObject
{
protected:
virtual bool condition(const libfwbuilder::Service *srv);
public:
separateTOS(const std::string &name) : separateServiceObject(name) {}
};
class printScrubRule : public PolicyRuleProcessor class printScrubRule : public PolicyRuleProcessor
+17 -2
View File
@@ -30,6 +30,7 @@
#include "fwbuilder/RuleElement.h" #include "fwbuilder/RuleElement.h"
#include "fwbuilder/IPService.h" #include "fwbuilder/IPService.h"
#include "fwbuilder/ICMPService.h" #include "fwbuilder/ICMPService.h"
#include "fwbuilder/ICMP6Service.h"
#include "fwbuilder/TCPService.h" #include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h" #include "fwbuilder/UDPService.h"
#include "fwbuilder/CustomService.h" #include "fwbuilder/CustomService.h"
@@ -542,6 +543,9 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
{ {
if (ICMPService::isA(srv)) if (ICMPService::isA(srv))
compiler->output << "icmp-type " << str << " "; compiler->output << "icmp-type " << str << " ";
else
if (ICMP6Service::isA(srv))
compiler->output << "icmp6-type " << str << " ";
else else
compiler->output << str << " "; compiler->output << str << " ";
} }
@@ -551,9 +555,17 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
str=_printTCPFlags(TCPService::cast(srv)); str=_printTCPFlags(TCPService::cast(srv));
if (!str.empty()) compiler->output << "flags " << str << " "; if (!str.empty()) compiler->output << "flags " << str << " ";
} }
if (IPService::isA(srv) && if (IPService::isA(srv))
(srv->getBool("fragm") || srv->getBool("short_fragm")) ) {
if (srv->getBool("fragm") || srv->getBool("short_fragm"))
compiler->output << " fragment "; compiler->output << " fragment ";
const IPService *ip = IPService::constcast(srv);
string tos = ip->getTOSCode();
string dscp = ip->getDSCPCode();
if (!tos.empty()) compiler->output << " tos " << tos;
if (!dscp.empty())
compiler->abort("PF does not support DSCP matching");
}
} else } else
{ {
string str; string str;
@@ -577,6 +589,9 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
compiler->output << "icmp-type { " << str << " } "; compiler->output << "icmp-type { " << str << " } ";
else else
{ {
if (ICMP6Service::isA(srv))
compiler->output << "icmp6-type { " << str << " } ";
else
compiler->output << str << " " << endl; compiler->output << str << " " << endl;
} }
} }
File diff suppressed because it is too large Load Diff