LCOV - code coverage report
Current view: top level - src - DNS.h (source / functions) Hit Total Coverage
Test: app.info Lines: 2 7 28.6 %
Date: 2010-12-13 Functions: 1 4 25.0 %
Branches: 2 10 20.0 %

           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

Generated by: LCOV version 1.8