mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 02:58: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
207
src/UDP.cc
Normal file
207
src/UDP.cc
Normal file
|
@ -0,0 +1,207 @@
|
|||
// $Id: UDP.cc 6219 2008-10-01 05:39:07Z vern $
|
||||
//
|
||||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Net.h"
|
||||
#include "NetVar.h"
|
||||
#include "UDP.h"
|
||||
#include "UDP_Rewriter.h"
|
||||
|
||||
UDP_Analyzer::UDP_Analyzer(Connection* conn)
|
||||
: TransportLayerAnalyzer(AnalyzerTag::UDP, conn)
|
||||
{
|
||||
conn->EnableStatusUpdateTimer();
|
||||
conn->SetInactivityTimeout(udp_inactivity_timeout);
|
||||
request_len = reply_len = -1; // -1 means "haven't seen any activity"
|
||||
}
|
||||
|
||||
UDP_Analyzer::~UDP_Analyzer()
|
||||
{
|
||||
// XXX: need to implement this!
|
||||
// delete src_pkt_writer;
|
||||
}
|
||||
|
||||
void UDP_Analyzer::Init()
|
||||
{
|
||||
if ( transformed_pkt_dump && RewritingTrace() )
|
||||
SetTraceRewriter(new UDP_Rewriter(this, transformed_pkt_dump_MTU,
|
||||
transformed_pkt_dump));
|
||||
}
|
||||
|
||||
void UDP_Analyzer::Done()
|
||||
{
|
||||
Analyzer::Done();
|
||||
}
|
||||
|
||||
void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
|
||||
int seq, const IP_Hdr* ip, int caplen)
|
||||
{
|
||||
assert(ip);
|
||||
|
||||
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
|
||||
|
||||
const struct udphdr* up = (const struct udphdr*) data;
|
||||
|
||||
// Increment data before checksum check so that data will
|
||||
// point to UDP payload even if checksum fails. Particularly,
|
||||
// it allows event packet_contents to get to the data.
|
||||
data += sizeof(struct udphdr);
|
||||
|
||||
// We need the min() here because Ethernet frame padding can lead to
|
||||
// caplen > len.
|
||||
if ( packet_contents )
|
||||
PacketContents(data, min(len, caplen) - sizeof(struct udphdr));
|
||||
|
||||
int chksum = up->uh_sum;
|
||||
|
||||
if ( ! ignore_checksums && caplen >= len )
|
||||
{
|
||||
bool bad = false;
|
||||
|
||||
if ( ip->IP4_Hdr() && chksum &&
|
||||
udp_checksum(ip->IP4_Hdr(), up, len) != 0xffff )
|
||||
bad = true;
|
||||
|
||||
#ifdef BROv6
|
||||
if ( ip->IP6_Hdr() && /* checksum is not optional for IPv6 */
|
||||
udp6_checksum(ip->IP6_Hdr(), up, len) != 0xffff )
|
||||
bad = true;
|
||||
#endif
|
||||
|
||||
if ( bad )
|
||||
{
|
||||
Weird("bad_UDP_checksum");
|
||||
|
||||
if ( is_orig )
|
||||
Conn()->CheckHistory(HIST_ORIG_CORRUPT_PKT, 'C');
|
||||
else
|
||||
Conn()->CheckHistory(HIST_RESP_CORRUPT_PKT, 'c');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ulen = ntohs(up->uh_ulen);
|
||||
if ( ulen != len )
|
||||
Weird(fmt("UDP_datagram_length_mismatch(%d!=%d)", ulen, len));
|
||||
|
||||
len -= sizeof(struct udphdr);
|
||||
ulen -= sizeof(struct udphdr);
|
||||
caplen -= sizeof(struct udphdr);
|
||||
|
||||
Conn()->SetLastTime(current_timestamp);
|
||||
|
||||
if ( udp_contents )
|
||||
{
|
||||
PortVal port_val(ntohs(up->uh_dport), TRANSPORT_UDP);
|
||||
Val* result = 0;
|
||||
bool do_udp_contents = false;
|
||||
|
||||
if ( is_orig )
|
||||
{
|
||||
result = udp_content_delivery_ports_orig->Lookup(
|
||||
&port_val);
|
||||
if ( udp_content_deliver_all_orig ||
|
||||
(result && result->AsBool()) )
|
||||
do_udp_contents = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = udp_content_delivery_ports_resp->Lookup(
|
||||
&port_val);
|
||||
if ( udp_content_deliver_all_resp ||
|
||||
(result && result->AsBool()) )
|
||||
do_udp_contents = true;
|
||||
}
|
||||
|
||||
if ( do_udp_contents )
|
||||
{
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(is_orig, TYPE_BOOL));
|
||||
vl->append(new StringVal(len, (const char*) data));
|
||||
ConnectionEvent(udp_contents, vl);
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_orig )
|
||||
{
|
||||
Conn()->CheckHistory(HIST_ORIG_DATA_PKT, 'D');
|
||||
|
||||
if ( request_len < 0 )
|
||||
request_len = ulen;
|
||||
else
|
||||
{
|
||||
request_len += ulen;
|
||||
#ifdef DEBUG
|
||||
if ( request_len < 0 )
|
||||
warn("wrapping around for UDP request length");
|
||||
#endif
|
||||
}
|
||||
|
||||
Event(udp_request);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Conn()->CheckHistory(HIST_RESP_DATA_PKT, 'd');
|
||||
|
||||
if ( reply_len < 0 )
|
||||
reply_len = ulen;
|
||||
else
|
||||
{
|
||||
reply_len += ulen;
|
||||
#ifdef DEBUG
|
||||
if ( reply_len < 0 )
|
||||
warn("wrapping around for UDP reply length");
|
||||
#endif
|
||||
}
|
||||
|
||||
Event(udp_reply);
|
||||
}
|
||||
|
||||
if ( caplen >= len )
|
||||
ForwardPacket(len, data, is_orig, seq, ip, caplen);
|
||||
|
||||
if ( TraceRewriter() && current_hdr )
|
||||
((UDP_Rewriter*) TraceRewriter())->NextPacket(is_orig,
|
||||
current_timestamp, current_hdr, current_pkt,
|
||||
current_hdr_size, ip->IP4_Hdr(), up);
|
||||
|
||||
#if 0
|
||||
// XXX: needs to be implemented fully!
|
||||
if ( src_pkt_writer && current_hdr )
|
||||
src_pkt_writer->NextPacket(current_hdr, current_pkt);
|
||||
#endif
|
||||
}
|
||||
|
||||
void UDP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
|
||||
{
|
||||
bro_int_t size = is_orig ? request_len : reply_len;
|
||||
if ( size < 0 )
|
||||
{
|
||||
endp->Assign(0, new Val(0, TYPE_COUNT));
|
||||
endp->Assign(1, new Val(int(UDP_INACTIVE), TYPE_COUNT));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
endp->Assign(0, new Val(size, TYPE_COUNT));
|
||||
endp->Assign(1, new Val(int(UDP_ACTIVE), TYPE_COUNT));
|
||||
}
|
||||
}
|
||||
|
||||
bool UDP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int UDP_Analyzer::MemoryAllocation() const
|
||||
{
|
||||
// A rather low lower bound....
|
||||
return Analyzer::MemoryAllocation() + padded_sizeof(*this) - 24;
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue