]> git.stg.codes - stg.git/blob - projects/traffcounter/rf_tester.cpp
Produce debug output only if SMUX_DEBUG is defined
[stg.git] / projects / traffcounter / rf_tester.cpp
1 /*
2  *  Network:
3  *   - server: 192.168.0.1
4  *   - user A: 192.168.0.2
5  *   - user B: 192.168.0.3
6  *
7  *  External resources:
8  *   - host 1: 216.239.59.104
9  *   - host 2: 72.14.221.104
10  *   - host 3: 66.249.93.104
11  *   - host 4: 195.5.61.68
12  *   
13  *  Directions:
14  *   - Local: ALL 192.168.0.0/24
15  *   - DNS: TCP_UDP 195.5.61.68/32:53
16  *   - FTP: TCP 129.22.8.159/32:20-21
17  *   - World: ALL 0.0.0.0/0
18  *
19  */
20
21 #include <cstdlib>
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 #include <algorithm>
26
27 #include <arpa/inet.h>
28
29 #include "rules.h"
30 #include "rules_finder.h"
31 #include "logger.h"
32
33 using namespace std;
34 using namespace STG;
35
36 STGLogger log;
37
38 RULE MakeRule(const std::string & ip,
39               const std::string & mask,
40               uint16_t port1,
41               uint16_t port2,
42               int proto,
43               int dir)
44 {
45     RULE rule;
46
47     rule.ip = inet_addr(ip.c_str());
48     rule.mask = inet_addr(mask.c_str());
49     rule.port1 = port1;
50     rule.port2 = port2;
51     rule.proto = proto;
52     rule.dir = dir;
53
54     return rule;
55 }
56
57 RULES PrepareRules()
58 {
59     RULES rules;
60     RULE local(MakeRule("192.168.0.0",
61                         "255.255.255.0",
62                         0,
63                         65535,
64                         -1,
65                         0));
66     RULE dns(MakeRule("195.5.61.68",
67                       "255.255.255.255",
68                       53,
69                       53,
70                       -1,
71                       1));
72     RULE ftp(MakeRule("129.22.8.159",
73                       "255.255.255.255",
74                       20,
75                       21,
76                       -1,
77                       2));
78     RULE world(MakeRule("0.0.0.0",
79                         "0.0.0.0",
80                         0,
81                         65535,
82                         -1,
83                         3));
84
85     rules.push_back(local);
86
87     rules.push_back(dns);
88
89     rules.push_back(ftp);
90
91     rules.push_back(world);
92
93     return rules;
94 }
95
96 PENDING_PACKET MakePacket(const std::string & from,
97                           const std::string & to,
98                           uint16_t sport,
99                           uint16_t dport,
100                           int proto,
101                           PENDING_PACKET::DIRECTION direction,
102                           int length)
103 {
104     iphdr hdr;
105
106     hdr.ihl = 5;
107     hdr.version = 4;
108     hdr.tos = 0;
109     hdr.tot_len = length;
110     hdr.id = 0;
111     hdr.frag_off = 50;
112     hdr.ttl = 64;
113     hdr.protocol = proto;
114     hdr.check = 0;
115     hdr.saddr = inet_addr(from.c_str());
116     hdr.daddr = inet_addr(to.c_str());
117
118     PENDING_PACKET packet(hdr, sport, dport);
119
120     packet.direction = direction;
121
122     return packet;
123 }
124
125 struct TEST_INFO {
126     int  wantedDir;
127     int  actualDir; // Parser error status
128     bool stdException; // Parser throws an std execption
129     bool otherException; // Parser throws another exception
130     bool result;
131 };
132
133 struct RF_TESTER : public std::unary_function<std::pair<PENDING_PACKET, int>, void>
134 {
135 public:
136     RF_TESTER(RULES_FINDER & r)
137         : rf(r),
138           testLog(),
139           result(true)
140         {
141         };
142     ~RF_TESTER()
143         {
144         PrintLog();
145         if (result)
146             exit(EXIT_SUCCESS);
147         exit(EXIT_FAILURE);
148         }
149     void operator()(const std::pair<PENDING_PACKET, int> & entry)
150         {
151         TEST_INFO info;
152         info.wantedDir = entry.second;
153         info.actualDir = -1;
154         info.stdException = false;
155         info.otherException = false;
156         info.result = true;
157         try
158             {
159             info.actualDir = rf.GetDir(entry.first);
160             }
161         catch (std::exception & ex)
162             {
163             info.stdException = true;
164             info.result = false;
165             }
166         catch (...)
167             {
168             info.otherException = true;
169             info.result = false;
170             }
171         info.result &= (info.actualDir == info.wantedDir);
172         result &= info.result;
173         testLog.push_back(info);
174         };
175
176     void PrintLog()
177         {
178         int testNumber = 1;
179         std::cout << "RF_TESTER results:\n";
180         std::cout << "-----------------------------------------------------------------\n";
181         std::vector<TEST_INFO>::const_iterator it;
182         for (it = testLog.begin(); it != testLog.end(); ++it)
183             {
184             std::cout << "Test no.: " << testNumber++ << "\t"
185                       << "Correct dir: " << it->wantedDir << "\t"
186                       << "Actual dir:" << it->actualDir << "\t"
187                       << "STD exceptions: " << it->stdException << "\t"
188                       << "Other exceptions: " << it->otherException << "\t"
189                       << "Result: " << it->result << "\n";
190             }
191         std::cout << "-----------------------------------------------------------------\n";
192         std::cout << "Final result: " << (result ? "passed" : "failed") << std::endl;
193         }
194
195     bool Result() const { return result; };
196 private:
197     RULES_FINDER & rf;
198     std::vector<TEST_INFO> testLog;
199     bool result;
200 };
201
202 int main()
203 {
204     RULES rules(PrepareRules());
205     RULES_FINDER rf;
206
207     rf.SetRules(rules);
208
209     std::list<std::pair<PENDING_PACKET, int> > tests;
210
211     // Local, SSH
212     tests.push_back(make_pair(MakePacket("192.168.0.2", "192.168.0.1", 3214, 22, 6, PENDING_PACKET::OUTGOING, 0), 0));
213     tests.push_back(make_pair(MakePacket("192.168.0.1", "192.168.0.2", 22, 3214, 6, PENDING_PACKET::OUTGOING, 0), 0));
214     // Local, SSH, incorrect direction detection
215     tests.push_back(make_pair(MakePacket("192.168.0.2", "192.168.0.1", 3214, 22, 6, PENDING_PACKET::INCOMING, 0), 0));
216     tests.push_back(make_pair(MakePacket("192.168.0.1", "192.168.0.2", 22, 3214, 6, PENDING_PACKET::INCOMING, 0), 0));
217     // Local, FTP
218     tests.push_back(make_pair(MakePacket("192.168.0.2", "192.168.0.1", 3214, 20, 6, PENDING_PACKET::OUTGOING, 0), 0));
219     tests.push_back(make_pair(MakePacket("192.168.0.1", "192.168.0.2", 21, 3214, 6, PENDING_PACKET::OUTGOING, 0), 0));
220     // Local, DNS
221     tests.push_back(make_pair(MakePacket("192.168.0.2", "192.168.0.1", 3214, 53, 6, PENDING_PACKET::OUTGOING, 0), 0));
222     tests.push_back(make_pair(MakePacket("192.168.0.1", "192.168.0.2", 53, 3214, 6, PENDING_PACKET::OUTGOING, 0), 0));
223     // Known DNS, DNS
224     tests.push_back(make_pair(MakePacket("192.168.0.2", "195.5.61.68", 3210, 53, 6, PENDING_PACKET::OUTGOING, 0), 1));
225     tests.push_back(make_pair(MakePacket("195.5.61.68", "192.168.0.2", 53, 3210, 6, PENDING_PACKET::INCOMING, 0), 1));
226     // Known DNS, invalid ports
227     tests.push_back(make_pair(MakePacket("192.168.0.2", "195.5.61.68", 3210, 54, 6, PENDING_PACKET::OUTGOING, 0), 3));
228     tests.push_back(make_pair(MakePacket("195.5.61.68", "192.168.0.2", 20, 3210, 6, PENDING_PACKET::INCOMING, 0), 3));
229     // Known FTP, FTP
230     tests.push_back(make_pair(MakePacket("192.168.0.2", "129.22.8.159", 3241, 20, 6, PENDING_PACKET::OUTGOING, 0), 2));
231     tests.push_back(make_pair(MakePacket("129.22.8.159", "192.168.0.2", 21, 3241, 6, PENDING_PACKET::INCOMING, 0), 2));
232     // Known FTP, invalid ports
233     tests.push_back(make_pair(MakePacket("192.168.0.2", "129.22.8.159", 3241, 53, 6, PENDING_PACKET::OUTGOING, 0), 3));
234     tests.push_back(make_pair(MakePacket("129.22.8.159", "192.168.0.2", 22, 3241, 6, PENDING_PACKET::INCOMING, 0), 3));
235
236     std::for_each(tests.begin(),
237                  tests.end(),
238                  RF_TESTER(rf));
239
240     return EXIT_SUCCESS;
241 }