mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 18:48:20 +00:00
Initial import of svn+ssh:://svn.icir.org/bro/trunk/bro as of r7088
This commit is contained in:
commit
61757ac78b
1383 changed files with 380824 additions and 0 deletions
229
src/FlowSrc.cc
Normal file
229
src/FlowSrc.cc
Normal file
|
@ -0,0 +1,229 @@
|
|||
/// $Id: FlowSrc.cc 4621 2007-07-10 13:37:13Z bager $
|
||||
//
|
||||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
//
|
||||
// Written by Bernhard Ager, TU Berlin (2006/2007).
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "FlowSrc.h"
|
||||
#include "Net.h"
|
||||
#include "netflow_pac.h"
|
||||
|
||||
FlowSrc::FlowSrc()
|
||||
{ // TODO: v9.
|
||||
idle = false;
|
||||
data = 0;
|
||||
current_timestamp = next_timestamp = 0.0;
|
||||
netflow_analyzer = new binpac::NetFlow::NetFlow_Analyzer();
|
||||
}
|
||||
|
||||
FlowSrc::~FlowSrc()
|
||||
{
|
||||
delete netflow_analyzer;
|
||||
}
|
||||
|
||||
void FlowSrc::GetFds(int* read, int* write, int* except)
|
||||
{
|
||||
#ifdef USE_SELECT_LOOP
|
||||
if ( selectable_fd >= 0 )
|
||||
*read = selectable_fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
double FlowSrc::NextTimestamp(double* network_time)
|
||||
{
|
||||
if ( ! data && ! ExtractNextPDU() )
|
||||
return -1.0;
|
||||
else
|
||||
return next_timestamp;
|
||||
}
|
||||
|
||||
void FlowSrc::Process()
|
||||
{
|
||||
if ( ! data && ! ExtractNextPDU() )
|
||||
return;
|
||||
|
||||
// This is normally done by calling net_packet_dispatch(),
|
||||
// but as we don't have a packet to dispatch ...
|
||||
network_time = next_timestamp;
|
||||
expire_timers();
|
||||
|
||||
netflow_analyzer->downflow()->set_exporter_ip(exporter_ip);
|
||||
|
||||
// We handle exceptions in NewData (might have changed w/ new binpac).
|
||||
netflow_analyzer->NewData(0, data, data + pdu_len);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
void FlowSrc::Close()
|
||||
{
|
||||
close(selectable_fd);
|
||||
}
|
||||
|
||||
|
||||
FlowSocketSrc::~FlowSocketSrc()
|
||||
{
|
||||
delete [] listenparms;
|
||||
}
|
||||
|
||||
int FlowSocketSrc::ExtractNextPDU()
|
||||
{
|
||||
sockaddr_in from;
|
||||
socklen_t fromlen = sizeof(from);
|
||||
pdu_len = recvfrom(selectable_fd, buffer, NF_MAX_PKT_SIZE, 0,
|
||||
(struct sockaddr*) &from, &fromlen);
|
||||
if ( pdu_len < 0 )
|
||||
{
|
||||
run_time("problem reading NetFlow data from socket");
|
||||
data = 0;
|
||||
next_timestamp = -1.0;
|
||||
closed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( fromlen != sizeof(from) )
|
||||
{
|
||||
run_time("malformed NetFlow PDU");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = buffer;
|
||||
exporter_ip = from.sin_addr.s_addr;
|
||||
next_timestamp = current_time();
|
||||
|
||||
if ( next_timestamp < current_timestamp )
|
||||
next_timestamp = current_timestamp;
|
||||
else
|
||||
current_timestamp = next_timestamp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
FlowSocketSrc::FlowSocketSrc(const char* listen_parms)
|
||||
{
|
||||
int n = strlen(listen_parms) + 1;
|
||||
|
||||
char laddr[n], port[n], ident[n];
|
||||
laddr[0] = port[0] = ident[0] = '\0';
|
||||
|
||||
int ret = sscanf(listen_parms, "%[^:]:%[^=]=%s", laddr, port, ident);
|
||||
if ( ret < 2 )
|
||||
{
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"parsing your listen-spec went nuts: laddr='%s', port='%s'\n",
|
||||
laddr[0] ? laddr : "", port[0] ? port : "");
|
||||
closed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const char* id = (ret == 3) ? ident : listen_parms;
|
||||
netflow_analyzer->downflow()->set_identifier(id);
|
||||
|
||||
struct addrinfo aiprefs = {
|
||||
0, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, NULL, NULL, NULL
|
||||
};
|
||||
struct addrinfo* ainfo = 0;
|
||||
if ( (ret = getaddrinfo(laddr, port, &aiprefs, &ainfo)) != 0 )
|
||||
{
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"getaddrinfo(%s, %s, ...): %s",
|
||||
laddr, port, gai_strerror(ret));
|
||||
closed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (selectable_fd = socket (PF_INET, SOCK_DGRAM, 0)) < 0 )
|
||||
{
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"socket: %s", strerror(errno));
|
||||
closed = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ( bind (selectable_fd, ainfo->ai_addr, ainfo->ai_addrlen) < 0 )
|
||||
{
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"bind: %s", strerror(errno));
|
||||
closed = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
freeaddrinfo(ainfo);
|
||||
}
|
||||
|
||||
|
||||
FlowFileSrc::~FlowFileSrc()
|
||||
{
|
||||
delete [] readfile;
|
||||
}
|
||||
|
||||
int FlowFileSrc::ExtractNextPDU()
|
||||
{
|
||||
FlowFileSrcPDUHeader pdu_header;
|
||||
|
||||
if ( read(selectable_fd, &pdu_header, sizeof(pdu_header)) <
|
||||
int(sizeof(pdu_header)) )
|
||||
return Error(errno, "read header");
|
||||
|
||||
if ( pdu_header.pdu_length > NF_MAX_PKT_SIZE )
|
||||
{
|
||||
run_time("NetFlow packet too long");
|
||||
|
||||
// Safely skip over the too-long PDU.
|
||||
if ( lseek(selectable_fd, pdu_header.pdu_length, SEEK_CUR) < 0 )
|
||||
return Error(errno, "lseek");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( read(selectable_fd, buffer, pdu_header.pdu_length) <
|
||||
pdu_header.pdu_length )
|
||||
return Error(errno, "read data");
|
||||
|
||||
if ( next_timestamp < pdu_header.network_time )
|
||||
{
|
||||
next_timestamp = pdu_header.network_time;
|
||||
current_timestamp = pdu_header.network_time;
|
||||
}
|
||||
else
|
||||
current_timestamp = next_timestamp;
|
||||
|
||||
data = buffer;
|
||||
pdu_len = pdu_header.pdu_length;
|
||||
exporter_ip = pdu_header.ipaddr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
FlowFileSrc::FlowFileSrc(const char* readfile)
|
||||
{
|
||||
int n = strlen(readfile) + 1;
|
||||
char ident[n];
|
||||
this->readfile = new char[n];
|
||||
|
||||
int ret = sscanf(readfile, "%[^=]=%s", this->readfile, ident);
|
||||
const char* id = (ret == 2) ? ident : this->readfile;
|
||||
netflow_analyzer->downflow()->set_identifier(id);
|
||||
|
||||
selectable_fd = open(this->readfile, O_RDONLY);
|
||||
if ( selectable_fd < 0 )
|
||||
{
|
||||
closed = 1;
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"open: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int FlowFileSrc::Error(int errlvl, const char* errmsg)
|
||||
{
|
||||
snprintf(errbuf, BRO_FLOW_ERRBUF_SIZE,
|
||||
"%s: %s", errmsg, strerror(errlvl));
|
||||
data = 0;
|
||||
next_timestamp = -1.0;
|
||||
closed = 1;
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue