/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Author : Maxim Mamontov */ /* $Revision: 1.3 $ $Date: 2009/10/12 08:46:05 $ $Author: faust $ */ #include "rules_finder.h" #include "logger.h" #include "lock.h" STG::RULES_FINDER::RULES_FINDER() { pthread_mutex_init(&mutex, NULL); } STG::RULES_FINDER::~RULES_FINDER() { pthread_mutex_destroy(&mutex); } void STG::RULES_FINDER::SetRules(const RULES & r) { SCOPED_LOCK lock(mutex); rules = r; } int STG::RULES_FINDER::GetDir(const PENDING_PACKET & packet) const { bool addrMatch; bool portMatch; STG::RULES::const_iterator ln; int ruleLine(1); SCOPED_LOCK lock(mutex); ln = rules.begin(); while (ln != rules.end()) { addrMatch = false; portMatch = false; // Port range switch (packet.direction) { case PENDING_PACKET::INCOMING: portMatch = (packet.sport >= ln->port1) && (packet.sport <= ln->port2); break; case PENDING_PACKET::OUTGOING: portMatch = (packet.dport >= ln->port1) && (packet.dport <= ln->port2); break; case PENDING_PACKET::LOCAL: portMatch = ((packet.sport >= ln->port1) && (packet.sport <= ln->port2)) || ((packet.dport >= ln->port1) && (packet.dport <= ln->port2)); break; default: ++ruleLine; ++ln; continue; } if (!portMatch) { ++ruleLine; ++ln; continue; } /*portMatch = ((packet.sport >= ln->port1) && (packet.sport <= ln->port2) && (packet.direction == PENDING_PACKET::INCOMING)) || ((packet.dport >= ln->port1) && (packet.dport <= ln->port2) && (packet.direction == PENDING_PACKET::OUTGOING));*/ if (ln->proto != packet.proto) { // Is it a normal protcol number? if (ln->proto >= 0) { ++ruleLine; ++ln; continue; } else if (ln->proto == -2) { // -2 - TCP_UDP if (packet.proto != 6 && packet.proto != 17) { ++ruleLine; ++ln; continue; } } // -1 - ALL } switch (packet.direction) { case PENDING_PACKET::INCOMING: // From outer world to us addrMatch = (packet.saddr & ln->mask) == ln->ip; break; case PENDING_PACKET::OUTGOING: // From us to outer world addrMatch = (packet.daddr & ln->mask) == ln->ip; break; case PENDING_PACKET::LOCAL: // From us to us addrMatch = (packet.saddr & ln->mask) == ln->ip || (packet.daddr & ln->mask) == ln->ip; break; default: // From outer world to outer world ++ruleLine; ++ln; continue; } if (addrMatch) { // At this point ports and protocol are matched return ln->dir; } ++ruleLine; ++ln; } //while (ln != rules.end()) return -1; }