]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnspacket.hh
5fe655aa4ce9ba113b63d208ec81423bdd5707fe
[thirdparty/pdns.git] / pdns / dnspacket.hh
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2005 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 2 as published
7 by the Free Software Foundation
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #ifndef DNSPACKET_HH
19
20 #if __GNUC__ == 2
21 #if __GNUC_MINOR__ < 95
22 #error Your compiler is too old! Try g++ 3.3 or higher
23 #else
24 #warning There are known problems with PowerDNS binaries compiled by gcc version 2.95 and 2.96!
25 #endif
26 #endif
27
28 #define DNSPACKET_HH
29
30 #include <cstdio>
31 #include <cstring>
32 #include <cstdlib>
33 #include <sys/types.h>
34 #include "iputils.hh"
35
36 #ifndef WIN32
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <sys/time.h>
40 #include <unistd.h>
41 #include <arpa/inet.h>
42
43 #endif // WIN32
44
45 #include <iostream>
46 #include <string>
47
48 #include <vector>
49 #include "qtype.hh"
50 #include "dns.hh"
51 #include "misc.hh"
52 #include "utility.hh"
53 #include "logger.hh"
54 #include "ahuexception.hh"
55
56 #ifdef HAVE_CONFIG_H
57 #include "config.h"
58 #endif // HAVE_CONFIG_H
59
60
61 #ifdef WIN32
62 # ifdef BYTE_ORDER
63 # undef BYTE_ORDER
64 # endif // BYTE_ORDER
65 # define BYTE_ORDER LITTLE_ENDIAN
66 #endif // WIN32
67
68 class DNSBackend;
69
70 /** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */
71 void fillSOAData(const string &content, SOAData &data);
72
73 /** for use by DNSPacket, converts a SOAData class to a ascii line again */
74 string serializeSOAData(const SOAData &data);
75
76 string &attodot(string &str); //!< for when you need to insert an email address in the SOA
77
78 //! This class represents DNS packets, either received or to be sent.
79 class DNSPacket
80 {
81 public:
82 DNSPacket();
83 DNSPacket(const DNSPacket &orig);
84
85 int noparse(const char *mesg, int len); //!< parse a raw UDP or TCP packet and suck the data inward
86 int parse(const char *mesg, int len); //!< parse a raw UDP or TCP packet and suck the data inward
87 string getString(); //!< for serialization - just passes the whole packet
88
89 // address & socket manipulation
90 void setRemote(const ComboAddress*);
91 string getRemote() const;
92 string getLocal() const
93 {
94 ComboAddress ca;
95 socklen_t len=sizeof(ca);
96 getsockname(d_socket, (sockaddr*)&ca, &len);
97 return ca.toString();
98 }
99 uint16_t getRemotePort() const;
100
101 Utility::sock_t getSocket() const
102 {
103 return d_socket;
104 }
105 void setSocket(Utility::sock_t sock);
106
107
108 // these manipulate 'd'
109 void setA(bool); //!< make this packet authoritative - manipulates 'd'
110 void setID(uint16_t); //!< set the DNS id of this packet - manipulates 'd'
111 void setRA(bool); //!< set the Recursion Available flag - manipulates 'd'
112 void setRD(bool); //!< set the Recursion Desired flag - manipulates 'd'
113 void setAnswer(bool); //!< Make this packet an answer - clears the 'stringbuffer' first, if passed 'true', does nothing otherwise, manipulates 'd'
114
115 void setOpcode(uint16_t); //!< set the Opcode of this packet - manipulates 'd'
116 void setRcode(int v); //!< set the Rcode of this packet - manipulates 'd'
117
118 void clearRecords(); //!< when building a packet, wipe all previously added records (clears 'rrs')
119
120 /** Add a DNSResourceRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
121 Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
122 DNSResourceRecord d_place field */
123 void addRecord(const DNSResourceRecord &); // adds to 'rrs'
124
125 void setQuestion(int op, const string &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (label, type, class etc)
126
127 DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer
128 void wrapup(void); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer
129 const char *getData(void); //!< get binary representation of packet, will call 'wrapup' for you
130
131 const char *getRaw(void); //!< provides access to the raw packet, possibly on a packet that has never been 'wrapped'
132 void spoofID(uint16_t id); //!< change the ID of an existing packet. Useful for fixing up packets returned from the PacketCache
133 void spoofQuestion(const string &qd); //!< paste in the exact right case of the question. Useful for PacketCache
134 void truncate(int new_length); // has documentation in source
135
136 vector<DNSResourceRecord*> getAPRecords(); //!< get a vector with DNSResourceRecords that need additional processing
137 void setCompress(bool compress);
138
139 DNSPacket *replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
140
141 void commitD(); //!< copies 'd' into the stringbuffer
142 int getMaxReplyLen(); //!< retrieve the maximum length of the packet we should send in response
143 void setMaxReplyLen(int bytes); //!< set the max reply len (used when retrieving from the packet cache, and this changed)
144
145 bool couldBeCached(); //!< returns 0 if this query should bypass the packet cache
146
147 //////// DATA !
148
149 ComboAddress remote;
150 uint16_t len; //!< length of the raw binary packet 2
151 uint16_t qclass; //!< class of the question - should always be INternet 2
152 struct dnsheader d; //!< dnsheader at the start of the databuffer 12
153
154 QType qtype; //!< type of the question 8
155
156 string qdomain; //!< qname of the question 4 - unsure how this is used
157 bool d_tcp;
158
159 private:
160 void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies
161
162 bool d_wrapped; // 1
163 bool d_compress; // 1
164 uint16_t d_qlen; // length of the question (including class & type) in this packet 2
165
166 int d_socket; // 4
167
168 string stringbuffer; // this is where everything lives 4
169 int d_maxreplylen;
170 string d_ednsping;
171 bool d_wantsnsid;
172 vector<DNSResourceRecord> rrs; // 4
173 };
174
175
176
177 #endif