]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/capture/ipq_linux/ipq_cap.cpp
e0beba9c2b34f452127e0182a6edcaaab3e8bcda
[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 #include "../../../traffcounter.h"
9
10 extern "C"
11 {
12 #include "libipq.h"
13 }
14
15 class IPQ_CAP_CREATOR {
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 PLUGIN * GetPlugin()
42 {
43 return icc.GetCapturer();
44 }
45 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
48 const std::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 int IPQ_CAP::Start()
64 {
65 if (isRunning)
66     return 0;
67 if (IPQCapOpen() < 0)
68     {
69     errorStr = "Cannot open socket!";
70     printfd(__FILE__, "Cannot open socket\n");
71     return -1;
72     }
73 nonstop = true;
74 if (pthread_create(&thread, NULL, Run, this) == 0)
75     {
76     return 0;
77     }
78 errorStr = "Cannot create thread.";
79 printfd(__FILE__, "Cannot create thread\n");
80 return -1;
81 }
82 //-----------------------------------------------------------------------------
83 int IPQ_CAP::Stop()
84 {
85 if (!isRunning)
86     return 0;
87 nonstop = false;
88 //5 seconds to thread stops itself
89 for (int i = 0; i < 25; i++)
90     {
91     if (!isRunning)
92         break;
93     usleep(200000);
94     }
95 //after 5 seconds waiting thread still running. now killing it
96 if (isRunning)
97     {
98     if (pthread_kill(thread, SIGINT))
99         {
100         errorStr = "Cannot kill thread.";
101         return -1;
102         }
103     for (int i = 0; i < 25 && isRunning; ++i)
104         {
105         usleep(200000);
106         }
107     if (isRunning)
108         {
109         printfd(__FILE__, "Thread not stopped\n");
110         }
111     else
112         {
113         pthread_join(thread, NULL);
114         }
115     }
116 IPQCapClose();
117 return 0;
118 }
119 //-----------------------------------------------------------------------------
120 void * IPQ_CAP::Run(void * d)
121 {
122 RAW_PACKET raw_packet;
123
124 IPQ_CAP * dc = (IPQ_CAP *)d;
125 dc->isRunning = true;
126 memset(&raw_packet, 0, sizeof(raw_packet));
127 raw_packet.dataLen = -1;
128 while (dc->nonstop)
129     {
130     int status = dc->IPQCapRead(&raw_packet, 68);
131     if (status == -1 ||
132         status == -2 ||
133         status == -3 ||
134         status == -4)
135         continue;
136     dc->traffCnt->Process(raw_packet);
137     }
138 dc->isRunning = false;
139 return NULL;
140 }
141 //-----------------------------------------------------------------------------
142 int IPQ_CAP::IPQCapOpen()
143 {
144 ipq_h = ipq_create_handle(0, PF_INET);
145 if (ipq_h == NULL)
146     {
147     ipq_destroy_handle(ipq_h);
148     errorStr = "Cannot create ipq handle!";
149     return -1;
150     }
151 int status = ipq_set_mode(ipq_h, IPQ_COPY_PACKET, PAYLOAD_LEN);
152 if (status < 0)
153     {
154     ipq_destroy_handle(ipq_h);
155     errorStr = "Cannot set IPQ_COPY_PACKET mode!";
156     return -1;
157     }
158 return 0;
159 }
160 //-----------------------------------------------------------------------------
161 int IPQ_CAP::IPQCapClose()
162 {
163 ipq_destroy_handle(ipq_h);
164 return 0;
165 }
166 //-----------------------------------------------------------------------------
167 int IPQ_CAP::IPQCapRead(void * buffer, int blen)
168 {
169 memset(buf, 0, BUFSIZE);
170 int status = ipq_read(ipq_h, buf, BUFSIZE, 1);
171 if (status == 0)
172     return -4;
173 if (errno == EINTR)
174     return -3;
175 if (status < 0)
176     return -1;
177 if (ipq_message_type(buf) != IPQM_PACKET)
178     return -2;
179 static ipq_packet_msg_t * m = ipq_get_packet(buf);
180 memcpy(buffer, m->payload, blen);
181 ipq_set_verdict(ipq_h, m->packet_id, NF_ACCEPT, 0, NULL);
182 return 0;
183 }
184 //-----------------------------------------------------------------------------