Branch data Line data Source code
1 : : // $Id: Discard.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 "Var.h"
9 : : #include "Discard.h"
10 : :
11 : 1 : Discarder::Discarder()
12 : : {
13 : 1 : ip_hdr = internal_type("ip_hdr")->AsRecordType();
14 : 1 : tcp_hdr = internal_type("tcp_hdr")->AsRecordType();
15 : 1 : udp_hdr = internal_type("udp_hdr")->AsRecordType();
16 : 1 : icmp_hdr = internal_type("icmp_hdr")->AsRecordType();
17 : :
18 : 1 : check_ip = internal_func("discarder_check_ip");
19 : 1 : check_tcp = internal_func("discarder_check_tcp");
20 : 1 : check_udp = internal_func("discarder_check_udp");
21 : 1 : check_icmp = internal_func("discarder_check_icmp");
22 : :
23 : 1 : discarder_maxlen = static_cast<int>(opt_internal_int("discarder_maxlen"));
24 : 1 : }
25 : :
26 : 1 : Discarder::~Discarder()
27 : : {
28 : 1 : }
29 : :
30 : 1 : int Discarder::IsActive()
31 : : {
32 [ + - ][ + - ]: 1 : return check_ip || check_tcp || check_udp || check_icmp;
[ + - ][ - + ]
33 : : }
34 : :
35 : 0 : int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
36 : : {
37 : 0 : int discard_packet = 0;
38 : :
39 : 0 : const struct ip* ip4 = ip->IP4_Hdr();
40 : :
41 [ # # ]: 0 : if ( check_ip )
42 : : {
43 : 0 : val_list* args = new val_list;
44 : 0 : args->append(BuildHeader(ip4));
45 : 0 : discard_packet = check_ip->Call(args)->AsBool();
46 [ # # ]: 0 : delete args;
47 : :
48 [ # # ]: 0 : if ( discard_packet )
49 : 0 : return discard_packet;
50 : : }
51 : :
52 : 0 : int proto = ip4->ip_p;
53 [ # # ][ # # ]: 0 : if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
[ # # ]
54 : : proto != IPPROTO_ICMP )
55 : : // This is not a protocol we understand.
56 : 0 : return 0;
57 : :
58 : : // XXX shall we only check the first packet???
59 : 0 : uint32 frag_field = ntohs(ip4->ip_off);
60 [ # # ]: 0 : if ( (frag_field & 0x3fff) != 0 )
61 : : // Never check any fragment.
62 : 0 : return 0;
63 : :
64 : 0 : int ip_hdr_len = ip4->ip_hl * 4;
65 : 0 : len -= ip_hdr_len; // remove IP header
66 : 0 : caplen -= ip_hdr_len;
67 : :
68 : 0 : int is_tcp = (proto == IPPROTO_TCP);
69 : 0 : int is_udp = (proto == IPPROTO_UDP);
70 : : int min_hdr_len = is_tcp ?
71 : : sizeof(struct tcphdr) :
72 [ # # ][ # # ]: 0 : (is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
73 : :
74 [ # # ][ # # ]: 0 : if ( len < min_hdr_len || caplen < min_hdr_len )
75 : : // we don't have a complete protocol header
76 : 0 : return 0;
77 : :
78 : : // Where the data starts - if this is a protocol we know about,
79 : : // this gets advanced past the transport header.
80 : 0 : const u_char* data = ((u_char*) ip4 + ip_hdr_len);
81 : :
82 [ # # ]: 0 : if ( is_tcp )
83 : : {
84 [ # # ]: 0 : if ( check_tcp )
85 : : {
86 : 0 : const struct tcphdr* tp = (const struct tcphdr*) data;
87 : 0 : int th_len = tp->th_off * 4;
88 : :
89 : 0 : val_list* args = new val_list;
90 : 0 : args->append(BuildHeader(ip4));
91 : 0 : args->append(BuildHeader(tp, len));
92 : 0 : args->append(BuildData(data, th_len, len, caplen));
93 : 0 : discard_packet = check_tcp->Call(args)->AsBool();
94 [ # # ]: 0 : delete args;
95 : : }
96 : : }
97 : :
98 [ # # ]: 0 : else if ( is_udp )
99 : : {
100 [ # # ]: 0 : if ( check_udp )
101 : : {
102 : 0 : const struct udphdr* up = (const struct udphdr*) data;
103 : 0 : int uh_len = sizeof (struct udphdr);
104 : :
105 : 0 : val_list* args = new val_list;
106 : 0 : args->append(BuildHeader(ip4));
107 : 0 : args->append(BuildHeader(up));
108 : 0 : args->append(BuildData(data, uh_len, len, caplen));
109 : 0 : discard_packet = check_udp->Call(args)->AsBool();
110 [ # # ]: 0 : delete args;
111 : : }
112 : : }
113 : :
114 : : else
115 : : {
116 [ # # ]: 0 : if ( check_icmp )
117 : : {
118 : 0 : const struct icmp* ih = (const struct icmp*) data;
119 : :
120 : 0 : val_list* args = new val_list;
121 : 0 : args->append(BuildHeader(ip4));
122 : 0 : args->append(BuildHeader(ih));
123 : 0 : discard_packet = check_icmp->Call(args)->AsBool();
124 [ # # ]: 0 : delete args;
125 : : }
126 : : }
127 : :
128 : 0 : return discard_packet;
129 : : }
130 : :
131 : 0 : Val* Discarder::BuildHeader(const struct ip* ip)
132 : : {
133 : 0 : RecordVal* hdr = new RecordVal(ip_hdr);
134 : :
135 : 0 : hdr->Assign(0, new Val(ip->ip_hl * 4, TYPE_COUNT));
136 : 0 : hdr->Assign(1, new Val(ip->ip_tos, TYPE_COUNT));
137 : 0 : hdr->Assign(2, new Val(ntohs(ip->ip_len), TYPE_COUNT));
138 : 0 : hdr->Assign(3, new Val(ntohs(ip->ip_id), TYPE_COUNT));
139 : 0 : hdr->Assign(4, new Val(ip->ip_ttl, TYPE_COUNT));
140 : 0 : hdr->Assign(5, new Val(ip->ip_p, TYPE_COUNT));
141 : 0 : hdr->Assign(6, new AddrVal(ip->ip_src.s_addr));
142 : 0 : hdr->Assign(7, new AddrVal(ip->ip_dst.s_addr));
143 : :
144 : 0 : return hdr;
145 : : }
146 : :
147 : 0 : Val* Discarder::BuildHeader(const struct tcphdr* tp, int tcp_len)
148 : : {
149 : 0 : RecordVal* hdr = new RecordVal(tcp_hdr);
150 : :
151 : 0 : hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP));
152 : 0 : hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP));
153 : 0 : hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT));
154 : 0 : hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT));
155 : :
156 : 0 : int tcp_hdr_len = tp->th_off * 4;
157 : :
158 : 0 : hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT));
159 : 0 : hdr->Assign(5, new Val(tcp_len - tcp_hdr_len, TYPE_COUNT));
160 : :
161 : 0 : hdr->Assign(6, new Val(tp->th_flags, TYPE_COUNT));
162 : 0 : hdr->Assign(7, new Val(ntohs(tp->th_win), TYPE_COUNT));
163 : :
164 : 0 : return hdr;
165 : : }
166 : :
167 : 0 : Val* Discarder::BuildHeader(const struct udphdr* up)
168 : : {
169 : 0 : RecordVal* hdr = new RecordVal(udp_hdr);
170 : :
171 : 0 : hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP));
172 : 0 : hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP));
173 : 0 : hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT));
174 : :
175 : 0 : return hdr;
176 : : }
177 : :
178 : 0 : Val* Discarder::BuildHeader(const struct icmp* icmp)
179 : : {
180 : 0 : RecordVal* hdr = new RecordVal(icmp_hdr);
181 : :
182 : 0 : hdr->Assign(0, new Val(icmp->icmp_type, TYPE_COUNT));
183 : :
184 : 0 : return hdr;
185 : : }
186 : :
187 : 0 : Val* Discarder::BuildData(const u_char* data, int hdrlen, int len, int caplen)
188 : : {
189 : 0 : len -= hdrlen;
190 : 0 : caplen -= hdrlen;
191 : 0 : data += hdrlen;
192 : :
193 : 0 : len = max(min(min(len, caplen), discarder_maxlen), 0);
194 : :
195 : 0 : return new StringVal(new BroString(data, len, 1));
196 [ + - ][ + - ]: 6 : }
|