]> git.stg.codes - stg.git/blob - projects/traffcounter/rules_finder.cpp
Merge branch 'master' into full-month-stats
[stg.git] / projects / traffcounter / rules_finder.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21 /*
22  $Revision: 1.3 $
23  $Date: 2009/10/12 08:46:05 $
24  $Author: faust $
25  */
26
27 #include "rules_finder.h"
28 #include "logger.h"
29 #include "lock.h"
30
31 STG::RULES_FINDER::RULES_FINDER()
32 {
33     pthread_mutex_init(&mutex, NULL);
34 }
35
36 STG::RULES_FINDER::~RULES_FINDER()
37 {
38     pthread_mutex_destroy(&mutex);
39 }
40
41 void STG::RULES_FINDER::SetRules(const RULES & r)
42 {
43 SCOPED_LOCK lock(mutex);
44 rules = r;
45 }
46
47 int STG::RULES_FINDER::GetDir(const PENDING_PACKET & packet) const
48 {
49 bool addrMatch;
50 bool portMatch;
51
52 STG::RULES::const_iterator ln;
53 int ruleLine(1);
54
55 SCOPED_LOCK lock(mutex);
56
57 ln = rules.begin();
58
59 while (ln != rules.end())
60     {
61     addrMatch = false;
62     portMatch = false;
63
64     // Port range
65     switch (packet.direction) {
66         case PENDING_PACKET::INCOMING:
67             portMatch = (packet.sport >= ln->port1) &&
68                         (packet.sport <= ln->port2);
69             break;
70         case PENDING_PACKET::OUTGOING:
71             portMatch = (packet.dport >= ln->port1) &&
72                         (packet.dport <= ln->port2);
73             break;
74         case PENDING_PACKET::LOCAL:
75             portMatch = ((packet.sport >= ln->port1) &&
76                         (packet.sport <= ln->port2)) ||
77                         ((packet.dport >= ln->port1) &&
78                         (packet.dport <= ln->port2));
79             break;
80         default:
81             ++ruleLine;
82             ++ln;
83             continue;
84     }
85
86     if (!portMatch) {
87         ++ruleLine;
88         ++ln;
89         continue;
90     }
91
92     /*portMatch = ((packet.sport >= ln->port1) &&
93                  (packet.sport <= ln->port2) &&
94                  (packet.direction == PENDING_PACKET::INCOMING)) ||
95                 ((packet.dport >= ln->port1) &&
96                  (packet.dport <= ln->port2) &&
97                  (packet.direction == PENDING_PACKET::OUTGOING));*/
98
99     if (ln->proto != packet.proto)
100         {
101         // Is it a normal protcol number?
102         if (ln->proto >= 0)
103             {
104             ++ruleLine;
105             ++ln;
106             continue;
107             }
108         else if (ln->proto == -2)
109             {
110             // -2 - TCP_UDP
111             if (packet.proto != 6 &&
112                 packet.proto != 17)
113                 {
114                 ++ruleLine;
115                 ++ln;
116                 continue;
117                 }
118             }
119         // -1 - ALL
120         }
121
122     switch (packet.direction) {
123         case PENDING_PACKET::INCOMING:
124             // From outer world to us
125             addrMatch = (packet.saddr & ln->mask) == ln->ip;
126             break;
127         case PENDING_PACKET::OUTGOING:
128             // From us to outer world
129             addrMatch = (packet.daddr & ln->mask) == ln->ip;
130             break;
131         case PENDING_PACKET::LOCAL:
132             // From us to us
133             addrMatch = (packet.saddr & ln->mask) == ln->ip ||
134                         (packet.daddr & ln->mask) == ln->ip;
135             break;
136         default:
137             // From outer world to outer world
138             ++ruleLine;
139             ++ln;
140             continue;
141     }
142
143
144     if (addrMatch)
145         {
146         // At this point ports and protocol are matched
147         return ln->dir;
148         }
149
150     ++ruleLine;
151     ++ln;
152     }   //while (ln != rules.end())
153
154 return -1;
155 }