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
// Copyright (C) 2015-2018 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 DUID_FACTORY_H
#define DUID_FACTORY_H

#include <dhcp/duid.h>
#include <boost/noncopyable.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <stdint.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <vector><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace isc {
namespace dhcp {

/// @brief Factory for generating DUIDs (DHCP Unique Identifiers).
///
/// DHCPv6 clients and servers are identified by DUIDs (see RFC 8415).
/// DUIDs are unique identifiers carried in the appropriate DHCP
/// options. RFC 8415 defines 4 types of DUIDs:
/// -# DUID-LLT
/// -# DUID-EN
/// -# DUID-LL
/// -# DUID-UUID
///
/// of which the DUID-LLT is recommended for all general purpose computing
/// devices. Future specifications may define new DUID types. The current
/// implementation of the class only supports DUID types defined in RFC 8415.
///
/// In most cases DUIDs can be generated automatically, i.e. no manual
/// configuration is required. For example, DUID-LLT is composed of the
/// current time and link layer address and type of one of the network
/// interfaces. Once the DUID is generated it should be stored in the persistent
/// storage and used by a server or client even when the network interface which
/// address had been used to generate the DUID is removed.
///
/// In some cases administrators may elect to use other types of DUIDs, which
/// are easier to generate (in case of lack of persistent storage or when
/// specifics of the device favors some generation methods), e.g. DUID-EN
/// doesn't rely on the link layer addresses of interfaces present in the
/// system.
///
/// In some cases administrators may want to influence the value of the
/// generated DUID. For example, DUID-EN includes enterprise identifier and
/// the administrator may want to select this identifier.
///
/// This class allows for selecting a type of DUID to be generated. It also
/// allows for setting desired values for the components of the DUIDs
/// being generated, while leaving other components unspecified. For example
/// an administrator may elect to set the enterprise id for the DUID-EN
/// and leave the variable length identifier unspecified. The variable
/// length identifier will be autogenerated.
///
/// This class is also responsible for storing the generated DUID in a
/// file. The location of this file is specified in the class constructor.
/// If this location is not specified the DUID is not stored, i.e. is
/// lost when the server or client shuts down. However, the DUID may be
/// reconstructed according to the configuration of the client or server
/// when they are back online.
class DUIDFactory : public boost::noncopyable {
public:

    /// @brief Constructor.
    ///
    /// @param storage_location Absolute path to the file where DUID is
    /// stored.
    DUIDFactory(const std::string& storage_location = "");

    /// @brief Checks if generated DUID will be stored in the file.
    ///
    /// @return true if generated DUIDs are stored in a file, false
    /// otherwise.
    bool isStored() const;

    /// @brief Generates DUID-LLT.
    ///
    /// This method generates DUID-LLT (Link Layer plus Time).
    ///
    /// @param htype Hardware type. If this is set to 0 and link layer
    /// address is empty a value from existing DUID or a default value
    /// of @c HTYPE_ETHER is used. Otherwise a link layer type of selected
    /// interface is used.
    /// @param time_in Explicit value of time for the DUID. If this is
    /// set to 0 a value from existing DUID or current time is used,
    /// otherwise a value specified is used.
    /// @param ll_identifier Data to be used as link layer address. If
    /// this is an empty vector this method will try to use link layer
    /// address from existing DUID. If there is no DUID yet, it will
    /// iterate over all active interfaces and will pick link layer
    /// address of one of them.
    ///
    /// @throw isc::Unexpected if none of the interfaces includes has a
    /// suitable link layer address.
    void createLLT(const uint16_t htype, const uint32_t time_in,
                   const std::vector<uint8_t>& ll_identifier);

    /// @brief Generates DUID-EN.
    ///
    /// This method generates DUID-EN (DUID Enterprise).
    ///
    /// @param enterprise_id Enterprise id. If this value is 0, a value
    /// from existing DUID is used or ISC's enterprise id if there is
    /// no DUID yet.
    /// @param identifier Data to be used as variable length identifier.
    /// If this is an empty vector, an identifier from existing DUID is
    /// used. If there is no DUID yet, the 6-bytes long vector with random
    /// values is generated.
    void createEN(const uint32_t enterprise_id,
                  const std::vector<uint8_t>& identifier);

    /// @brief Generates DUID-LL.
    ///
    /// This method generates DUID-LL (Link Layer).
    ///
    /// @param htype Hardware type. If this is set to 0 and link layer
    /// address is empty a value from existing DUID or a default value
    /// of @c HTYPE_ETHER is used. Otherwise a link layer type of selected
    /// interface is used.
    /// @param ll_identifier Data to be used as link layer address. If
    /// this is an empty vector this method will try to use link layer
    /// address from existing DUID. If there is no DUID yet, it will
    /// iterate over all active interfaces and will pick link layer
    /// address of one of them.
    ///
    /// @throw isc::Unexpected if none of the interfaces includes has a
    /// suitable link layer address.
    void createLL(const uint16_t htype,
                  const std::vector<uint8_t>& ll_identifier);

    /// @brief Returns current DUID.
    ///
    /// This method first checks if the DUID has been generated, i.e. as a
    /// result of calling DUIDFactory::createLLT. If the DUID hasn't been
    /// generated, this method will try to read the DUID from the persistent
    /// storage. If the DUID is found in persistent storage it is returned.
    /// Otherwise, the DUID-LLT is generated and returned. In some cases the
    /// generation of the DUID-LLT may fail, e.g. when there are no interfaces
    /// with a suitable link layer address. In this case, this method will
    /// generate DUID-EN, with the ISC enterprise id. If this fails, e.g. as a
    /// result of error while storing the generated DUID-EN, exception
    /// is thrown.
    ///
    /// @return Instance of the DUID read from file, or generated.
    DuidPtr get();

private:

    /// @brief Creates link layer identifier.
    ///
    /// This method iterates over existing network interfaces and finds the
    /// one with a suitable link layer address to generate a DUID-LLT or
    /// DUID-LL. It uses selected link layer address to generate identifier
    /// held in those DUID types.
    ///
    /// @param [out] identifier Link layer address for the DUID.
    /// @param [out] htype Link layer type to be included in the DUID.
    void createLinkLayerId(std::vector<uint8_t>& identifier,
                           uint16_t& htype) const;

    /// @brief Sets a new DUID as current.
    ///
    /// The generated DUID is stored in the file, if such file is specified.
    /// The new DUID will be returned when @c DUIDFactory::get is called.
    ///
    /// @param duid_vector New DUID represented as vector of bytes.
    void set(const std::vector<uint8_t>& duid_vector);

    /// @brief Reads DUID from file, if file exists.
    void readFromFile();

    /// @brief Location of the file holding generated DUID (if specified).
    std::string storage_location_;

    /// @brief Pointer to generated DUID.
    DuidPtr duid_;

};

}; // end of isc::dhcp namespace
}; // end of isc namespace

#endif /* DUID_FACTORY_H */