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
131
132
133
134
135
136
137
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Copyright (C) 2014-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#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 file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dhcp/option_data_types.h>
#include <stdint.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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 (16) is described in section 21.16
/// of RFC 8415 and the format of the DHCPv4 V-I Vendor Class option (124) is
/// described in section 3 of RFC3925. Each of these options carries enterprise
/// id followed by the collection of tuples carrying 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.
///
/// Currently, the enterprise id field is set to a value of the first
/// enterprise id occurrence in the parsed option. This assumes that
/// all tuples in the same option are for the same vendor.
class OptionVendorClass : public Option {
public:

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

    /// @brief Constructor.
    ///
    /// This constructor instance of the DHCPv4 V-I Vendor Class option (124)
    /// or DHCPv6 Vendor Class option (16), depending on universe specified.
    /// If the universe is v4, the constructor adds one empty tuple to the
    /// option, as per RFC3925, section 3. the complete option must hold at
    /// least one data-len field for opaque data. If the specified universe
    /// is v6, the constructor adds no tuples.
    ///
    /// @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 Copies this option and returns a pointer to the copy.
    OptionPtr clone() const;<--- Derived function 'OptionVendorClass::clone'

    /// @brief Renders option into the buffer in the wire format.
    ///
    /// @param [out] buf Buffer to which the option is rendered.
    /// @param check if set to false, allows options larger than 255 for v4
    virtual void pack(isc::util::OutputBuffer& buf, bool check = true) const;<--- Function in derived class

    /// @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);<--- unpack is a virtual function

    /// @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 for which tuple to get.
    /// @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_);
    }

    /// @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;

    /// @brief Returns the full length of the option, including option header.
    virtual uint16_t len() const;<--- Function in derived class

    /// @brief Returns text representation of the option.
    ///
    /// @param indent Number of space characters before text.
    /// @return Text representation of the option.
    virtual std::string toText(int indent = 0) const;<--- Function in derived class

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) {
        if (u == V4) {
            return (DHO_VIVCO_SUBOPTIONS);
        } else {
            return (D6O_VENDOR_CLASS);
        }
    }

    /// @brief Returns minimal length of the option for the given universe.
    ///
    /// For DHCPv6, The Vendor Class option mandates a 2-byte
    /// OPTION_VENDOR_CLASS followed by a 2-byte option-len with a 4-byte
    /// enterprise-number.  While section 21.16 of RFC 8415 specifies that the
    /// information contained within the data area can contain one or more
    /// opaque fields, the inclusion of the vendor-class-data is not mandatory
    /// and therefore not factored into the overall possible minimum length.
    ///
    /// For DHCPv4, The V-I Vendor Class option mandates a 1-byte option-code
    /// followed by a 1-byte option-len with a 4-byte enterprise-number.
    /// While section 3 of RFC3925 specifies that the information contained
    /// within the per-vendor data area can contain one or more opaque fields,
    /// the inclusion of the vendor-class-data is not mandatory and therefore
    /// not factored into the overall possible minimum length.
    uint16_t getMinimalLength() const {
        return (getUniverse() == Option::V4 ? 6 : 8);
    }

    /// @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