AgentXcpp  Revision:0.1.1
Internals Documentation
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Pages
oid.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2012 Tanjeff-Nicolai Moos <tanjeff@cccmz.de>
3  *
4  * This file is part of the agentXcpp library.
5  *
6  * AgentXcpp is free software: you can redistribute it and/or modify
7  * it under the terms of the AgentXcpp library license, version 1, which
8  * consists of the GNU General Public License and some additional
9  * permissions.
10  *
11  * AgentXcpp is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * See the AgentXcpp library license in the LICENSE file of this package
17  * for more details.
18  */
19 
20 #ifndef _OID_H_
21 #define _OID_H_
22 
23 #include <vector>
24 #include <ostream>
25 #include <string>
26 
27 #include <boost/cstdint.hpp>
28 
29 #include "variable.hpp"
30 #include "exceptions.hpp"
31 
32 using boost::uint32_t;
33 
34 namespace agentxcpp
35 {
36  /**
37  * \brief Represents an SNMP object identifier (OID).
38  *
39  * This class represents an OID. OID's are sequences of sub-identifiers,
40  * which are integers.
41  *
42  * This class provides constructors taking a string which contains an OID.
43  * For example, this works:
44  *
45  * \code
46  * oid myCompany = oid("1.3.6.1.4.1.355");
47  * \endcode
48  *
49  * Also a constructor is provided which takes an oid and a string and
50  * concatenates them, so this works also:
51  *
52  * \code
53  * oid myObject = oid(myCompany, "1.1.3.0");
54  * \endcode
55  *
56  * In addition, some common oid's are provided as constants, e.g.
57  * 'enterprises_oid', so the following will also work (note that the second
58  * argument is a string, not an integer!):
59  *
60  * \code
61  * oid yourCompany = oid(enterprises_oid, "42"); // second param is a string!
62  * \endcode
63  *
64  * The string given to the constructors must have a valid syntax. If a
65  * malformed string is provided, inval_param is thrown and the object is
66  * not constructed. For example, the following strings are malformed:
67  *
68  * \code
69  * "1,3,6" // wrong separator (must be a period)
70  * "1.3.6." // trailing character at the end
71  * "1.3.6.1.4.1.123456789123" // last subid is too big (must fit in a 32 bit unsigned integer)
72  * \endcode
73  *
74  * However, the following strings are accepted:
75  *
76  * \code
77  * "1.3.6"
78  * "1" // a single subid is ok
79  * "1.3.6.1.4.1.42.1.0" // 0 as subid is ok
80  * "" // empty string is ok
81  * \endcode
82  *
83  * This class inherits from std:vector<uint32_t>, which means that an oid
84  * object can be manipulated the same way as a std::vector<> can be
85  * manipulated:
86  *
87  * \code
88  * oid theirCompany = enterprises_oid;
89  * theirCompany.push_back(23); // Don't use a string here!
90  * \endcode
91  *
92  */
93  class oid: public variable, public std::vector<uint32_t>
94  {
95  private:
96 
97  /**
98  * \brief the 'include' field.
99  */
100  bool include;
101 
102  /**
103  * \brief Parse an OID from a string and append it.
104  *
105  * The OID contained within the string 's' is parsed and appended
106  * this object. The format of the string is described above
107  *
108  * \param s The OID to be parsed.
109  *
110  * \exception inval_param If the string is malformed.
111  */
112  void parse_string(std::string s);
113 
114  public:
115 
116  /**
117  * \brief Default Constructor
118  *
119  * This constructs an empty oid (the null oid).
120  *
121  * \internal
122  * The 'include' field is initialized to 'false'.
123  * \endinternal
124  *
125  * \exception None.
126  */
127  oid()
128  {
129  include = false;
130  }
131 
132 
133  /**
134  * \brief Initialize an oid object with an OID in string format.
135  *
136  * This constructor takes a string and initializes the oid object
137  * with the OID contained within this string. The format of the
138  * string is described above.
139  *
140  * \internal
141  * The 'include' field is initialized to 'false'.
142  * \endinternal
143  *
144  * \param id The initial object identifier.
145  *
146  * \exception inval_param If the string is malformed.
147  */
148  oid(std::string id);
149 
150  /**
151  * \brief Initialize an oid object with another oid plus an OID in
152  * string format.
153  *
154  * All subid's are copied from 'o'. Then, the OID contained within
155  * the string 'id' is appended. The format of the string is
156  * described in the documentation of this class.
157  *
158  * \internal
159  * The 'include' field is copied from 'o'.
160  * \endinternal
161  *
162  * \param o The starting OID.
163  *
164  * \param id The OID to append.
165  *
166  * \exception inval_param If the string is malformed.
167  */
168  oid(const oid& o, std::string id);
169 
170  /**
171  * \brief Assignment operator
172  *
173  * Copies all data from 'o' into this OID.
174  *
175  * \param o The OID to copy from.
176  *
177  * \return A reference to this OID.
178  */
179  oid& operator=(const oid& o);
180 
181  /**
182  * \internal
183  *
184  * \brief Get the current include value.
185  *
186  * The include value is present in the serialized form of an OID.
187  * If an OID object is created by parsing a AgentX message, the
188  * 'include' member is set accordingly.
189  *
190  * See RFC 2741, sections 5.1 and 5.2 for details.
191  */
192  bool get_include()
193  {
194  return include;
195  }
196 
197  /**
198  * \internal
199  *
200  * \brief set the include value
201  *
202  * The include value is present in the serialized form of an OID.
203  * If an OID object is serialized, the include field is encoded
204  * into the stream.
205  *
206  * See RFC 2741, sections 5.1 and 5.2 for details.
207  */
208  void set_include(bool i)
209  {
210  include = i;
211  }
212 
213  /**
214  * \internal
215  *
216  * \brief Encode an OID object as described in RFC 2741,
217  * section 5.1.
218  */
219  binary serialize() const;
220 
221  /**
222  * \internal
223  *
224  * \brief Construct the object from input stream
225  *
226  * This constructor parses the serialized form of the object.
227  * It takes an iterator, starts parsing at the position of the
228  * iterator and advances the iterator to the position right behind
229  * the object.
230  *
231  * The constructor expects valid data from the stream; if parsing
232  * fails, parse_error is thrown. In this case, the iterator is left
233  * at an undefined position.
234  *
235  * \param pos Iterator pointing to the current stream position.
236  * The iterator is advanced while reading the header.
237  *
238  * \param end Iterator pointing one element past the end of the
239  * current stream. This is needed to mark the end of the
240  * buffer.
241  *
242  * \param big_endian Whether the input stream is in big endian
243  * format
244  *
245  * \exception parse_error If parsing fails. In this case, the
246  * iterator is left at an undefined
247  * position.
248  */
249  oid(binary::const_iterator& pos,
250  const binary::const_iterator& end,
251  bool big_endian=true);
252 
253  /**
254  * \brief The less-than operator
255  *
256  * An OID is less than another OID if either the first
257  * not-identical part is lesser or if all parts are identical and
258  * it has lesser parts.
259  *
260  * Example:\n
261  * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n
262  * is less than \n
263  * 1.3.6.1.4.1.42.3<b>.4</b>.1 \n
264  * Note the next to last number.
265  *
266  * Also,\n
267  * 1.3.6.1.4.1.42.3.3.1 \n
268  * is less than \n
269  * 1.3.6.1.4.1.42.3.3.1<b>.1</b> \n
270  * because it is shorter.
271  *
272  * However, \n
273  * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n
274  * is greater than \n
275  * 1.3.6.1.4.1.42.3<b>.2</b>.1.1 \n
276  * because the 9th number is greater (although the first OID has
277  * less numbers than the second).
278  *
279  * \param o The OID tocompare to.
280  *
281  * \return True if the OID is less than 'o', false otherwise.
282  */
283  bool operator<(const oid& o) const;
284 
285  /**
286  * \brief The equal-operator
287  *
288  * See operator<() for a more detailed description about comparing
289  * OIDs.
290  *
291  * \param o The OID tocompare to.
292  *
293  * \return True if the OIDs are equal, false otherwise.
294  */
295  bool operator==(const oid& o) const;
296 
297  /**
298  * \brief The not-equal-operator for oids
299  *
300  * See operator<() for a more detailed description about comparing
301  * OIDs.
302  *
303  * \param o The OID tocompare to.
304  *
305  * \return False if the OIDs are equal, true otherwise.
306  */
307  bool operator!=(const oid& o) const
308  {
309  return ! (*this == o);
310  }
311 
312  /**
313  * \brief The greater-than operator
314  *
315  * See operator<() for a more detailed description about comparing
316  * OIDs.
317  *
318  * \param o The OID tocompare to.
319  *
320  * \return True if the OID is greater than 'o', false otherwise.
321  */
322  bool operator>(const oid& o) const
323  {
324  // a > b is the same as b < a :-)
325  return o < *this;
326  }
327 
328  /**
329  * \brief Checks whether the given oid is in the subtree of this
330  * oid.
331  *
332  * This method checks whether the given OID is included in the
333  * subtree which has this oid as root.
334  *
335  * Examples:\n
336  * \code
337  * oid id("1.3.6.1.4.1.42.3");
338  * id.contains( oid(1.3.6.1.4.1.42.3) ); // true
339  * id.contains( oid(1.3.6.1.4.1.42) ); // false
340  * id.contains( oid(1.3.6.1.4.1.43.3) ); // false
341  * id.contains( oid(1.3.6.1.4.1.42.3.3.1) ); // true
342  * \endcode
343  *
344  * \param id The OID to check.
345  *
346  * \return True if id is contained in the subtree, false
347  * otherwise.
348  */
349  bool contains(const oid& id);
350 
351  /**
352  * \internal
353  *
354  * \brief Whether it is the null Object Identifier
355  *
356  * According to RFC 2741, 5.1 "Object Identifier", a null object
357  * identifier has serial representation of for 4 bytes which are
358  * all set to 0. An OID with no subid's and the index field set to
359  * 0 results in that representation and is thus considered to be
360  * the null OID.
361  *
362  * \return True if the object is the null OID, false otherwise.
363  */
364  bool is_null() const;
365 
366  friend std::ostream& operator<<(std::ostream& out,
367  const agentxcpp::oid& o);
368 
369  /**
370  * \internal
371  *
372  * \brief Update the internal state of the object.
373  *
374  * This function calls get() to obtain a new value and stores that
375  * value within this object.
376  *
377  * \exception generic_error If obtaining the new value failed.
378  */
379  virtual void update()
380  {
381  *this = this->get();
382  }
383 
384  /**
385  * \brief Obtain the current value for the object.
386  *
387  * This member function is derived by classes representing SNMP
388  * variables and shall return the current value of the object.
389  *
390  * The default implementation throws generic_error.
391  *
392  * \return The current value of the object.
393  *
394  * \exception generic_error If obtaining the current value fails.
395  * No other exception shall be thrown.
396  */
397  virtual oid get()
398  {
399  throw( generic_error() );
400  }
401  };
402 
403  /**
404  * \brief The output operator for the oid class.
405  *
406  * Object identifiers (oid objects) can be output as follows:
407  *
408  * \code
409  * oid led_state(enterprises_oid, "1.3.3.1");
410  * cout << "LED state OID: " << led_state << endl;
411  * \endcode
412  *
413  * The last line will output "LED state OID: .1.3.6.1.4.1.3.3.1".
414  *
415  * \param out The stream to which to write the output.
416  *
417  * \param o The OID to output.
418  *
419  * \return The 'out' parameter.
420  */
421  std::ostream& operator<<(std::ostream& out, const agentxcpp::oid& o);
422 
423 
424  // TODO: Possibly these should be put into the agentxcpp::oid namespace?
425  // The use of \memberof is not elegant.
426 
427  /**
428  * \memberof oid
429  *
430  * \brief The 'iso' OID according to RFC 1155.
431  */
432  const oid iso_oid("1");
433 
434  /**
435  * \memberof oid
436  *
437  * \brief The 'ccitt' OID according to RFC 1155.
438  */
439  const oid ccitt_oid("0");
440 
441  /**
442  * \memberof oid
443  *
444  * \brief The 'joint.iso.ccitt' OID according to RFC 1155.
445  */
446  const oid joint_iso_ccitt_oid("2");
447 
448  /**
449  * \memberof oid
450  *
451  * \brief The 'iso.org' OID according to RFC 1155.
452  */
453  const oid org_oid(iso_oid,"3");
454 
455  /**
456  * \memberof oid
457  *
458  * \brief The 'iso.org.dod' OID according to RFC 1155.
459  */
460  const oid dod_oid(org_oid,"6");
461 
462  /**
463  * \memberof oid
464  *
465  * \brief The 'iso.org.dod.internet' OID according to RFC 1155.
466  */
467  const oid internet_oid(dod_oid,"1");
468 
469  /**
470  * \memberof oid
471  *
472  * \brief The 'iso.org.dod.internet.directory' OID according to RFC 1155.
473  */
474  const oid directory_oid(internet_oid,"1");
475 
476  /**
477  * \memberof oid
478  *
479  * \brief The 'iso.org.dod.internet.mgmt' OID according to RFC 1155.
480  */
481  const oid mgmt_oid(internet_oid,"2");
482 
483  /**
484  * \memberof oid
485  *
486  * \brief The 'iso.org.dod.internet.experimental' OID according to
487  * RFC 1155.
488  */
489  const oid experimental_oid(internet_oid,"3");
490 
491  /**
492  * \memberof oid
493  *
494  * \brief The 'iso.org.dod.internet.private' OID according to RFC 1155.
495  */
496  const oid private_oid(internet_oid,"4");
497 
498  /**
499  * \memberof oid
500  *
501  * \brief The 'iso.org.dod.internet.private.enterprises' OID according to
502  * RFC 1155.
503  */
504  const oid enterprises_oid(private_oid, "1");
505 }
506 
507 
508 #endif