1 // Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef SHARED_NETWORKS_LIST_PARSER_H
8 #define SHARED_NETWORKS_LIST_PARSER_H
9 
10 #include <cc/data.h>
11 #include <cc/dhcp_config_error.h>
12 #include <cc/simple_parser.h>
13 #include <exceptions/exceptions.h>
14 #include <dhcpsrv/subnet.h>
15 #include <dhcpsrv/parsers/shared_network_parser.h>
16 #include <vector>
17 
18 namespace isc {
19 namespace dhcp {
20 
21 /// @brief Parser for a list of shared networks.
22 ///
23 /// This is a generic parser for a list of IPv4 or IPv6 shared networks.
24 ///
25 /// @tparam SharedNetworkParserType Type of the parser to be used for
26 /// parsing shared network, i.e. @ref SharedNetwork4Parser or
27 /// @ref SharedNetwork6Parser.
28 template<typename SharedNetworkParserType>
29 class SharedNetworksListParser : public data::SimpleParser {
30 public:
31 
32     /// @brief Constructor.
33     ///
34     /// @param check_iface Check if the specified interface exists in
35     /// the system.
36     SharedNetworksListParser(bool check_iface = true)
check_iface_(check_iface)37         : check_iface_(check_iface) {
38     }
39 
40     /// @brief Parses a list of shared networks.
41     ///
42     /// @tparam CfgSharedNetworksTypePtr Type of the configuration structure
43     /// into which the result will be stored, i.e. @ref CfgSharedNetworks4
44     /// or @ref CfgSharedNetworks6.
45     /// @param [out] cfg Shared networks configuration structure into which
46     /// the data should be parsed.
47     /// @param shared_networks_list_data List element holding a list of
48     /// shared networks.
49     ///
50     /// @throw DhcpConfigError when error has occurred, e.g. when networks
51     /// with duplicated names have been specified.
52     template<typename CfgSharedNetworksTypePtr>
parse(CfgSharedNetworksTypePtr & cfg,const data::ConstElementPtr & shared_networks_list_data)53     void parse(CfgSharedNetworksTypePtr& cfg,
54                const data::ConstElementPtr& shared_networks_list_data) {
55         try {
56             // Get the C++ vector holding networks.
57             const std::vector<data::ElementPtr>& networks_list =
58                 shared_networks_list_data->listValue();
59             // Iterate over all networks and do the parsing.
60             for (auto network_element = networks_list.cbegin();
61                  network_element != networks_list.cend(); ++network_element) {
62                 SharedNetworkParserType parser(check_iface_);
63                 auto network = parser.parse(*network_element);
64                 cfg->add(network);
65             }
66         } catch (const DhcpConfigError&) {
67             // Such exceptions are emitted by the lower level parsers and
68             // errors should already include element's positions. So, we
69             // simply rethrow.
70             throw;
71 
72         } catch (const std::exception& ex) {
73             // Other exceptions don't include positions of the elements, so
74             // we should append one.
75             isc_throw(DhcpConfigError, ex.what() << " ("
76                       << shared_networks_list_data->getPosition() << ")");
77         }
78     }
79 
80 protected:
81     /// Check if the specified interface exists in the system.
82     bool check_iface_;
83 };
84 
85 /// @brief Type of the shared networks list parser for IPv4.
86 typedef SharedNetworksListParser<SharedNetwork4Parser> SharedNetworks4ListParser;
87 
88 /// @brief Type of the shared networks list parser for IPv6.
89 typedef SharedNetworksListParser<SharedNetwork6Parser> SharedNetworks6ListParser;
90 
91 
92 } // end of namespace isc::dhcp
93 } // end of namespace isc
94 
95 #endif // SHARED_NETWORKS_LIST_PARSER_H
96