]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/capture/ipq_linux/ipq_cap.cpp
Traffcounter divided into interface and implementation
[stg.git] / projects / stargazer / plugins / capture / ipq_linux / ipq_cap.cpp
1 #include <signal.h>
2 #include <cerrno>
3 #include <netinet/in.h>
4 #include <linux/netfilter.h>
5
6 #include "ipq_cap.h"
7 #include "raw_ip_packet.h"
8
9 extern "C"
10 {
11 #include "libipq.h"
12 }
13
14 class IPQ_CAP_CREATOR {
15 private:
16     IPQ_CAP * ic;
17
18 public:
19     IPQ_CAP_CREATOR()
20         : ic(new IPQ_CAP())
21         {
22         };
23     ~IPQ_CAP_CREATOR()
24         {
25         delete ic;
26         };
27
28     IPQ_CAP * GetCapturer()
29         {
30         return ic;
31         };
32 };
33 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
36 IPQ_CAP_CREATOR icc;
37 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
40 PLUGIN * GetPlugin()
41 {
42 return icc.GetCapturer();
43 }
44 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 const std::string IPQ_CAP::GetVersion() const
48 {
49 return "ipq_cap v.1.2";
50 }
51 //-----------------------------------------------------------------------------
52 IPQ_CAP::IPQ_CAP()
53     : ipq_h(NULL),
54       nonstop(false),
55       isRunning(false),
56       capSock(-1),
57       traffCnt(NULL)
58 {
59 memset(buf, 0, BUFSIZE);
60 }
61 //-----------------------------------------------------------------------------
62 void IPQ_CAP::SetTraffcounter(TRAFFCOUNTER * tc)
63 {
64 traffCnt = tc;
65 }
66 //-----------------------------------------------------------------------------
67 const std::string & IPQ_CAP::GetStrError() const
68 {
69 return errorStr;
70 }
71 //-----------------------------------------------------------------------------
72 int IPQ_CAP::Start()
73 {
74 if (isRunning)
75     return 0;
76 if (IPQCapOpen() < 0)
77     {
78     errorStr = "Cannot open socket!";
79     printfd(__FILE__, "Cannot open socket\n");
80     return -1;
81     }
82 nonstop = true;
83 if (pthread_create(&thread, NULL, Run, this) == 0)
84     {
85     return 0;
86     }
87 errorStr = "Cannot create thread.";
88 printfd(__FILE__, "Cannot create thread\n");
89 return -1;
90 }
91 //-----------------------------------------------------------------------------
92 int IPQ_CAP::Stop()
93 {
94 if (!isRunning)
95     return 0;
96 nonstop = false;
97 //5 seconds to thread stops itself
98 for (int i = 0; i < 25; i++)
99     {
100     if (!isRunning)
101         break;
102     usleep(200000);
103     }
104 //after 5 seconds waiting thread still running. now killing it
105 if (isRunning)
106     {
107     if (pthread_kill(thread, SIGINT))
108         {
109         errorStr = "Cannot kill thread.";
110         return -1;
111         }
112     for (int i = 0; i < 25 && isRunning; ++i)
113         {
114         usleep(200000);
115         }
116     if (isRunning)
117         {
118         printfd(__FILE__, "Thread not stopped\n");
119         }
120     else
121         {
122         pthread_join(thread, NULL);
123         }
124     }
125 IPQCapClose();
126 return 0;
127 }
128 //-----------------------------------------------------------------------------
129 bool IPQ_CAP::IsRunning()
130 {
131 return isRunning;
132 }
133 //-----------------------------------------------------------------------------
134 void * IPQ_CAP::Run(void * d)
135 {
136 RAW_PACKET raw_packet;
137 int status;
138
139 IPQ_CAP * dc = (IPQ_CAP *)d;
140 dc->isRunning = true;
141 memset(&raw_packet, 0, sizeof(raw_packet));
142 raw_packet.dataLen = -1;
143 while (dc->nonstop)
144     {
145     status = dc->IPQCapRead(&raw_packet, 68);
146     if (status == -1 ||
147         status == -2 ||
148         status == -3 ||
149         status == -4)
150         continue;
151     dc->traffCnt->Process(raw_packet);
152     }
153 dc->isRunning = false;
154 return NULL;
155 }
156 //-----------------------------------------------------------------------------
157 uint16_t IPQ_CAP::GetStartPosition() const
158 {
159 return 0;
160 }
161 //-----------------------------------------------------------------------------
162 uint16_t IPQ_CAP::GetStopPosition() const
163 {
164 return 0;
165 }
166 //-----------------------------------------------------------------------------
167 int IPQ_CAP::IPQCapOpen()
168 {
169 int status;
170
171 ipq_h = ipq_create_handle(0, PF_INET);
172 if (ipq_h == NULL)
173     {
174     ipq_destroy_handle(ipq_h);
175     errorStr = "Cannot create ipq handle!";
176     return -1;
177     }
178 status = ipq_set_mode(ipq_h, IPQ_COPY_PACKET, PAYLOAD_LEN);
179 if (status < 0)
180     {
181     ipq_destroy_handle(ipq_h);
182     errorStr = "Cannot set IPQ_COPY_PACKET mode!";
183     return -1;
184     }
185 return 0;
186 }
187 //-----------------------------------------------------------------------------
188 int IPQ_CAP::IPQCapClose()
189 {
190 ipq_destroy_handle(ipq_h);
191 return 0;
192 }
193 //-----------------------------------------------------------------------------
194 int IPQ_CAP::IPQCapRead(void * buffer, int blen)
195 {
196 int status;
197 static ipq_packet_msg_t *m;
198
199 memset(buf, 0, BUFSIZE);
200 status = ipq_read(ipq_h, buf, BUFSIZE, 1);
201 if (status == 0)
202     return -4;
203 if (errno == EINTR)
204     return -3;
205 if (status < 0)
206     return -1;
207 if (ipq_message_type(buf) != IPQM_PACKET)
208     return -2;
209 m = ipq_get_packet(buf);
210 memcpy(buffer, m->payload, blen);
211 ipq_set_verdict(ipq_h, m->packet_id, NF_ACCEPT, 0, NULL);
212 return 0;
213 }
214 //-----------------------------------------------------------------------------