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