Branch data Line data Source code
1 : : // $Id: DNS.h 6885 2009-08-20 04:37:55Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef dns_h
6 : : #define dns_h
7 : :
8 : : #include "TCP.h"
9 : : #include "binpac_bro.h"
10 : :
11 : : typedef enum {
12 : : DNS_OP_QUERY = 0, ///< standard query
13 : : DNS_OP_IQUERY = 1, ///< reverse query
14 : :
15 : : // ### Is server status 2 or 3? RFC 1035 says it's 2
16 : : // DNS_OP_SERVER_STATUS = 3, ///< server status request
17 : : DNS_OP_SERVER_STATUS = 2, ///< server status request
18 : :
19 : : // Netbios operations (query = 0).
20 : : NETBIOS_REGISTRATION = 5,
21 : : NETBIOS_RELEASE = 6,
22 : : NETBIOS_WACK = 7, // wait for ACK
23 : : NETBIOS_REFRESH = 8,
24 : : } DNS_Opcode;
25 : :
26 : : typedef enum {
27 : : DNS_CODE_OK = 0, ///< no error
28 : : DNS_CODE_FORMAT_ERR = 1, ///< format error
29 : : DNS_CODE_SERVER_FAIL = 2, ///< server failure
30 : : DNS_CODE_NAME_ERR = 3, ///< no such domain
31 : : DNS_CODE_NOT_IMPL = 4, ///< not implemented
32 : : DNS_CODE_REFUSED = 5, ///< refused
33 : : } DNS_Code;
34 : :
35 : : typedef enum {
36 : : TYPE_A = 1, ///< host address
37 : : TYPE_NS = 2, ///< authoritative name server
38 : : TYPE_CNAME = 5, ///< canonical name
39 : : TYPE_SOA = 6, ///< start of authority
40 : : TYPE_WKS = 11, ///< well known service
41 : : TYPE_PTR = 12, ///< domain name pointer
42 : : TYPE_HINFO = 13, ///< host information
43 : : TYPE_MX = 15, ///< mail routing information
44 : : TYPE_TXT = 16, ///< text strings
45 : : TYPE_SIG = 24, ///< digital signature (RFC 2535)
46 : : TYPE_KEY = 25, ///< public key (RFC 2535)
47 : : TYPE_PX = 26, ///< pointer to X.400/RFC822 mapping info (RFC 1664)
48 : : TYPE_AAAA = 28, ///< IPv6 address (RFC 1886
49 : : TYPE_NBS = 32, ///< Netbios name (RFC 1002)
50 : : TYPE_SRV = 33, ///< service location (RFC 2052)
51 : : TYPE_NAPTR = 35, ///< naming authority pointer (RFC 2168)
52 : : TYPE_KX = 36, ///< Key Exchange (RFC 2230)
53 : : TYPE_CERT = 37, ///< Certificate (RFC 2538)
54 : : TYPE_A6 = 38, ///< IPv6 address with indirection (RFC 2874)
55 : : TYPE_DNAME = 39, ///< Non-terminal DNS name redirection (RFC 2672)
56 : : TYPE_EDNS = 41, ///< OPT pseudo-RR (RFC 2671)
57 : : TYPE_TKEY = 249, ///< Transaction Key (RFC 2930)
58 : : TYPE_TSIG = 250, ///< Transaction Signature (RFC 2845)
59 : :
60 : : // The following are only valid in queries.
61 : : TYPE_AXFR = 252,
62 : : TYPE_ALL = 255,
63 : : TYPE_WINS = 65281, ///< Microsoft's WINS RR
64 : : TYPE_WINSR = 65282, ///< Microsoft's WINS-R RR
65 : : } RR_Type;
66 : :
67 : : #define DNS_CLASS_IN 1
68 : : #define DNS_CLASS_ANY 255
69 : :
70 : : typedef enum {
71 : : DNS_QUESTION,
72 : : DNS_ANSWER,
73 : : DNS_AUTHORITY,
74 : : DNS_ADDITIONAL,
75 : : } DNS_AnswerType;
76 : :
77 : :
78 : : struct DNS_RawMsgHdr {
79 : : unsigned short id;
80 : : unsigned short flags;
81 : : unsigned short qdcount;
82 : : unsigned short ancount;
83 : : unsigned short nscount;
84 : : unsigned short arcount;
85 : : };
86 : :
87 : : struct EDNS_ADDITIONAL { // size
88 : : unsigned short name; // -
89 : : unsigned short type; // 16 : ExtractShort(data, len)
90 : : unsigned short payload_size; // 16
91 : : unsigned short extended_rcode; // 8
92 : : unsigned short version; // 8
93 : : unsigned short z; // 16
94 : : unsigned short rdata_len; // 16
95 : : };
96 : :
97 : : struct TSIG_DATA {
98 : : BroString* alg_name;
99 : : unsigned long time_s;
100 : : unsigned short time_ms;
101 : : BroString* sig;
102 : : unsigned short fudge;
103 : : unsigned short orig_id;
104 : : unsigned short rr_error;
105 : : };
106 : :
107 : : class DNS_MsgInfo {
108 : : public:
109 : : DNS_MsgInfo(DNS_RawMsgHdr* hdr, int is_query);
110 : : ~DNS_MsgInfo();
111 : :
112 : : Val* BuildHdrVal();
113 : : Val* BuildAnswerVal();
114 : : Val* BuildEDNS_Val();
115 : : Val* BuildTSIG_Val();
116 : :
117 : : int id;
118 : : int opcode; ///< query type, see DNS_Opcode
119 : : int rcode; ///< return code, see DNS_Code
120 : : int QR; ///< query record flag
121 : : int AA; ///< authoritiave answer flag
122 : : int TC; ///< truncated - size > 512 bytes for udp
123 : : int RD; ///< recursion desired
124 : : int RA; ///< recursion available
125 : : int Z; ///< zero - this 3 bit field *must* be zero
126 : : int qdcount; ///< number of questions
127 : : int ancount; ///< number of answers
128 : : int nscount; ///< number of authority RRs
129 : : int arcount; ///< number of additional RRs
130 : : int is_query; ///< whether it came from the session initiator
131 : :
132 : : StringVal* query_name;
133 : : RR_Type atype;
134 : : int aclass; ///< normally = 1, inet
135 : : int ttl;
136 : :
137 : : DNS_AnswerType answer_type;
138 : : int skip_event; ///< if true, don't generate corresponding events
139 : : // int answer_count; ///< count of responders. if >1 and not
140 : : ///< identical answer, there may be problems
141 : : // uint32* addr; ///< cache value to pass back results
142 : : ///< for forward lookups
143 : :
144 : : // More values for spesific DNS types.
145 : : // struct EDNS_ADDITIONAL* edns;
146 : :
147 : : int tsig_init;
148 : : struct TSIG_DATA* tsig;
149 : : };
150 : :
151 : :
152 : : class DNS_Interpreter {
153 : : public:
154 : : DNS_Interpreter(Analyzer* analyzer);
155 : :
156 : : int ParseMessage(const u_char* data, int len, int is_query);
157 : :
158 : 0 : void Timeout() { }
159 : :
160 : : protected:
161 : : int EndMessage(DNS_MsgInfo* msg);
162 : :
163 : : int ParseQuestions(DNS_MsgInfo* msg,
164 : : const u_char*& data, int& len,
165 : : const u_char* start);
166 : : int ParseAnswers(DNS_MsgInfo* msg, int n, DNS_AnswerType answer_type,
167 : : const u_char*& data, int& len,
168 : : const u_char* start);
169 : :
170 : : int ParseQuestion(DNS_MsgInfo* msg,
171 : : const u_char*& data, int& len, const u_char* start);
172 : : int ParseAnswer(DNS_MsgInfo* msg,
173 : : const u_char*& data, int& len, const u_char* start);
174 : :
175 : : u_char* ExtractName(const u_char*& data, int& len,
176 : : u_char* label, int label_len,
177 : : const u_char* msg_start);
178 : : int ExtractLabel(const u_char*& data, int& len,
179 : : u_char*& label, int& label_len,
180 : : const u_char* msg_start);
181 : :
182 : : uint16 ExtractShort(const u_char*& data, int& len);
183 : : uint32 ExtractLong(const u_char*& data, int& len);
184 : :
185 : : int ParseRR_Name(DNS_MsgInfo* msg,
186 : : const u_char*& data, int& len, int rdlength,
187 : : const u_char* msg_start);
188 : : int ParseRR_SOA(DNS_MsgInfo* msg,
189 : : const u_char*& data, int& len, int rdlength,
190 : : const u_char* msg_start);
191 : : int ParseRR_MX(DNS_MsgInfo* msg,
192 : : const u_char*& data, int& len, int rdlength,
193 : : const u_char* msg_start);
194 : : int ParseRR_NBS(DNS_MsgInfo* msg,
195 : : const u_char*& data, int& len, int rdlength,
196 : : const u_char* msg_start);
197 : : int ParseRR_SRV(DNS_MsgInfo* msg,
198 : : const u_char*& data, int& len, int rdlength,
199 : : const u_char* msg_start);
200 : : int ParseRR_EDNS(DNS_MsgInfo* msg,
201 : : const u_char*& data, int& len, int rdlength,
202 : : const u_char* msg_start);
203 : : int ParseRR_A(DNS_MsgInfo* msg,
204 : : const u_char*& data, int& len, int rdlength);
205 : : int ParseRR_AAAA(DNS_MsgInfo* msg,
206 : : const u_char*& data, int& len, int rdlength);
207 : : int ParseRR_WKS(DNS_MsgInfo* msg,
208 : : const u_char*& data, int& len, int rdlength);
209 : : int ParseRR_HINFO(DNS_MsgInfo* msg,
210 : : const u_char*& data, int& len, int rdlength);
211 : : int ParseRR_TXT(DNS_MsgInfo* msg,
212 : : const u_char*& data, int& len, int rdlength,
213 : : const u_char* msg_start);
214 : : int ParseRR_TSIG(DNS_MsgInfo* msg,
215 : : const u_char*& data, int& len, int rdlength,
216 : : const u_char* msg_start);
217 : :
218 : : void SendReplyOrRejectEvent(DNS_MsgInfo* msg, EventHandlerPtr event,
219 : : const u_char*& data, int& len,
220 : : BroString* question_name);
221 : :
222 : : Analyzer* analyzer;
223 : : };
224 : :
225 : :
226 : : typedef enum {
227 : : DNS_LEN_HI, ///< looking for the high-order byte of the length
228 : : DNS_LEN_LO, ///< looking for the low-order byte of the length
229 : : DNS_MESSAGE_BUFFER, ///< building up the message in the buffer
230 : : } TCP_DNS_state;
231 : :
232 : : // Support analyzer which chunks the TCP stream into "packets".
233 : : // ### This should be merged with TCP_Contents_RPC.
234 : : class Contents_DNS : public TCP_SupportAnalyzer {
235 : : public:
236 : : Contents_DNS(Connection* c, bool orig, DNS_Interpreter* interp);
237 : : ~Contents_DNS();
238 : :
239 : : void Flush(); ///< process any partially-received data
240 : :
241 : : TCP_DNS_state State() const { return state; }
242 : :
243 : : protected:
244 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
245 : :
246 : : DNS_Interpreter* interp;
247 : :
248 : : u_char* msg_buf;
249 : : int buf_n; ///< number of bytes in msg_buf
250 : : int buf_len; ///< size of msg_buf
251 : : int msg_size; ///< expected size of message
252 : : TCP_DNS_state state;
253 : : };
254 : :
255 : : // Works for both TCP and UDP.
256 : : class DNS_Analyzer : public TCP_ApplicationAnalyzer {
257 : : public:
258 : : DNS_Analyzer(Connection* conn);
259 : : ~DNS_Analyzer();
260 : :
261 : : virtual void DeliverPacket(int len, const u_char* data, bool orig,
262 : : int seq, const IP_Hdr* ip, int caplen);
263 : :
264 : : virtual void Init();
265 : : virtual void Done();
266 : : virtual void ConnectionClosed(TCP_Endpoint* endpoint,
267 : : TCP_Endpoint* peer, int gen_event);
268 : 0 : virtual int RewritingTrace()
269 : : {
270 : : return rewriting_dns_trace ||
271 [ # # ][ # # ]: 0 : TCP_ApplicationAnalyzer::RewritingTrace();
272 : : }
273 : :
274 : : void ExpireTimer(double t);
275 : :
276 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
277 : 0 : { return new DNS_Analyzer(conn); }
278 : :
279 : 1 : static bool Available()
280 : : {
281 : : return (dns_request || dns_full_request) &&
282 [ + - ][ - + ]: 1 : ! FLAGS_use_binpac;
[ # # ]
283 : : }
284 : :
285 : : protected:
286 : : DNS_Interpreter* interp;
287 : : Contents_DNS* contents_dns_orig;
288 : : Contents_DNS* contents_dns_resp;
289 : : int did_session_done;
290 : : };
291 : :
292 : : // FIXME: Doesn't really fit into new analyzer structure. What to do?
293 : : int IsReuse(double t, const u_char* pkt);
294 : :
295 : : #endif
|