Branch data Line data Source code
1 : : // $Id: UDP.cc 6219 2008-10-01 05:39:07Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include "Net.h"
8 : : #include "NetVar.h"
9 : : #include "UDP.h"
10 : : #include "UDP_Rewriter.h"
11 : :
12 : 684 : UDP_Analyzer::UDP_Analyzer(Connection* conn)
13 : 684 : : TransportLayerAnalyzer(AnalyzerTag::UDP, conn)
14 : : {
15 : 684 : conn->EnableStatusUpdateTimer();
16 : 684 : conn->SetInactivityTimeout(udp_inactivity_timeout);
17 : 684 : request_len = reply_len = -1; // -1 means "haven't seen any activity"
18 : 684 : }
19 : :
20 : 684 : UDP_Analyzer::~UDP_Analyzer()
21 : : {
22 : : // XXX: need to implement this!
23 : : // delete src_pkt_writer;
24 [ + - ][ # # ]: 684 : }
[ # # ]
25 : :
26 : 684 : void UDP_Analyzer::Init()
27 : : {
28 [ - + ][ # # ]: 684 : if ( transformed_pkt_dump && RewritingTrace() )
[ - + ]
29 : : SetTraceRewriter(new UDP_Rewriter(this, transformed_pkt_dump_MTU,
30 : 0 : transformed_pkt_dump));
31 : 684 : }
32 : :
33 : 684 : void UDP_Analyzer::Done()
34 : : {
35 : 684 : Analyzer::Done();
36 : 684 : }
37 : :
38 : : void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
39 : 1683 : int seq, const IP_Hdr* ip, int caplen)
40 : : {
41 [ - + ]: 1683 : assert(ip);
42 : :
43 : 1683 : Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
44 : :
45 : 1683 : const struct udphdr* up = (const struct udphdr*) data;
46 : :
47 : : // Increment data before checksum check so that data will
48 : : // point to UDP payload even if checksum fails. Particularly,
49 : : // it allows event packet_contents to get to the data.
50 : 1683 : data += sizeof(struct udphdr);
51 : :
52 : : // We need the min() here because Ethernet frame padding can lead to
53 : : // caplen > len.
54 [ - + ]: 1683 : if ( packet_contents )
55 : 0 : PacketContents(data, min(len, caplen) - sizeof(struct udphdr));
56 : :
57 : 1683 : int chksum = up->uh_sum;
58 : :
59 [ + - ][ + - ]: 1683 : if ( ! ignore_checksums && caplen >= len )
60 : : {
61 : 1683 : bool bad = false;
62 : :
63 [ + - ][ + - ]: 1683 : if ( ip->IP4_Hdr() && chksum &&
[ - + ][ - + ]
64 : : udp_checksum(ip->IP4_Hdr(), up, len) != 0xffff )
65 : 0 : bad = true;
66 : :
67 : : #ifdef BROv6
68 : : if ( ip->IP6_Hdr() && /* checksum is not optional for IPv6 */
69 : : udp6_checksum(ip->IP6_Hdr(), up, len) != 0xffff )
70 : : bad = true;
71 : : #endif
72 : :
73 [ - + ]: 1683 : if ( bad )
74 : : {
75 : 0 : Weird("bad_UDP_checksum");
76 : :
77 [ # # ]: 0 : if ( is_orig )
78 : 0 : Conn()->CheckHistory(HIST_ORIG_CORRUPT_PKT, 'C');
79 : : else
80 : 0 : Conn()->CheckHistory(HIST_RESP_CORRUPT_PKT, 'c');
81 : :
82 : 0 : return;
83 : : }
84 : : }
85 : :
86 : 1683 : int ulen = ntohs(up->uh_ulen);
87 [ - + ]: 1683 : if ( ulen != len )
88 : 0 : Weird(fmt("UDP_datagram_length_mismatch(%d!=%d)", ulen, len));
89 : :
90 : 1683 : len -= sizeof(struct udphdr);
91 : 1683 : ulen -= sizeof(struct udphdr);
92 : 1683 : caplen -= sizeof(struct udphdr);
93 : :
94 : 1683 : Conn()->SetLastTime(current_timestamp);
95 : :
96 [ - + ]: 1683 : if ( udp_contents )
97 : : {
98 : 0 : PortVal port_val(ntohs(up->uh_dport), TRANSPORT_UDP);
99 : 0 : Val* result = 0;
100 : 0 : bool do_udp_contents = false;
101 : :
102 [ # # ]: 0 : if ( is_orig )
103 : : {
104 : : result = udp_content_delivery_ports_orig->Lookup(
105 : 0 : &port_val);
106 [ # # # # ]: 0 : if ( udp_content_deliver_all_orig ||
[ # # ][ # # ]
107 : : (result && result->AsBool()) )
108 : 0 : do_udp_contents = true;
109 : : }
110 : : else
111 : : {
112 : : result = udp_content_delivery_ports_resp->Lookup(
113 : 0 : &port_val);
114 [ # # # # ]: 0 : if ( udp_content_deliver_all_resp ||
[ # # ][ # # ]
115 : : (result && result->AsBool()) )
116 : 0 : do_udp_contents = true;
117 : : }
118 : :
119 [ # # ]: 0 : if ( do_udp_contents )
120 : : {
121 : 0 : val_list* vl = new val_list;
122 : 0 : vl->append(BuildConnVal());
123 : 0 : vl->append(new Val(is_orig, TYPE_BOOL));
124 : 0 : vl->append(new StringVal(len, (const char*) data));
125 : 0 : ConnectionEvent(udp_contents, vl);
126 : 0 : }
127 : : }
128 : :
129 [ + + ]: 1683 : if ( is_orig )
130 : : {
131 : 1173 : Conn()->CheckHistory(HIST_ORIG_DATA_PKT, 'D');
132 : :
133 [ + + ]: 1173 : if ( request_len < 0 )
134 : 563 : request_len = ulen;
135 : : else
136 : : {
137 : 610 : request_len += ulen;
138 : : #ifdef DEBUG
139 [ - + ]: 610 : if ( request_len < 0 )
140 : 0 : warn("wrapping around for UDP request length");
141 : : #endif
142 : : }
143 : :
144 : 1173 : Event(udp_request);
145 : : }
146 : :
147 : : else
148 : : {
149 : 510 : Conn()->CheckHistory(HIST_RESP_DATA_PKT, 'd');
150 : :
151 [ + + ]: 510 : if ( reply_len < 0 )
152 : 399 : reply_len = ulen;
153 : : else
154 : : {
155 : 111 : reply_len += ulen;
156 : : #ifdef DEBUG
157 [ - + ]: 111 : if ( reply_len < 0 )
158 : 0 : warn("wrapping around for UDP reply length");
159 : : #endif
160 : : }
161 : :
162 : 510 : Event(udp_reply);
163 : : }
164 : :
165 [ + - ]: 1683 : if ( caplen >= len )
166 : 1683 : ForwardPacket(len, data, is_orig, seq, ip, caplen);
167 : :
168 [ - + ][ # # ]: 1683 : if ( TraceRewriter() && current_hdr )
[ - + ]
169 : : ((UDP_Rewriter*) TraceRewriter())->NextPacket(is_orig,
170 : : current_timestamp, current_hdr, current_pkt,
171 : 1683 : current_hdr_size, ip->IP4_Hdr(), up);
172 : :
173 : : #if 0
174 : : // XXX: needs to be implemented fully!
175 : : if ( src_pkt_writer && current_hdr )
176 : : src_pkt_writer->NextPacket(current_hdr, current_pkt);
177 : : #endif
178 : : }
179 : :
180 : 2736 : void UDP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
181 : : {
182 [ + + ]: 2736 : bro_int_t size = is_orig ? request_len : reply_len;
183 [ + + ]: 2736 : if ( size < 0 )
184 : : {
185 : 1774 : endp->Assign(0, new Val(0, TYPE_COUNT));
186 : 1774 : endp->Assign(1, new Val(int(UDP_INACTIVE), TYPE_COUNT));
187 : : }
188 : :
189 : : else
190 : : {
191 : 962 : endp->Assign(0, new Val(size, TYPE_COUNT));
192 : 962 : endp->Assign(1, new Val(int(UDP_ACTIVE), TYPE_COUNT));
193 : : }
194 : 2736 : }
195 : :
196 : 999 : bool UDP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
197 : : {
198 : 999 : return 0;
199 : : }
200 : :
201 : 0 : unsigned int UDP_Analyzer::MemoryAllocation() const
202 : : {
203 : : // A rather low lower bound....
204 : 0 : return Analyzer::MemoryAllocation() + padded_sizeof(*this) - 24;
205 [ + - ][ + - ]: 6 : }
206 : 3 :
207 : :
|