00001 /* 00002 * Copyright 2011-2012 Tanjeff-Nicolai Moos <tanjeff@cccmz.de> 00003 * 00004 * This file is part of the agentXcpp library. 00005 * 00006 * AgentXcpp is free software: you can redistribute it and/or modify 00007 * it under the terms of the AgentXcpp library license, version 1, which 00008 * consists of the GNU General Public License and some additional 00009 * permissions. 00010 * 00011 * AgentXcpp is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * See the AgentXcpp library license in the LICENSE file of this package 00017 * for more details. 00018 */ 00019 00020 #ifndef _OID_H_ 00021 #define _OID_H_ 00022 00023 #include <vector> 00024 #include <ostream> 00025 #include <string> 00026 #include "variable.hpp" 00027 #include "types.hpp" 00028 #include "exceptions.hpp" 00029 00030 namespace agentxcpp 00031 { 00032 /** 00033 * \brief Represents an SNMP object identifier (OID). 00034 * 00035 * This class represents an OID. OID's are sequences of sub-identifiers, 00036 * which are integers. 00037 * 00038 * This class provides constructors taking a string which contains an OID. 00039 * For example, this works: 00040 * 00041 * \code 00042 * oid myCompany = oid("1.3.6.1.4.1.355"); 00043 * \endcode 00044 * 00045 * Also a constructor is provided which takes an oid and a string and 00046 * concatenates them, so this works also: 00047 * 00048 * \code 00049 * oid myObject = oid(myCompany, "1.1.3.0"); 00050 * \endcode 00051 * 00052 * In addition, some common oid's are provided as constants, e.g. 00053 * 'enterprises_oid', so the following will also work (note that the second 00054 * argument is a string, not an integer!): 00055 * 00056 * \code 00057 * oid yourCompany = oid(enterprises_oid, "42"); // second param is a string! 00058 * \endcode 00059 * 00060 * The string given to the constructors must have a valid syntax. If a 00061 * malformed string is provided, inval_param is thrown and the object is 00062 * not constructed. For example, the following strings are malformed: 00063 * 00064 * \code 00065 * "1,3,6" // wrong separator (must be a period) 00066 * "1.3.6." // trailing character at the end 00067 * "1.3.6.1.4.1.123456789123" // last subid is too big (must fit in a 32 bit unsigned integer) 00068 * \endcode 00069 * 00070 * However, the following strings are accepted: 00071 * 00072 * \code 00073 * "1.3.6" 00074 * "1" // a single subid is ok 00075 * "1.3.6.1.4.1.42.1.0" // 0 as subid is ok 00076 * "" // empty string is ok 00077 * \endcode 00078 * 00079 * This class inherits from std:vector<uint32_t>, which means that an oid 00080 * object can be manipulated the same way as a std::vector<> can be 00081 * manipulated: 00082 * 00083 * \code 00084 * oid theirCompany = enterprises_oid; 00085 * theirCompany.push_back(23); // Don't use a string here! 00086 * \endcode 00087 * 00088 */ 00089 class oid: public variable, public std::vector<uint32_t> 00090 { 00091 private: 00092 00093 /** 00094 * \brief the 'include' field. 00095 */ 00096 bool include; 00097 00098 /** 00099 * \brief Parse an OID from a string and append it. 00100 * 00101 * The OID contained within the string 's' is parsed and appended 00102 * this object. The format of the string is described above 00103 * 00104 * \param s The OID to be parsed. 00105 * 00106 * \exception inval_param If the string is malformed. 00107 */ 00108 void parse_string(std::string s); 00109 00110 public: 00111 00112 /** 00113 * \brief Default Constructor 00114 * 00115 * This constructs an empty oid (the null oid). 00116 * 00117 * \internal 00118 * The 'include' field is initialized to 'false'. 00119 * \endinternal 00120 * 00121 * \exception None. 00122 */ 00123 oid() 00124 { 00125 include = false; 00126 } 00127 00128 00129 /** 00130 * \brief Initialize an oid object with an OID in string format. 00131 * 00132 * This constructor takes a string and initializes the oid object 00133 * with the OID contained within this string. The format of the 00134 * string is described above. 00135 * 00136 * \internal 00137 * The 'include' field is initialized to 'false'. 00138 * \endinternal 00139 * 00140 * \param id The initial object identifier. 00141 * 00142 * \exception inval_param If the string is malformed. 00143 */ 00144 oid(std::string id); 00145 00146 /** 00147 * \brief Initialize an oid object with another oid plus an OID in 00148 * string format. 00149 * 00150 * All subid's are copied from 'o'. Then, the OID contained within 00151 * the string 'id' is appended. The format of the string is 00152 * described in the documentation of this class. 00153 * 00154 * \internal 00155 * The 'include' field is copied from 'o'. 00156 * \endinternal 00157 * 00158 * \param o The starting OID. 00159 * 00160 * \param id The OID to append. 00161 * 00162 * \exception inval_param If the string is malformed. 00163 */ 00164 oid(const oid& o, std::string id); 00165 00166 /** 00167 * \brief Assignment operator 00168 * 00169 * Copies all data from 'o' into this OID. 00170 * 00171 * \param o The OID to copy from. 00172 * 00173 * \return A reference to this OID. 00174 */ 00175 oid& operator=(const oid& o); 00176 00177 /** 00178 * \internal 00179 * 00180 * \brief Get the current include value. 00181 * 00182 * The include value is present in the serialized form of an OID. 00183 * If an OID object is created by parsing a AgentX message, the 00184 * 'include' member is set accordingly. 00185 * 00186 * See RFC 2741, sections 5.1 and 5.2 for details. 00187 */ 00188 bool get_include() 00189 { 00190 return include; 00191 } 00192 00193 /** 00194 * \internal 00195 * 00196 * \brief set the include value 00197 * 00198 * The include value is present in the serialized form of an OID. 00199 * If an OID object is serialized, the include field is encoded 00200 * into the stream. 00201 * 00202 * See RFC 2741, sections 5.1 and 5.2 for details. 00203 */ 00204 void set_include(bool i) 00205 { 00206 include = i; 00207 } 00208 00209 /** 00210 * \internal 00211 * 00212 * \brief Encode an OID object as described in RFC 2741, 00213 * section 5.1. 00214 */ 00215 data_t serialize() const; 00216 00217 /** 00218 * \internal 00219 * 00220 * \brief Construct the object from input stream 00221 * 00222 * This constructor parses the serialized form of the object. 00223 * It takes an iterator, starts parsing at the position of the 00224 * iterator and advances the iterator to the position right behind 00225 * the object. 00226 * 00227 * The constructor expects valid data from the stream; if parsing 00228 * fails, parse_error is thrown. In this case, the iterator is left 00229 * at an undefined position. 00230 * 00231 * \param pos Iterator pointing to the current stream position. 00232 * The iterator is advanced while reading the header. 00233 * 00234 * \param end Iterator pointing one element past the end of the 00235 * current stream. This is needed to mark the end of the 00236 * buffer. 00237 * 00238 * \param big_endian Whether the input stream is in big endian 00239 * format 00240 * 00241 * \exception parse_error If parsing fails. In this case, the 00242 * iterator is left at an undefined 00243 * position. 00244 */ 00245 oid(data_t::const_iterator& pos, 00246 const data_t::const_iterator& end, 00247 bool big_endian=true); 00248 00249 /** 00250 * \brief The less-than operator 00251 * 00252 * An OID is less than another OID if either the first 00253 * not-identical part is lesser or if all parts are identical and 00254 * it has lesser parts. 00255 * 00256 * Example:\n 00257 * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n 00258 * is less than \n 00259 * 1.3.6.1.4.1.42.3<b>.4</b>.1 \n 00260 * Note the next to last number. 00261 * 00262 * Also,\n 00263 * 1.3.6.1.4.1.42.3.3.1 \n 00264 * is less than \n 00265 * 1.3.6.1.4.1.42.3.3.1<b>.1</b> \n 00266 * because it is shorter. 00267 * 00268 * However, \n 00269 * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n 00270 * is greater than \n 00271 * 1.3.6.1.4.1.42.3<b>.2</b>.1.1 \n 00272 * because the 9th number is greater (although the first OID has 00273 * less numbers than the second). 00274 * 00275 * \param o The OID tocompare to. 00276 * 00277 * \return True if the OID is less than 'o', false otherwise. 00278 */ 00279 bool operator<(const oid& o) const; 00280 00281 /** 00282 * \brief The equal-operator 00283 * 00284 * See operator<() for a more detailed description about comparing 00285 * OIDs. 00286 * 00287 * \param o The OID tocompare to. 00288 * 00289 * \return True if the OIDs are equal, false otherwise. 00290 */ 00291 bool operator==(const oid& o) const; 00292 00293 /** 00294 * \brief The not-equal-operator for oids 00295 * 00296 * See operator<() for a more detailed description about comparing 00297 * OIDs. 00298 * 00299 * \param o The OID tocompare to. 00300 * 00301 * \return False if the OIDs are equal, true otherwise. 00302 */ 00303 bool operator!=(const oid& o) const 00304 { 00305 return ! (*this == o); 00306 } 00307 00308 /** 00309 * \brief The greater-than operator 00310 * 00311 * See operator<() for a more detailed description about comparing 00312 * OIDs. 00313 * 00314 * \param o The OID tocompare to. 00315 * 00316 * \return True if the OID is greater than 'o', false otherwise. 00317 */ 00318 bool operator>(const oid& o) const 00319 { 00320 // a > b is the same as b < a :-) 00321 return o < *this; 00322 } 00323 00324 /** 00325 * \brief Checks whether the given oid is in the subtree of this 00326 * oid. 00327 * 00328 * This method checks whether the given OID is included in the 00329 * subtree which has this oid as root. 00330 * 00331 * Examples:\n 00332 * \code 00333 * oid id("1.3.6.1.4.1.42.3"); 00334 * id.contains( oid(1.3.6.1.4.1.42.3) ); // true 00335 * id.contains( oid(1.3.6.1.4.1.42) ); // false 00336 * id.contains( oid(1.3.6.1.4.1.43.3) ); // false 00337 * id.contains( oid(1.3.6.1.4.1.42.3.3.1) ); // true 00338 * \endcode 00339 * 00340 * \param id The OID to check. 00341 * 00342 * \return True if id is contained in the subtree, false 00343 * otherwise. 00344 */ 00345 bool contains(const oid& id); 00346 00347 /** 00348 * \internal 00349 * 00350 * \brief Whether it is the null Object Identifier 00351 * 00352 * According to RFC 2741, 5.1 "Object Identifier", a null object 00353 * identifier has serial representation of for 4 bytes which are 00354 * all set to 0. An OID with no subid's and the index field set to 00355 * 0 results in that representation and is thus considered to be 00356 * the null OID. 00357 * 00358 * \return True if the object is the null OID, false otherwise. 00359 */ 00360 bool is_null() const; 00361 00362 friend std::ostream& operator<<(std::ostream& out, 00363 const agentxcpp::oid& o); 00364 00365 /** 00366 * \internal 00367 * 00368 * \brief Update the internal state of the object. 00369 * 00370 * This function calls get() to obtain a new value and stores that 00371 * value within this object. 00372 * 00373 * \exception generic_error If obtaining the new value failed. 00374 */ 00375 virtual void update() 00376 { 00377 *this = this->get(); 00378 } 00379 00380 /** 00381 * \brief Obtain the current value for the object. 00382 * 00383 * This member function is derived by classes representing SNMP 00384 * variables and shall return the current value of the object. 00385 * 00386 * The default implementation throws generic_error. 00387 * 00388 * \return The current value of the object. 00389 * 00390 * \exception generic_error If obtaining the current value fails. 00391 * No other exception shall be thrown. 00392 */ 00393 virtual oid get() 00394 { 00395 throw( generic_error() ); 00396 } 00397 }; 00398 00399 /** 00400 * \brief The output operator for the oid class. 00401 * 00402 * Object identifiers (oid objects) can be output as follows: 00403 * 00404 * \code 00405 * oid led_state(enterprises_oid, "1.3.3.1"); 00406 * cout << "LED state OID: " << led_state << endl; 00407 * \endcode 00408 * 00409 * The last line will output "LED state OID: .1.3.6.1.4.1.3.3.1". 00410 * 00411 * \param out The stream to which to write the output. 00412 * 00413 * \param o The OID to output. 00414 * 00415 * \return The 'out' parameter. 00416 */ 00417 std::ostream& operator<<(std::ostream& out, const agentxcpp::oid& o); 00418 00419 00420 // TODO: Possibly these should be put into the agentxcpp::oid namespace? 00421 // The use of \memberof is not elegant. 00422 00423 /** 00424 * \memberof oid 00425 * 00426 * \brief The 'iso' OID according to RFC 1155. 00427 */ 00428 const oid iso_oid("1"); 00429 00430 /** 00431 * \memberof oid 00432 * 00433 * \brief The 'ccitt' OID according to RFC 1155. 00434 */ 00435 const oid ccitt_oid("0"); 00436 00437 /** 00438 * \memberof oid 00439 * 00440 * \brief The 'joint.iso.ccitt' OID according to RFC 1155. 00441 */ 00442 const oid joint_iso_ccitt_oid("2"); 00443 00444 /** 00445 * \memberof oid 00446 * 00447 * \brief The 'iso.org' OID according to RFC 1155. 00448 */ 00449 const oid org_oid(iso_oid,"3"); 00450 00451 /** 00452 * \memberof oid 00453 * 00454 * \brief The 'iso.org.dod' OID according to RFC 1155. 00455 */ 00456 const oid dod_oid(org_oid,"6"); 00457 00458 /** 00459 * \memberof oid 00460 * 00461 * \brief The 'iso.org.dod.internet' OID according to RFC 1155. 00462 */ 00463 const oid internet_oid(dod_oid,"1"); 00464 00465 /** 00466 * \memberof oid 00467 * 00468 * \brief The 'iso.org.dod.internet.directory' OID according to RFC 1155. 00469 */ 00470 const oid directory_oid(internet_oid,"1"); 00471 00472 /** 00473 * \memberof oid 00474 * 00475 * \brief The 'iso.org.dod.internet.mgmt' OID according to RFC 1155. 00476 */ 00477 const oid mgmt_oid(internet_oid,"2"); 00478 00479 /** 00480 * \memberof oid 00481 * 00482 * \brief The 'iso.org.dod.internet.experimental' OID according to 00483 * RFC 1155. 00484 */ 00485 const oid experimental_oid(internet_oid,"3"); 00486 00487 /** 00488 * \memberof oid 00489 * 00490 * \brief The 'iso.org.dod.internet.private' OID according to RFC 1155. 00491 */ 00492 const oid private_oid(internet_oid,"4"); 00493 00494 /** 00495 * \memberof oid 00496 * 00497 * \brief The 'iso.org.dod.internet.private.enterprises' OID according to 00498 * RFC 1155. 00499 */ 00500 const oid enterprises_oid(private_oid, "1"); 00501 } 00502 00503 00504 #endif