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.
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.
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
22 * Author : Maxim Mamontov <faust@stg.dp.ua>
27 $Date: 2010/09/10 06:41:06 $
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
42 #include "raw_ip_packet.h"
44 #include "../../../traffcounter.h"
59 NF_CAP * GetCapturer() { return nf; };
64 BASE_PLUGIN * GetPlugin()
66 return cnc.GetCapturer();
88 int NF_CAP::ParseSettings()
90 vector<PARAM_VALUE>::iterator it;
91 for (it = settings.moduleParams.begin(); it != settings.moduleParams.end(); ++it)
93 if (it->param == "TCPPort")
95 if (str2x(it->value[0], portT))
97 errorStr = "Invalid TCPPort value";
98 printfd(__FILE__, "Error: Invalid TCPPort value\n");
103 if (it->param == "UDPPort")
105 if (str2x(it->value[0], portU))
107 errorStr = "Invalid UDPPort value";
108 printfd(__FILE__, "Error: Invalid UDPPort value\n");
113 printfd(__FILE__, "'%s' is not a valid module param\n", it->param.c_str());
127 if (pthread_create(&tidUDP, NULL, RunUDP, this))
131 errorStr = "Cannot create UDP thread";
132 printfd(__FILE__, "Error: Cannot create UDP thread\n");
143 if (pthread_create(&tidTCP, NULL, RunTCP, this))
147 errorStr = "Cannot create TCP thread";
148 printfd(__FILE__, "Error: Cannot create TCP thread\n");
157 runningTCP = runningUDP = false;
158 if (portU && !stoppedUDP)
161 for (int i = 0; i < 25 && !stoppedUDP; ++i)
167 pthread_join(tidUDP, NULL);
171 if (pthread_kill(tidUDP, SIGUSR1))
173 errorStr = "Error sending signal to UDP thread";
174 printfd(__FILE__, "Error: Error sending signal to UDP thread\n");
177 printfd(__FILE__, "UDP thread NOT stopped\n");
180 if (portT && !stoppedTCP)
183 for (int i = 0; i < 25 && !stoppedTCP; ++i)
189 pthread_join(tidTCP, NULL);
193 if (pthread_kill(tidTCP, SIGUSR1))
195 errorStr = "Error sending signal to TCP thread";
196 printfd(__FILE__, "Error: Error sending signal to TCP thread\n");
199 printfd(__FILE__, "TCP thread NOT stopped\n");
205 bool NF_CAP::OpenUDP()
207 struct sockaddr_in sin;
208 sockUDP = socket(PF_INET, SOCK_DGRAM, 0);
211 errorStr = "Error opening UDP socket";
212 printfd(__FILE__, "Error: Error opening UDP socket\n");
215 sin.sin_family = AF_INET;
216 sin.sin_port = htons(portU);
217 sin.sin_addr.s_addr = inet_addr("0.0.0.0");
218 if (bind(sockUDP, (struct sockaddr *)&sin, sizeof(sin)))
220 errorStr = "Error binding UDP socket";
221 printfd(__FILE__, "Error: Error binding UDP socket\n");
227 bool NF_CAP::OpenTCP()
229 struct sockaddr_in sin;
230 sockTCP = socket(PF_INET, SOCK_STREAM, 0);
233 errorStr = "Error opening TCP socket";
234 printfd(__FILE__, "Error: Error opening TCP socket\n");
237 sin.sin_family = AF_INET;
238 sin.sin_port = htons(portT);
239 sin.sin_addr.s_addr = inet_addr("0.0.0.0");
240 if (bind(sockTCP, (struct sockaddr *)&sin, sizeof(sin)))
242 errorStr = "Error binding TCP socket";
243 printfd(__FILE__, "Error: Error binding TCP socket\n");
246 if (listen(sockTCP, 1))
248 errorStr = "Error listening on TCP socket";
249 printfd(__FILE__, "Error: Error listening TCP socket\n");
255 void * NF_CAP::RunUDP(void * c)
257 NF_CAP * cap = static_cast<NF_CAP *>(c);
258 uint8_t buf[BUF_SIZE];
260 struct sockaddr_in sin;
262 cap->stoppedUDP = false;
263 while (cap->runningUDP)
265 if (!cap->WaitPackets(cap->sockUDP))
272 res = recvfrom(cap->sockUDP, buf, BUF_SIZE, 0, reinterpret_cast<struct sockaddr *>(&sin), &slen);
273 if (!cap->runningUDP)
283 // Need to check actual data length and wait all data to receive
288 cap->errorStr = "Invalid data received";
289 printfd(__FILE__, "Error: Invalid data received through UDP\n");
294 cap->ParseBuffer(buf, res);
296 cap->stoppedUDP = true;
300 void * NF_CAP::RunTCP(void * c)
302 NF_CAP * cap = static_cast<NF_CAP *>(c);
303 uint8_t buf[BUF_SIZE];
306 struct sockaddr_in sin;
308 cap->stoppedTCP = false;
309 while (cap->runningTCP)
311 if (!cap->WaitPackets(cap->sockTCP))
318 sd = accept(cap->sockTCP, reinterpret_cast<struct sockaddr *>(&sin), &slen);
319 if (!cap->runningTCP)
326 cap->errorStr = "Error accepting connection";
327 printfd(__FILE__, "Error: Error accepting connection\n");
332 if (!cap->WaitPackets(sd))
338 res = recv(sd, buf, BUF_SIZE, MSG_WAITALL);
341 if (!cap->runningTCP)
350 // Need to check actual data length and wait all data to receive
355 cap->errorStr = "Invalid data received";
356 printfd(__FILE__, "Error: Invalid data received through TCP\n");
361 cap->ParseBuffer(buf, res);
363 cap->stoppedTCP = true;
367 void NF_CAP::ParseBuffer(uint8_t * buf, int size)
370 NF_HEADER * hdr = reinterpret_cast<NF_HEADER *>(buf);
371 if (htons(hdr->version) != 5)
376 int packets = htons(hdr->count);
378 if (packets < 0 || packets > 30)
383 if (24 + 48 * packets != size)
385 // See 'wrong logic' upper
389 for (int i = 0; i < packets; ++i)
391 NF_DATA * data = reinterpret_cast<NF_DATA *>(buf + 24 + i * 48);
393 /*ip.pckt[0] = 4 << 4;
395 ip.pckt[9] = data->proto;
396 ip.dataLen = ntohl(data->octets);
397 *(uint32_t *)(ip.pckt + 12) = data->srcAddr;
398 *(uint32_t *)(ip.pckt + 16) = data->dstAddr;
399 *(uint16_t *)(ip.pckt + 20) = data->srcPort;
400 *(uint16_t *)(ip.pckt + 22) = data->dstPort;*/
401 ip.ipHeader.ip_v = 4;
402 ip.ipHeader.ip_hl = 5;
403 ip.ipHeader.ip_p = data->proto;
404 ip.dataLen = ntohl(data->octets);
405 ip.ipHeader.ip_src.s_addr = data->srcAddr;
406 ip.ipHeader.ip_dst.s_addr = data->dstAddr;
407 ip.sPort = data->srcPort;
408 ip.dPort = data->dstPort;
410 traffCnt->Process(ip);
414 bool NF_CAP::WaitPackets(int sd) const
424 int res = select(sd + 1, &rfds, NULL, NULL, &tv);
425 if (res == -1) // Error
429 printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
434 if (res == 0) // Timeout