1<?php
2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4/**
5 * DNS Library for handling lookups and updates.
6 *
7 * PHP Version 5
8 *
9 * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 *   * Redistributions of source code must retain the above copyright
17 *     notice, this list of conditions and the following disclaimer.
18 *
19 *   * Redistributions in binary form must reproduce the above copyright
20 *     notice, this list of conditions and the following disclaimer in
21 *     the documentation and/or other materials provided with the
22 *     distribution.
23 *
24 *   * Neither the name of Mike Pultz nor the names of his contributors
25 *     may be used to endorse or promote products derived from this
26 *     software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 *
41 * @category  Networking
42 * @package   Net_DNS2
43 * @author    Mike Pultz <mike@mikepultz.com>
44 * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
46 * @version   SVN: $Id$
47 * @link      http://pear.php.net/package/Net_DNS2
48 * @since     File available since Release 0.6.0
49 *
50 */
51
52/**
53 * This class handles parsing and constructing the question sectino of DNS
54 * packets.
55 *
56 * This is referred to as the "zone" for update per RFC2136
57 *
58 * DNS question format - RFC1035 section 4.1.2
59 *
60 *      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
61 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62 *    |                                               |
63 *    /                     QNAME                     /
64 *    /                                               /
65 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66 *    |                     QTYPE                     |
67 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68 *    |                     QCLASS                    |
69 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70 *
71 * @category Networking
72 * @package  Net_DNS2
73 * @author   Mike Pultz <mike@mikepultz.com>
74 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
75 * @link     http://pear.php.net/package/Net_DNS2
76 * @see      Net_DNS2_Packet
77 *
78 */
79class Net_DNS2_Question
80{
81    /*
82     * The name of the question
83     *
84     * referred to as "zname" for updates per RFC2136
85     *
86     */
87    public $qname;
88
89    /*
90     * The RR type for the questino
91     *
92     * referred to as "ztype" for updates per RFC2136
93     *
94     */
95    public $qtype;
96
97    /*
98     * The RR class for the questino
99     *
100     * referred to as "zclass" for updates per RFC2136
101     *
102     */
103    public $qclass;
104
105    /**
106     * Constructor - builds a new Net_DNS2_Question object
107     *
108     * @param mixed &$packet either a Net_DNS2_Packet object, or null to
109     *                       build an empty object
110     *
111     * @throws Net_DNS2_Exception
112     * @access public
113     *
114     */
115    public function __construct(Net_DNS2_Packet &$packet = null)
116    {
117        if (!is_null($packet)) {
118
119            $this->set($packet);
120        } else {
121
122            $this->qname    = '';
123            $this->qtype    = 'A';
124            $this->qclass   = 'IN';
125        }
126    }
127
128    /**
129     * magic __toString() function to return the Net_DNS2_Question object as a string
130     *
131     * @return string
132     * @access public
133     *
134     */
135    public function __toString()
136    {
137        return ";;\n;; Question:\n;;\t " . $this->qname . '. ' .
138            $this->qtype . ' ' . $this->qclass . "\n";
139    }
140
141    /**
142     * builds a new Net_DNS2_Header object from a Net_DNS2_Packet object
143     *
144     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet object
145     *
146     * @return boolean
147     * @throws Net_DNS2_Exception
148     * @access public
149     *
150     */
151    public function set(Net_DNS2_Packet &$packet)
152    {
153        //
154        // expand the name
155        //
156        $this->qname = $packet->expand($packet, $packet->offset);
157        if ($packet->rdlength < ($packet->offset + 4)) {
158
159            throw new Net_DNS2_Exception(
160                'invalid question section: to small',
161                Net_DNS2_Lookups::E_QUESTION_INVALID
162            );
163        }
164
165        //
166        // unpack the type and class
167        //
168        $type   = ord($packet->rdata[$packet->offset++]) << 8 |
169            ord($packet->rdata[$packet->offset++]);
170        $class  = ord($packet->rdata[$packet->offset++]) << 8 |
171            ord($packet->rdata[$packet->offset++]);
172
173        //
174        // validate it
175        //
176        $type_name  = Net_DNS2_Lookups::$rr_types_by_id[$type];
177        $class_name = Net_DNS2_Lookups::$classes_by_id[$class];
178
179        if ( (!isset($type_name)) || (!isset($class_name)) ) {
180
181            throw new Net_DNS2_Exception(
182                'invalid question section: invalid type (' . $type .
183                ') or class (' . $class . ') specified.',
184                Net_DNS2_Lookups::E_QUESTION_INVALID
185            );
186        }
187
188        //
189        // store it
190        //
191        $this->qtype     = $type_name;
192        $this->qclass    = $class_name;
193
194        return true;
195    }
196
197    /**
198     * returns a binary packed Net_DNS2_Question object
199     *
200     * @param Net_DNS2_Packet &$packet the Net_DNS2_Packet object this question is
201     *                                 part of. This needs to be passed in so that
202     *                                 the compressed qname value can be packed in
203     *                                 with the names of the other parts of the
204     *                                 packet.
205     *
206     * @return string
207     * @throws Net_DNS2_Exception
208     * @access public
209     *
210     */
211    public function get(Net_DNS2_Packet &$packet)
212    {
213        //
214        // validate the type and class
215        //
216        $type  = Net_DNS2_Lookups::$rr_types_by_name[$this->qtype];
217        $class = Net_DNS2_Lookups::$classes_by_name[$this->qclass];
218
219        if ( (!isset($type)) || (!isset($class)) ) {
220
221            throw new Net_DNS2_Exception(
222                'invalid question section: invalid type (' . $this->qtype .
223                ') or class (' . $this->qclass . ') specified.',
224                Net_DNS2_Lookups::E_QUESTION_INVALID
225            );
226        }
227
228        $data = $packet->compress($this->qname, $packet->offset);
229
230        $data .= chr($type >> 8) . chr($type) . chr($class >> 8) . chr($class);
231        $packet->offset += 4;
232
233        return $data;
234    }
235}
236
237/*
238 * Local variables:
239 * tab-width: 4
240 * c-basic-offset: 4
241 * c-hanging-comment-ender-p: nil
242 * End:
243 */
244?>
245