1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-23 11:47:24 +01:00

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

View File

@ -1,5 +1,8 @@
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
TOS and DSCP matching in compiler for iptables.

View File

@ -34,6 +34,7 @@
#include "fwbuilder/ICMPService.h"
#include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h"
#include "fwbuilder/TagService.h"
#include "fwbuilder/Policy.h"
#include "fwbuilder/Interface.h"
#include "fwbuilder/Firewall.h"
@ -875,53 +876,6 @@ bool PolicyCompiler_pf::splitIfInterfaceInRE::processNext()
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()
{
PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler);
@ -958,6 +912,83 @@ bool PolicyCompiler_pf::printScrubRule::processNext()
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()
{
cout << " Compiling " << fw->getName();
@ -1066,10 +1097,10 @@ void PolicyCompiler_pf::compile()
add( new InterfacePolicyRules(
"process interface policy rules and store interface ids") );
add( new splitIfFirewallInSrc( "split rule if firewall is in Src" ));
add( new splitIfFirewallInDst( "split rule if firewall is in Dst" ));
add( new fillDirection( "determine directions" ));
add( new SplitDirection( "split rules with direction 'both'" ));
add( new splitIfFirewallInSrc("split rule if firewall is in Src" ));
add( new splitIfFirewallInDst("split rule if firewall is in Dst" ));
add( new fillDirection("determine directions" ));
add( new SplitDirection("split rules with direction 'both'" ));
add( new addLoopbackForRedirect(
"add loopback to rules that permit redirected services" ) );
add( new ExpandMultipleAddresses(
@ -1077,12 +1108,15 @@ void PolicyCompiler_pf::compile()
add( new dropRuleWithEmptyRE("drop rules with empty rule elements"));
add( new checkForDynamicInterfacesOfOtherObjects(
"check for dynamic interfaces of other hosts and firewalls" ));
add( new MACFiltering( "verify for MAC address filtering" ));
add( new checkForUnnumbered( "check for unnumbered interfaces" ));
add( new addressRanges( "expand address range objects" ));
add( new splitServices( "split rules with different protocols"));
add( new MACFiltering("verify for MAC address filtering" ));
add( new checkForUnnumbered("check for unnumbered interfaces" ));
add( new addressRanges("expand address range objects" ));
add( new splitServices("split rules with different protocols"));
add( new separateTCPWithFlags("separate TCP services with flags" ));
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(
"verify custom services for this platform"));
// add( new ProcessScrubOption( "process 'scrub' option" ));

View File

@ -354,12 +354,55 @@ namespace fwcompiler {
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
* not be used in combination with destination port with
* 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

View File

@ -30,6 +30,7 @@
#include "fwbuilder/RuleElement.h"
#include "fwbuilder/IPService.h"
#include "fwbuilder/ICMPService.h"
#include "fwbuilder/ICMP6Service.h"
#include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h"
#include "fwbuilder/CustomService.h"
@ -543,7 +544,10 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
if (ICMPService::isA(srv))
compiler->output << "icmp-type " << str << " ";
else
compiler->output << str << " ";
if (ICMP6Service::isA(srv))
compiler->output << "icmp6-type " << str << " ";
else
compiler->output << str << " ";
}
}
if (TCPService::isA(srv))
@ -551,9 +555,17 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
str=_printTCPFlags(TCPService::cast(srv));
if (!str.empty()) compiler->output << "flags " << str << " ";
}
if (IPService::isA(srv) &&
(srv->getBool("fragm") || srv->getBool("short_fragm")) )
if (IPService::isA(srv))
{
if (srv->getBool("fragm") || srv->getBool("short_fragm"))
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
{
string str;
@ -577,7 +589,10 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel)
compiler->output << "icmp-type { " << str << " } ";
else
{
compiler->output << str << " " << endl;
if (ICMP6Service::isA(srv))
compiler->output << "icmp6-type { " << str << " } ";
else
compiler->output << str << " " << endl;
}
}
}

File diff suppressed because it is too large Load Diff