option_vendor_class.h 7.15 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef OPTION_VENDOR_CLASS_H
#define OPTION_VENDOR_CLASS_H

#include <dhcp/dhcp4.h>
#include <dhcp/dhcp6.h>
#include <dhcp/opaque_data_tuple.h>
#include <dhcp/option.h>
#include <util/buffer.h>
#include <boost/shared_ptr.hpp>
#include <stdint.h>

namespace isc {
namespace dhcp {

/// @brief This class encapsulates DHCPv6 Vendor Class and DHCPv4 V-I Vendor
/// Class options.
///
/// The format of DHCPv6 Vendor Class option is described in section 22.16 of
/// RFC3315 and the format of the DHCPv4 V-I Vendor Class option is described
/// in section 3 of RFC3925. Each of these options carries enterprise id
/// followed by the collection of tuples carring opaque data. A single tuple
/// consists of the field holding opaque data length and the actual data.
/// In case of the DHCPv4 V-I Vendor Class each tuple is preceded by the
/// 4-byte long enterprise id. Also, the field which carries the length of
/// the tuple is 1-byte long for DHCPv4 V-I Vendor Class and 2-bytes long
/// for the DHCPv6 Vendor Class option.
///
/// Whether the encapsulated format is DHCPv4 V-I Vendor Class or DHCPv6
/// Vendor Class option is controlled by the @c u (universe) parameter passed
/// to the constructor.
///
/// @todo Currently, the enterprise id field is set to a value of the first
/// enterprise id occurrence in the parsed option. At some point we should
/// be able to differentiate between enterprise ids.
class OptionVendorClass : public Option {
public:

    /// @brief Collection of opaque data tuples carried by the option.
    typedef std::vector<OpaqueDataTuple> TuplesCollection;

    /// @brief Constructor.
    ///
    /// @param u universe (v4 or v6).
    /// @param vendor_id vendor enterprise id (unique 32-bit integer).
    OptionVendorClass(Option::Universe u, const uint32_t vendor_id);

    /// @brief Constructor.
    ///
    /// This constructor creates an instance of the option using a buffer with
    /// on-wire data. It may throw an exception if the @c unpack method throws.
    ///
    /// @param u universe (v4 or v6)
    /// @param begin Iterator pointing to the beginning of the buffer holding an
    /// option.
    /// @param end Iterator pointing to the end of the buffer holding an option.
    OptionVendorClass(Option::Universe u, OptionBufferConstIter begin,
                      OptionBufferConstIter end);

    /// @brief Renders option into the buffer in the wire format.
    ///
    /// @param [out] buf Buffer to which the option is rendered.
    virtual void pack(isc::util::OutputBuffer& buf);

    /// @brief Parses buffer holding an option.
    ///
    /// This function parses the buffer holding an option and initializes option
    /// properties: enterprise ids and the collection of tuples.
    ///
    /// @param begin Iterator pointing to the beginning of the buffer holding an
    /// option.
    /// @param end Iterator pointing to the end of the buffer holding an option.
    virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end);

    /// @brief Returns enterprise id.
    uint32_t getVendorId() const {
        return (vendor_id_);
    }

    /// @brief Adds a new opaque data tuple to the option.
    ///
    /// @param tuple Tuple to be added.
    /// @throw isc::BadValue if the type of the tuple doesn't match the
    /// universe this option belongs to.
    void addTuple(const OpaqueDataTuple& tuple);

    /// @brief Replaces tuple at the specified index with a new tuple.
    ///
    /// This function replaces an opaque data tuple at the specified position
    /// with the new tuple. If the specified index is out of range an exception
    /// is thrown.
    ///
    /// @param at Index at which the tuple should be replaced.
    /// @param tuple Tuple to be set.
    /// @throw isc::OutOfRange if the tuple position is out of range.
    /// @throw isc::BadValue if the type of the tuple doesn't match the
    /// universe this option belongs to.
    void setTuple(const size_t at, const OpaqueDataTuple& tuple);

    /// @brief Returns opaque data tuple at the specified position.
    ///
    ///  If the specified position is out of range an exception is thrown.
    ///
    /// @param at Index at which the tuple should be replaced.
    /// @throw isc::OutOfRange if the tuple position is out of range.
    OpaqueDataTuple getTuple(const size_t at) const;

    /// @brief Returns the number of opaque data tuples added to the option.
    size_t getTuplesNum() const {
        return (tuples_.size());
    }

    /// @brief Returns collection of opaque data tuples carried in the option.
    const TuplesCollection& getTuples() const {
        return (tuples_);
    }

131
132
133
134
135
136
137
    /// @brief Checks if the Vendor Class holds the opaque data tuple with the
    /// specified string.
    ///
    /// @param tuple_str String representation of the tuple being searched.
    /// @return true if the specified tuple exists for this option.
    bool hasTuple(const std::string& tuple_str) const;

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    /// @brief Returns the full length of the option, including option header.
    virtual uint16_t len();

private:

    /// @brief Returns option code appropriate for the specified universe.
    ///
    /// This function is called by the constructor to map the specified
    /// universe to the option code.
    ///
    /// @param u universe (V4 or V6).
    /// @return DHCPv4 V-I Vendor Class or DHCPv6 Vendor Class option code.
    static uint16_t getOptionCode(Option::Universe u) {
        return (u == V4 ? DHO_VIVCO_SUBOPTIONS : D6O_VENDOR_CLASS);
    }

    /// @brief Returns the tuple length field type for the given universe.
    ///
    /// This function returns the length field type which should be used
    /// for the opaque data tuples being added to this option.
    ///
    /// @return Tuple length field type for the universe this option belongs to.
    OpaqueDataTuple::LengthFieldType getLengthFieldType() const {
        return (getUniverse() == V4 ? OpaqueDataTuple::LENGTH_1_BYTE :
                OpaqueDataTuple::LENGTH_2_BYTES);
    }

    /// @brief Returns minimal length of the option for the given universe.
    uint16_t getMinimalLength() const {
        return (getUniverse() == Option::V4 ? 7 : 6);
    }

    /// @brief Enterprise ID.
    uint32_t vendor_id_;

    /// @brief Collection of opaque data tuples carried by the option.
    TuplesCollection tuples_;

};

/// @brief Defines a pointer to the @c OptionVendorClass.
typedef boost::shared_ptr<OptionVendorClass> OptionVendorClassPtr;

}
}

#endif // OPTION_VENDOR_CLASS_H